StructureMap: подключение (универсальная) реализация к реализации другого типа - PullRequest
0 голосов
/ 14 мая 2010

Если у меня есть интерфейс:

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 ]

2 голосов
/ 15 мая 2010

Функция сканирования StructureMap может справиться с этим:

ObjectFactory.Initialize(x => {
  x.Scan(y =>
  {
      y.TheCallingAssembly();
      y.ConnectImplementationsToTypesClosing(typeof(IRepository<>));
    });
});
1 голос
/ 14 мая 2010

Используя 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, чтобы он компилировался.

...