基于具体类型在StructureMap中注册泛型类型

时间:2014-06-24 12:42:21

标签: c# generics inversion-of-control ninject structuremap

这与我的question about Unity非常相似,只是它适用于StructureMap。

我正在尝试模拟我可以在Ninject中配置的行为,而只是使用Unity。

我正在尝试使用Cached Repository Pattern,给定以下类和接口:

public interface IRepository<T>
{
    T Get();
}

public class SqlRepository<T> : IRepository<T>
    where T : new()
{
    public T Get()
    {
        Console.WriteLine("Getting object of type '{0}'!", typeof(T).Name);
        return new T();
    }
}

public class CachedRepository<T> : IRepository<T>
    where T : class
{
    private readonly IRepository<T> repository;

    public CachedRepository(IRepository<T> repository)
    {
        this.repository = repository;
    }

    private T cachedObject;
    public T Get()
    {
        if (cachedObject == null)
        {
            cachedObject = repository.Get();
        }
        else
        {
            Console.WriteLine("Using cached repository to fetch '{0}'!", typeof(T).Name);
        }
        return cachedObject;
    }
}

基本上,只要我的应用程序使用IRepository<T>,就应该获得CachedRepository<T>的实例。但是在CachedRepository<T>内部,它应该获取SqlRepository<T>的实际SQL存储库。在Ninject中,我使用以下方法完成了这项工作:

ninjectModule.Bind(typeof(IRepository<>)).To(tyepof(SqlRepository<>)).WhenInjectedExactlyInto(tyepof(CachedRepository<>));
ninjectModule.Bind(typeof(IRepository<>)).To(tyepof(CachedRepository<>));

在StructureMap中,我使用以下内容完成了对非通用存储库的绑定:

x.For<IWidgetRepository>().Use<CachedWidgetRepository>().Ctor<IWidgetRepository>().Is<SqlWidgetRepository>();

不幸的是,Ctor方法没有带有通用的重载。

...Ctor(typeof(IRepository<>))... // Does not exist!
...Ctor<IRepository<>>()... // Compiler error!

可以手动注册每个可能的实例:

x.For<IRepository<Widget>>().Use<CachedRepository<Widget>>().Ctor<IRepository<Widget>>().Is<SqlRepository<Widget>>();

但这显然不太理想。

编辑:我找到了StackOverflow question,但答案显得过时了:StructureMap不再有TypeInterceptor类来继承,而是公开IInterceptor接口,所以已接受的答案,StackOverflow问题在这里不兼容。

0 个答案:

没有答案