StructureMap автоматически регистрирует классы-потомки - PullRequest
2 голосов
/ 31 августа 2009

У меня есть базовый класс репозитория . В конкретном проекте у меня есть несколько реализаций этого базового класса. например

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

Сейчас я регистрирую каждое из этих хранилищ в классе StructureMap ServiceRegistry. как это:

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

Это отстой, потому что каждый раз, когда я добавляю репозиторий, я должен помнить, чтобы зарегистрировать его. Это еще один шаг.

Есть ли способ найти проект / сборку, где расположен PersonRepository, и зарегистрировать все, что унаследовано от репозитория ?

1 Ответ

3 голосов
/ 03 сентября 2009

РЕДАКТИРОВАТЬ : Я только что загрузил новейшую сборку StructureMap с сервера CI проекта . То, что вам нужно, теперь включено, и нет необходимости использовать пользовательское соглашение:

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)
             );
    }
}
...