问题
I have several (eventually 100+) small DLL projects all based on MediatR. This means that the interfaces in use are just the IMediatR interfaces (IRequest<TResult>, IRequestHandler<IRequest<TResult>, TResult>). Since a lot of these do not have a UI and are called via orchestration from another DLL I was thinking I could create an Autofac Container project (DLL), register all the micro-services, then resolve what I need at runtime in another app that consumes my container. So far, so good.
Where I am running into problems is the registration of each and every CQRS handler. Right now, while everything is small in scope, they are being defined inline like this:
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
}
}
So, my question is: How do I correctly do this registration? Right now, 2 or 3 "cores" (micro-services) but next month, 20, next year, 200, etc...
TIA
回答1:
Instead of manually register assembly by assembly, you could do Assembly Scanning to retrieve all assemblies you need, and then, register them in simple loop (code not tested):
var assemblies = /* get assemblies based on project type (web/desktop) */;
foreach(var assembly in assemblies)
{
container.RegisterAssemblyTypes(assembly).AsImplementedInterfaces();
}
Btw, you should not expose your container as public property, unless you have very strong arguments to do so (service locator anti-pattern). Also SingleInstanceFactory
and MultiInstanceFactory
look pretty suspicious for me...
来源:https://stackoverflow.com/questions/35876478/autofac-mediatr-multiple-dll-projects