简单注入器:如何将事件处理程序实例注册到事件调度程序
Simple Injector: How to register event handlers instances to the event dispatcher
我有一个接口。
// Assembly: Common
public interface IEventHandler<TEvent> where TEvent : IDomainEvent
{
void HandleEvent(TEvent theEvent);
}
// Assembly: Common
public interface IDomainEvent
{
}
// Assembly: Common
public interface IEventDispatcher
{
void Register(IEventHandler<IDomainEvent> handler);
void Dispatch(IDomainEvent theEvent);
}
// Assembly: Membership
public sealed class MemberRegistered : IDomainEvent
{
// event properties
}
然后在我的 ASP MVC 5 项目上,我有事件的事件处理程序。
public sealed class MemberRegisteredHandler : IEventHandler<MemberRegistered>
{
public MemberRegisteredHandler(ApplicationUserManager userManager)
{
this.userManager = userManager;
}
private ApplicationUserManager userManager;
public void HandleEvent(MemberRegistered theEvent)
{
User user = new User(
theEvent.MemberId.ToString(),
theEvent.Username,
theEvent.PersonalInformation.Email);
this.userManager.CreateUserWithRandomPassword(user);
}
}
关于我的启动 class
var container = new Container();
// TIP: For Simple Injector >= v4.3, instead use container.Collection.Register.
container.RegisterManyForOpenGeneric(
typeof(IEventHandler<>),
container.RegisterAll,
Assembly.GetExecutingAssembly());
container.Register<IEventDispatcher, SimpleEventDispatcher>();
这样,我怎样才能得到 event dispatcher
并将所有事件处理程序注册到其中?
我试过了
var eventDispatcher = container.GetInstance<IEventDispatcher>();
foreach (var handler in container.GetAllInstances<IEventHandler<IDomainEvent>>())
{
eventDispatcher.Register(handler);
}
但是它不起作用。 GetAllInstances 方法未返回任何内容。
Things to note:
IEventDispatcher
依赖于我的 EF DbContext 构造函数,我(现在)有两个上下文。 MembershipContext
和 IdentityAccessContext
都派生自 EventDipatchingContext
,派生自 DbContext
。
基本上是 EventDispatchingContext : DbContext
然后是 MembershipContext : EventDispatchingContext
EventDispatchingContext
负责将事件委托给事件调度程序 after its Commit() method is invoked
。他们不会在我的域实体上立即被解雇。我从 Jimmy Bogard 的博客中得到了这个架构
https://lostechies.com/jimmybogard/2014/05/13/a-better-domain-events-pattern/
在这种情况下,我需要将 IEventDispatcher 设为单例吗?为什么?
如何正确地将处理程序注册到事件调度程序?
阻止 'registering' 事件调度程序中的事件处理程序。相反,您应该将事件调度程序实现作为 Composition Root 的一部分。这样您就可以安全地从调度程序中依赖容器,如下所示:
public class SimpleInjectorEventDispatcher : IEventDispatcher
{
private readonly Container container;
public SimpleInjectorEventDispatcher(Container container)
{
this.container = container;
}
public void Dispatch(IDomainEvent theEvent)
{
var handlerType =
typeof(IEventHandler<>).MakeGenericType(theEvent.GetType());
var handlers = this.container.GetAllInstances(handlerType);
foreach (dynamic handler in handlers)
{
handler.HandleEvent((dynamic)theEvent);
}
}
}
请注意 IEventDispatcher
接口现在只包含一个 Dispatch
方法。
Do I need to make IEventDispatcher a singleton in this case? Why?
您不必将事件调度程序实现设为单例,但由于它没有依赖项也没有状态,因此将其设为单例是明智的。这样它的消费者也可以成为单身人士。 more singletons the merrier.
我有一个接口。
// Assembly: Common
public interface IEventHandler<TEvent> where TEvent : IDomainEvent
{
void HandleEvent(TEvent theEvent);
}
// Assembly: Common
public interface IDomainEvent
{
}
// Assembly: Common
public interface IEventDispatcher
{
void Register(IEventHandler<IDomainEvent> handler);
void Dispatch(IDomainEvent theEvent);
}
// Assembly: Membership
public sealed class MemberRegistered : IDomainEvent
{
// event properties
}
然后在我的 ASP MVC 5 项目上,我有事件的事件处理程序。
public sealed class MemberRegisteredHandler : IEventHandler<MemberRegistered>
{
public MemberRegisteredHandler(ApplicationUserManager userManager)
{
this.userManager = userManager;
}
private ApplicationUserManager userManager;
public void HandleEvent(MemberRegistered theEvent)
{
User user = new User(
theEvent.MemberId.ToString(),
theEvent.Username,
theEvent.PersonalInformation.Email);
this.userManager.CreateUserWithRandomPassword(user);
}
}
关于我的启动 class
var container = new Container();
// TIP: For Simple Injector >= v4.3, instead use container.Collection.Register.
container.RegisterManyForOpenGeneric(
typeof(IEventHandler<>),
container.RegisterAll,
Assembly.GetExecutingAssembly());
container.Register<IEventDispatcher, SimpleEventDispatcher>();
这样,我怎样才能得到 event dispatcher
并将所有事件处理程序注册到其中?
我试过了
var eventDispatcher = container.GetInstance<IEventDispatcher>();
foreach (var handler in container.GetAllInstances<IEventHandler<IDomainEvent>>())
{
eventDispatcher.Register(handler);
}
但是它不起作用。 GetAllInstances 方法未返回任何内容。
Things to note:
IEventDispatcher
依赖于我的 EF DbContext 构造函数,我(现在)有两个上下文。 MembershipContext
和 IdentityAccessContext
都派生自 EventDipatchingContext
,派生自 DbContext
。
基本上是 EventDispatchingContext : DbContext
然后是 MembershipContext : EventDispatchingContext
EventDispatchingContext
负责将事件委托给事件调度程序 after its Commit() method is invoked
。他们不会在我的域实体上立即被解雇。我从 Jimmy Bogard 的博客中得到了这个架构
https://lostechies.com/jimmybogard/2014/05/13/a-better-domain-events-pattern/
在这种情况下,我需要将 IEventDispatcher 设为单例吗?为什么?
如何正确地将处理程序注册到事件调度程序?
阻止 'registering' 事件调度程序中的事件处理程序。相反,您应该将事件调度程序实现作为 Composition Root 的一部分。这样您就可以安全地从调度程序中依赖容器,如下所示:
public class SimpleInjectorEventDispatcher : IEventDispatcher
{
private readonly Container container;
public SimpleInjectorEventDispatcher(Container container)
{
this.container = container;
}
public void Dispatch(IDomainEvent theEvent)
{
var handlerType =
typeof(IEventHandler<>).MakeGenericType(theEvent.GetType());
var handlers = this.container.GetAllInstances(handlerType);
foreach (dynamic handler in handlers)
{
handler.HandleEvent((dynamic)theEvent);
}
}
}
请注意 IEventDispatcher
接口现在只包含一个 Dispatch
方法。
Do I need to make IEventDispatcher a singleton in this case? Why?
您不必将事件调度程序实现设为单例,但由于它没有依赖项也没有状态,因此将其设为单例是明智的。这样它的消费者也可以成为单身人士。 more singletons the merrier.