Using RegisterInitializer to Post Event Handlers

I have a WCF service that uses Simple Injector to inject dependencies. I want to hook some event handlers in the container loader. I created an interface IStatusChangeNotification:

public interface IStatusChangeNotification
{
    event EventHandler<int> JobStatusChange;
}

My CommandHandlerimplements IStatusChangeNotificationand there are two classes of event handler EmailNotificationand MmrNotification, each of which defines a method Notify(). Then in my botstrap code I have the following:

container.Register<EmailNotification>();
container.Register<MmrNotification>();

container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>),
                                     Assembly.GetExecutingAssembly());

container.RegisterInitializer<IStatusChangeNotification>(scn => 
    {
        scn.JobStatusChange += container.GetInstance<EmailNotification>().Notify;
        scn.JobStatusChange += container.GetInstance<MmrNotification>().Notify;
    });

This works and notifications are accepted. My question is, is this the right / best approach for connecting event handlers? How to remove handlers at the end of a request and fail to delete them, will lead to a memory leak?

+4
1

, , , . , , . .NET , :

// Abstractions
public interface IEventHandler<TEvent> where TEvent : IDomainEvent {
    void Handle(TEvent e);
}

public interface IEventPublisher {
    void Publish<TEvent>(TEvent e) where TEvent : IDomainEvent;
}

// Events
public class JobStatusChanged : IDomainEvent {
    public readonly int JobId;
    public JobStatusChanged(int jobId) {
        this.JobId = jobId;
    }
}

// Container-specific Event Publisher implementation
public class SimpleInjectorEventPublisher : IEventPublisher {
    private readonly Container container;
    public SimpleInjectorEventPublisher(Container container) {
        this.container = container;
    }

    public void Publish<TEvent>(TEvent e) {
        var handlers = container.GetAllInstances<IEventHandler<TEvent>>();
        foreach (var handler in handlers) {
            hanlder.Handle(e);
        }
    }
}

:

// Event Handlers
public class EmailNotificationJobStatusChangedHandler
    : IEventHandler<JobStatusChanged> {
    public void Handle(JobStatusChanged e)  {
        // TODO: Implementation
    }
}

public class MmrNotificationJobStatusChangedHandler
    : IEventHandler<JobStatusChanged> {
    public void Handle(JobStatusChanged e)  {
        // TODO: Implementation
    }
}

// Command Handler that publishes 
public class ChangeJobStatusCommandHandler : ICommandHandler<ChangeJobStatus> {
    private readonly IEventPublisher publisher;
    public ChangeJobStatusCommandHandler(IEventPublisher publisher) {
        this.publisher = publisher;
    }

    public void Handle(ChangeJobStatus command) {
        // change job status
        this.publisher.Publish(new JobStatusChanged(command.JobId));
    }
}

:

container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>),
    Assembly.GetExecutingAssembly());

// This registers a collection of eventhandlers with RegisterAll,
// since there can be multiple implementations for the same event.
container.RegisterManyForOpenGeneric(typeof(IEventHandler<>),
    container.RegisterAll,
    Assembly.GetExecutingAssembly());

, IEventHandler<JobStatusChanged> . RegisterInitializer .

:

  • IEventPublisher , .
  • , , .
  • , .
  • , SimpleInjectorEventProcessor. , , , ( ).
+7

Source: https://habr.com/ru/post/1531267/


All Articles