[英]StructureMap: Wiring (generic) implementations to an implementation of another type
如果我有一个界面:
public interface IRepository<T>
还有一个抽象类:
public abstract class LinqToSqlRepository<T, TContext> : IRepository<T>
where T : class
where TContext : DataContext
以及IRepository / LinqToSqlRepository的一整套实现(例如AccountRepository,ContactRepository等),使用StructureMap(2.5.3)通常将它们全部连接起来的最佳方法是什么?
例如,我希望此代码通过:
[Test]
public void ShouldWireUpAccountRepositories
{
var accountRepo = ObjectFactory.GetInstance<IRepository<Account>>();
Assert.IsInstanceOf<AccountRepository>(accountRepo);
}
无需明确编写:
ObjectFactory.Configure(x => x.ForRequestedType<IRepository<Account>>()
.TheDefaultIsConcreteType<AccountRepository>());
过去,我们总是在每个从通用类继承的存储库上创建一个特定的接口,并使用默认的扫描程序自动关联所有这些实例,但是我希望能够专门询问IRepository<Account>
而不会因其他界面/配置而使项目混乱不堪。
StructureMap的扫描功能可以处理以下问题:
ObjectFactory.Initialize(x => {
x.Scan(y =>
{
y.TheCallingAssembly();
y.ConnectImplementationsToTypesClosing(typeof(IRepository<>));
});
});
使用Fasterflect,您可以编写以下代码:
// get the assembly containing the repos
var assembly = Assembly.GetExecutingAssembly();
// get all repository types (classes whose name end with "Repository")
var types = assembly.Types( Flags.PartialNameMatch, "Repository" ).Where( t => t.IsClass );
// configure StructureMap for the found repos
foreach( Type repoType in types )
{
Type entityType = assembly.Type( repoType.Name.Replace( "Repository", "" );
// define the generic interface-based type to associate with the concrete repo type
Type genericRepoType = typeof(IRepository).MakeGenericType( entityType );
ObjectFactory.Configure( x => x.For( RequestedType( genericRepoType ) ).Use( repoType ) );
}
请注意,以上内容是从内存写入的,尚未经过编译器验证。 您需要Fasterflect的源代码版本才能进行编译。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.