0
votes

I'm working with an ASP.Net Core Web application and using the typical registration method in the Startup.cs class to register my services.

I have a need to access the registered services in the IServiceCollection in order to iterate over them to find a particular service instance.

How can this be done with the ASP.Net Core DI container? I need to do this outside of a controller.

Below is an example of what I'm trying to do. Note that the All method does not exist on the ServiceCollection, that's what I'm trying to figure out:

public class EventContainer : IEventDispatcher
{
    private readonly IServiceCollection _serviceCollection;

    public EventContainer(IServiceCollection serviceCollection)
    {
        _serviceCollection = serviceCollection;
    }

    public void Dispatch<TEvent>(TEvent eventToDispatch) where TEvent : IDomainEvent
    {
        foreach (var handler in _serviceCollection.All<IDomainHandler<TEvent>>())
        {
            handler.Handle(eventToDispatch);
        }
    }
}
1
Is it correct that you try to inject IServiceCollection in the constructor of EventContainer by registering it in your DI container? - larsbe
you really want to iterate it manually - why don't you want to use IServiceProvider: serviceProvider.GetService<IDomainHandler<TEvent>>() ? - Ivan Yuriev
Because my event handler might have several types associated with it. Like EmailHandler, PushNotificationHandler, etc. - Don Fitz

1 Answers

2
votes

After much trial end error I came upon a solution, so I must do the answer my own question of shame. The solution turned out to be quite simple yet not very intuitive. The key is to call BuildServiceProvider().GetServices() on the ServiceCollection:

public class EventContainer : IEventDispatcher
{
    private readonly IServiceCollection _serviceCollection;

    public EventContainer(IServiceCollection serviceCollection)
    {
        _serviceCollection = serviceCollection;
    }

    public void Dispatch<TEvent>(TEvent eventToDispatch) where TEvent : IDomainEvent
    {
        var services = _serviceCollection.BuildServiceProvider().GetServices<IDomainHandler<TEvent>>();

        foreach (var handler in services)
        {
            handler.Handle(eventToDispatch);
        }
    }
}