如何使用 Autofac 解决通用事件处理程序的不同实现
How to resolve different implementations of generic event handlers with Autofac
我是 Autofac 的新手,我无法获得事件订阅者应用程序工作的示例。你能帮我建模吗?
思路如下。
我有一个 REST API 控制器,客户端可以在其中 POST 事件(IDomainEvent 的实现)
控制器需要接收注入的所有投影仪 类(事件处理程序),它们将对事件执行某些操作。
public class EventsController
: Controller
{
private readonly IEnumerable<IEventHandler> _projectors;
public EventsController(IEnumerable<IEventHandler> projectors)
{
_projectors = projectors;
}
[HttpPost("EventA")]
public IActionResult AddEventA([FromBody]EventA evt)
{
foreach (var projector in _projectors)
{
projector.Handle(evt);
}
return Ok();
}
[HttpPost("EventB")]
public IActionResult AddEventB([FromBody]EventB evt)
{
foreach (var projector in _projectors)
{
projector.Handle(evt);
}
return Ok();
}
}
然后我有许多投影仪(事件处理程序)对它们订阅的事件执行不同的操作。
public class ProjectorA : IEventHandler<EventA>, IEventHandler<EventB>
{
private readonly IRepository _repository;
public ProjectorA(IRepository repository)
{
_repository = repository;
}
public void Handle(EventA evt)
{
// do something with EventA
}
public void Handle(EventB evt)
{
// do something with EventB
}
}
public class ProjectorB : IEventHandler<EventA>
{
private readonly IRepository _repository;
public ProjectorA(IRepository repository)
{
_repository = repository;
}
public void Handle(EventA evt)
{
// do something with EventA
}
// I don't care about EventB so I don't subscribe to it
}
我猜 IEventHandler 应该是这样的:
public interface IEventHandler<in TDomainEvent>
: IEventHandler
where TDomainEvent : IDomainEvent
{
void Handle(TDomainEvent evt);
}
如何修改此模型以及如何在 Autofac 中注册我的投影仪以类似方式使用它?
提前致谢!
如果你只有 2 种类型的 Event
最简单的方法是有 2 种依赖关系
public class EventsController
: Controller
{
private readonly IEnumerable<IEventHandler<EventA>> _Aprojectors;
private readonly IEnumerable<IEventHandler<EventB>> _Bprojectors;
public EventsController(IEnumerable<IEventHandler<EventA>> Aprojectors,
IEnumerable<IEventHandler<EventB>> Bprojectors)
{
_Aprojectors = Aprojectors;
_Bprojectors = Bprojectors;
}
// ...
}
但是如果你想要一个通用的解决方案,最简单的方法是创建一个通用存储库
public class EventsController<TEvent>
: Controller
where TEvent : IEvent
{
private readonly IEnumerable<IEventHandler<TEvent>> _projectors;
public EventsController(IEnumerable<IEventHandler<Event>> projectors)
{
_projectors = projectors;
}
[HttpPost()]
public IActionResult AddEvent([FromBody]TEvent evt)
{
foreach (var projector in _projectors)
{
projector.Handle(evt);
}
return Ok();
}
}
并像这样声明你的 EventHandler
builder.RegisterType<ProjectorA>().As<IEventHandler<AEvent>>();
builder.RegisterType<ProjectorB>().As<IEventHandler<BEvent>>();
在 ASP.net MVC 中默认不实现通用控制器。对于 ASP.net 核心,这个 post 包含关于如何实现这样一个通用控制器的很好的解释。
我是 Autofac 的新手,我无法获得事件订阅者应用程序工作的示例。你能帮我建模吗?
思路如下。
我有一个 REST API 控制器,客户端可以在其中 POST 事件(IDomainEvent 的实现)
控制器需要接收注入的所有投影仪 类(事件处理程序),它们将对事件执行某些操作。
public class EventsController
: Controller
{
private readonly IEnumerable<IEventHandler> _projectors;
public EventsController(IEnumerable<IEventHandler> projectors)
{
_projectors = projectors;
}
[HttpPost("EventA")]
public IActionResult AddEventA([FromBody]EventA evt)
{
foreach (var projector in _projectors)
{
projector.Handle(evt);
}
return Ok();
}
[HttpPost("EventB")]
public IActionResult AddEventB([FromBody]EventB evt)
{
foreach (var projector in _projectors)
{
projector.Handle(evt);
}
return Ok();
}
}
然后我有许多投影仪(事件处理程序)对它们订阅的事件执行不同的操作。
public class ProjectorA : IEventHandler<EventA>, IEventHandler<EventB>
{
private readonly IRepository _repository;
public ProjectorA(IRepository repository)
{
_repository = repository;
}
public void Handle(EventA evt)
{
// do something with EventA
}
public void Handle(EventB evt)
{
// do something with EventB
}
}
public class ProjectorB : IEventHandler<EventA>
{
private readonly IRepository _repository;
public ProjectorA(IRepository repository)
{
_repository = repository;
}
public void Handle(EventA evt)
{
// do something with EventA
}
// I don't care about EventB so I don't subscribe to it
}
我猜 IEventHandler 应该是这样的:
public interface IEventHandler<in TDomainEvent>
: IEventHandler
where TDomainEvent : IDomainEvent
{
void Handle(TDomainEvent evt);
}
如何修改此模型以及如何在 Autofac 中注册我的投影仪以类似方式使用它?
提前致谢!
如果你只有 2 种类型的 Event
最简单的方法是有 2 种依赖关系
public class EventsController
: Controller
{
private readonly IEnumerable<IEventHandler<EventA>> _Aprojectors;
private readonly IEnumerable<IEventHandler<EventB>> _Bprojectors;
public EventsController(IEnumerable<IEventHandler<EventA>> Aprojectors,
IEnumerable<IEventHandler<EventB>> Bprojectors)
{
_Aprojectors = Aprojectors;
_Bprojectors = Bprojectors;
}
// ...
}
但是如果你想要一个通用的解决方案,最简单的方法是创建一个通用存储库
public class EventsController<TEvent>
: Controller
where TEvent : IEvent
{
private readonly IEnumerable<IEventHandler<TEvent>> _projectors;
public EventsController(IEnumerable<IEventHandler<Event>> projectors)
{
_projectors = projectors;
}
[HttpPost()]
public IActionResult AddEvent([FromBody]TEvent evt)
{
foreach (var projector in _projectors)
{
projector.Handle(evt);
}
return Ok();
}
}
并像这样声明你的 EventHandler
builder.RegisterType<ProjectorA>().As<IEventHandler<AEvent>>();
builder.RegisterType<ProjectorB>().As<IEventHandler<BEvent>>();
在 ASP.net MVC 中默认不实现通用控制器。对于 ASP.net 核心,这个 post