Контейнер IoC, который может регистрировать все (не универсально) автоматически без конфигурации (сборка в сборку) - PullRequest
2 голосов
/ 18 декабря 2010

Идея в том, что у меня есть проект Core с большим количеством интерфейсов, а также проект Data and Service с реализациями (все 1-к-1), например:

Core { IFooRepo, IBarRepo, IFooService, IBarService}
Data {FooRepo: IFooRepo, BarRepo : IBarRepo}
Service {FooService : IFooService, BarService : IBarService}

, поэтому я хотел бы что-то вроде

register(Core, Data);
register(Core, Service);

Есть много контейнеров IoC, и я не знаю, какой из них может это сделать, или кто-нибудь знает, что ближе к этому решению?

Ответы [ 3 ]

4 голосов
/ 18 декабря 2010

Вы говорите об авторегистрации. Многие контейнеры IoC поддерживают это.

StructureMap http://structuremap.net/structuremap/ScanningAssemblies.htm

Замок Виндзор (см. Нижнюю часть 2-й страницы статьи) http://www.code -magazine.com / article.aspx? Quickid = 0906051

Autofac http://code.google.com/p/autofac/wiki/Scanning

Ninject Похоже, вы можете сделать это через Kernel.Scan (), хотя я не смог найти документы. (Сервер был недоступен.) Как использовать расширение Ninject Conventions без ссылки на сборку (или типы внутри нее)

В последний раз я смотрел, Unity не поддерживает автоматическую регистрацию, хотя это может измениться с недавним выпуском.

ОБНОВЛЕНИЕ: Спасибо Маурисио за то, что заметил, что я неправильно определил желаемую функцию как автоматическое подключение Исправлены и обновлены ссылки.

3 голосов
/ 18 декабря 2010

В Autofac самый простой способ добиться этого:

var builder = new ContainerBuilder();

var data = typeof(BarRepo).Assembly();
builder.RegisterAssemblyTypes(data).AsImplementedInterfaces();

var service = typeof(BarService).Assembly();
builder.RegisterAssemblyTypes(service).AsImplementedInterfactes();

var container = builder.Build();

Теперь это не будет избирательным в отношении сервисных интерфейсов, происходящих из базовой сборки. Если это действительно имеет значение (вероятно, не должно), тогда измените вышеуказанные регистрации следующим образом:

var core = typeof(IBarRepo).Assembly();

builder.RegisterAssemblyTypes(data)
    .As(t => t.GetInterfaces()
         .Where(i => i.Assembly == core)
         .Select(i => new TypedService(i)));

Ура, Ник

1 голос
/ 18 декабря 2010

Windsor позволяет вам легко регистрировать классы как интерфейсы, которые они предоставляют, либо все из них, либо выборочно. ( см. Документацию ).

Он не имеет поддержки OOTB для вашего сценария (фильтрация реализованных интерфейсов, чтобы включить только интерфейсы из конкретной сборки), но (как и для всего в Виндзоре) есть ловушка, которую вы можете использовать, чтобы легко иметь это.

container.Register(
   AllTypes.FromAssemblyContaining<SomeClass>()
      WithService.Select((type, @base) =>
         type.GetAllInterfaces()
             .Where(i => i.Assembly == yourInterfacesAssembly)))
);
...