StructureMap:连接(通用)实现到另一种类型的实现

时间:2010-05-14 16:22:50

标签: c# .net structuremap

如果我有一个界面:

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>没有使用其他接口/配置混乱项目。

2 个答案:

答案 0 :(得分:2)

StructureMap的扫描功能可以处理:

ObjectFactory.Initialize(x => {
  x.Scan(y =>
  {
      y.TheCallingAssembly();
      y.ConnectImplementationsToTypesClosing(typeof(IRepository<>));
    });
});

答案 1 :(得分:1)

使用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的源版本才能进行编译。