StructureMap自动注册后代类

时间:2009-08-31 06:05:44

标签: structuremap

我有一个Repository< T>的基类。在一个特定的项目中,我有几个这个基类的实现。例如

PersonRepository : Repository<T>
EmployerRepository : Repository<T>

现在,我在StructureMap ServiceRegistry类中注册了每个存储库。像这样:

ForRequestedType<Repository<Person>>()
  .TheDefaultIsConcreteType<PersonRepository>();
ForRequestedType<Repository<Employer>>()
  .TheDefaultIsConcreteType<EmployerRepository>();

这很糟糕,因为每次添加存储库时,我都要记得注册它。这是又一步。

有没有办法可以搜索PersonRepository所在的项目/程序集,并注册从Repository&lt; T&gt;继承的所有内容?

1 个答案:

答案 0 :(得分:3)

编辑:我刚刚从project's CI server下载了最新版本的StructureMap。 您现在需要的是,我们不需要使用自定义约定:

public class RepositoryRegistry : Registry
{
    public RepositoryRegistry()
    {
        Scan(assemblyScanner =>
             {
                 assemblyScanner.AssemblyContainingType<PersonRepository>();
                 assemblyScanner.AddAllTypesOf(typeof (IRepository<>));
                 assemblyScanner.ConnectImplementationsToTypesClosing(typeof(IRepository<>));
             });
    }
}

这是我最初的解决方案:

这是一个很好的起点,但可能需要改进:

public class RepositoryRegistry : Registry
{
    public RepositoryRegistry()
    {
        Scan(assemblyScanner =>
             {
                 assemblyScanner.AssemblyContainingType<PersonRepository>();
                 assemblyScanner.AddAllTypesOf(typeof (IRepository<>));
                 assemblyScanner.With<RepositoryConvention>();
             });
    }
}

public class RepositoryConvention : ITypeScanner
{
    public void Process(Type type, PluginGraph graph)
    {
        var selectedInterface =
            (from @interface in type.GetInterfaces()
            where @interface.IsGenericType &&
                  @interface.GetGenericTypeDefinition()
                      .IsAssignableFrom(typeof (IRepository<>))
            select @interface).SingleOrDefault();

        if(selectedInterface != null)
            graph.Configure(registry =>
                 registry.ForRequestedType(selectedInterface)
                    .TheDefaultIsConcreteType(type)
             );
    }
}