[英]Autofac 4 Resolve<IEnumerable<IEventHandler<TEvent>>> returns an empty list
我经历过数十个类似的问题,但没有找到解决问题的方法。 因此,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);
}
}
}
命令处理程序返回必须发布的域事件的列表。
更新资料
啊,我现在明白了,您只需要构造正确的类型即可传递给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评论后编辑
在您的合成根目录中使用RegisterGeneric来注册IEventHandler <>
http://docs.autofac.org/en/latest/register/registration.html#open-generic-components
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.