Autofac, MediatR и несколько проектов DLL

У меня есть несколько (в конечном итоге более 100) небольших проектов DLL, основанных на MediatR. Это означает, что используемые интерфейсы являются только интерфейсами IMediatR (IRequest, IRequestHandler, TResult>). Поскольку многие из них не имеют пользовательского интерфейса и вызываются через оркестровку из другой библиотеки DLL, я подумал, что могу создать проект контейнера Autofac (DLL), зарегистрировать все микро-сервисы, а затем решить то, что мне нужно во время выполнения, в другом приложении, которое потребляет мой контейнер. Все идет нормально.

Я сталкиваюсь с проблемами при регистрации каждого обработчика CQRS. Прямо сейчас, хотя все имеет небольшую область видимости, они определяются внутри строки следующим образом:

namespace My.Core.Container
{
    public class CoreDependencies
    {
        #region Properties
        public IMediator Mediator { get; private set; }
        public IContainer Container { get; private set; }

        private static ContainerBuilder _builder;
        #endregion

        #region Constructor
        public CoreDependencies()
        {
            _builder = new ContainerBuilder();

            // register MediatR types...
            _builder.RegisterSource(new ContravariantRegistrationSource());
            _builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly).AsImplementedInterfaces();
            _builder.Register<SingleInstanceFactory>(ctx => 
            {
                var c = ctx.Resolve<IComponentContext>();
                return t => c.Resolve(t);
            });
            _builder.Register<MultiInstanceFactory>(ctx =>
            {
                var c = ctx.Resolve<IComponentContext>();
                return t => (IEnumerable<object>)c.Resolve(typeof(IEnumerable<>).MakeGenericType(t));
            });

            // ################################################## //
            // register EntityTree micro services...
            _builder.RegisterAssemblyTypes(typeof(My.Core.EntityTree.GetChildren).GetTypeInfo().Assembly).AsImplementedInterfaces();
            _builder.RegisterAssemblyTypes(typeof(My.Core.EntityTree.DeleteEntity).GetTypeInfo().Assembly).AsImplementedInterfaces();
            _builder.RegisterAssemblyTypes(typeof(My.Core.EntityTree.AddEntity).GetTypeInfo().Assembly).AsImplementedInterfaces();

            // register next micro services...
            // register next micro services...
            // ad naseum...
            // ################################################## //

            // Now build it...
            Container = _builder.Build();
            Mediator = Container.Resolve<IMediator>();
        }
        #endregion
    }
}

Итак, мой вопрос: как мне правильно сделать эту регистрацию? Прямо сейчас, 2 или 3 "ядра" (микро-услуги), но в следующем месяце, 20, в следующем году, 200 и т. Д.

ТИА

1 ответ

Решение

Вместо того, чтобы вручную регистрировать сборку по сборке, вы можете выполнить сканирование сборок, чтобы получить все необходимые сборки, а затем зарегистрировать их в простом цикле (код не проверен):

var assemblies = /* get assemblies based on project type (web/desktop) */;
foreach(var assembly in assemblies)
{
    container.RegisterAssemblyTypes(assembly).AsImplementedInterfaces();
}

Кстати, вы не должны выставлять свой контейнер как общедоступное свойство, если у вас нет очень веских аргументов для этого (анти-паттерн поиска сервисов). Также SingleInstanceFactory а также MultiInstanceFactory выглядеть довольно подозрительно для меня...

Другие вопросы по тегам