我已经经历了数十个类似的问题,但没有找到解决问题的方法。因此,这可能是Autofac 4的问题,我发现的所有问题都与以前的版本有关。
我有以下事件发布者
public class EventPublisher : IEventPublisher
{
private readonly IComponentContext _context;
public EventPublisher(IComponentContext context)
{
_context = context;
}
public async Task Publish<TEvent>(TEvent @event) where TEvent : IEvent
{
if (@event == null)
{
throw new ArgumentNullException(nameof(@event));
}
var eventHandlers = _context.Resolve<IEnumerable<IEventHandler<TEvent>>>();
foreach (IEventHandler<TEvent> handler in eventHandlers)
{
await handler.Handle(@event);
}
}
}
这是服务注册
builder.RegisterAssemblyTypes(typeof(SiteEventsHandler).Assembly).AsClosedTypesOf(typeof(IEventHandler<>));
尽管服务已正确注册(我可以在注册表中看到它们),但 resolve 方法返回一个空列表。
更新
以下是调用事件发布者的命令发送
器public class CommandSender : ICommandSender
{
private readonly IResolver _resolver;
private readonly IEventPublisher _eventPublisher;
public CommandSender(IResolver resolver, IEventPublisher eventPublisher)
{
_resolver = resolver;
_eventPublisher = eventPublisher;
}
public void Send<TCommand>(TCommand command) where TCommand : ICommand
{
if (command == null)
{
throw new ArgumentNullException(nameof(command));
}
var commandHandler = _resolver.Resolve<ICommandHandler<TCommand>>();
if (commandHandler == null)
{
throw new Exception($"No handler found for command '{command.GetType().FullName}'");
}
var events = commandHandler.Handle(command);
foreach (var @event in events)
{
_eventPublisher.Publish(@event);
}
}
}
命令处理程序返回必须发布的域事件的列表。
在组合根中使用 RegisterGeneric 来注册 IEventHandler<>
http://docs.autofac.org/en/latest/register/registration.html#open-generic-components
更新
啊,我现在明白了,你只需要构造正确的类型来传递给Autofac。在 EventPublisher 类中尝试此操作:
public async Task Publish<TEvent>(TEvent @event) where TEvent : IEvent
{
if (@event == null)
{
throw new ArgumentNullException(nameof(@event));
}
var handlerType = typeof (IEventHandler<>).MakeGenericType(@event.GetType());
var handlerCollectionType = typeof (IEnumerable<>).MakeGenericType(handlerType);
var eventHandlers = _context.Resolve(handlerCollectionType);
foreach (IEventHandler<TEvent> handler in eventHandlers)
{
await handler.Handle(@event);
}
}
结束更新
您确定服务注册正确吗?可能是您注册的程序集不正确:
typeof(SiteEventsHandler).Assembly
这适用于我的以下设置 - 事件接口和类:
public interface IEvent {}
public class MyEvent : IEvent {}
服务接口:
public interface IEventHandler<in T> where T : Event {}
还有两个实现:
public class MyEventHandlerOne : IEventHandler<MyEvent> {}
public class MyEventHandlerTwo : IEventHandler<MyEvent> {}
Autofac 的配置如下:
var builder = new ContainerBuilder();
builder
.RegisterAssemblyTypes(typeof (IEvent).Assembly)
.AsClosedTypesOf(typeof (IEventHandler<>))
.AsImplementedInterfaces()
.InstancePerDependency();
_container = builder.Build();
解析服务会提供 2 个集合:
var canResolve = CanResolve<MyEvent>(_container);
static bool CanResolve<T>(IComponentContext context) where T : IEvent
{
var handlers = context.Resolve<IEnumerable<IEventHandler<T>>>().ToList();
return handlers.Any();
}
在34gl3的评论后编辑