我是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();
}
}
然后我有很多Projectors(事件处理程序),它们对他们订阅的事件做了不同的事情。
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中注册我的投影仪以便以类似的方式使用它?
提前致谢!
答案 0 :(得分:0)
如果你只有两种类型的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核心,这篇文章https://stackoverflow.com/a/45698048/814735包含有关如何实现这种通用控制器的很好的解释。