我在没有找到解决问题的方法的情况下经历了数十个类似的问题。 因此,它可能是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);
}
}
}
命令处理程序返回必须发布的域事件列表。
答案 0 :(得分:0)
<强>更新强>
我现在明白了,你只需构造正确的类型传递给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
这对我有用,具有以下设置 - 事件界面&amp;类:
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的评论之后编辑
答案 1 :(得分:0)
在Composition Root中使用RegisterGeneric注册IEventHandler&lt;&gt;
http://docs.autofac.org/en/latest/register/registration.html#open-generic-components