简体   繁体   English

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

[英]StructureMap: Wiring (generic) implementations to an implementation of another type

If I have an interface: 如果我有一个界面:

public interface IRepository<T>

And an abstract class: 还有一个抽象类:

public abstract class LinqToSqlRepository<T, TContext> : IRepository<T>
        where T : class
        where TContext : DataContext

And a whole bunch of implementations of IRepository / LinqToSqlRepository (eg AccountRepository, ContactRepository, etc.), what's the best way to to use StructureMap (2.5.3) to generically wire them all up? 以及IRepository / LinqToSqlRepository的一整套实现(例如AccountRepository,ContactRepository等),使用StructureMap(2.5.3)通常将它们全部连接起来的最佳方法是什么?

eg, I want this code to pass: 例如,我希望此代码通过:

[Test]    
public void ShouldWireUpAccountRepositories
{
  var accountRepo = ObjectFactory.GetInstance<IRepository<Account>>();
  Assert.IsInstanceOf<AccountRepository>(accountRepo);
}

Without explicitly writing this: 无需明确编写:

ObjectFactory.Configure(x => x.ForRequestedType<IRepository<Account>>()
    .TheDefaultIsConcreteType<AccountRepository>());

In the past, we've always created a specific interface on each repository that inherited from the generic one, and used the default scanner to automatically wire all of those instances, but I'd like to be able to ask specifically for an IRepository<Account> without cluttering up the project with additional interfaces / configurations. 过去,我们总是在每个从通用类继承的存储库上创建一个特定的接口,并使用默认的扫描程序自动关联所有这些实例,但是我希望能够专门询问IRepository<Account>而不会因其他界面/配置而使项目混乱不堪。

StructureMap's scanning feature can handle that: StructureMap的扫描功能可以处理以下问题:

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

Using Fasterflect you could write the following code: 使用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 ) );
}

Note that the above is written from memory and has not been compiler verified. 请注意,以上内容是从内存写入的,尚未经过编译器验证。 You'll need the source version of Fasterflect to make it compile. 您需要Fasterflect的源代码版本才能进行编译。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM