我有一个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;继承的所有内容?
答案 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)
);
}
}