这与我的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问题在这里不兼容。