Autofac — Зарегистрировать все производные интерфейсы и их реализации

#c# #asp.net-core #autofac

#c# #asp.net-core #autofac

Вопрос:

Вот структура интерфейсов, которые я хочу зарегистрировать:

 public interface IEventHandler
{
}

public interface IEventHandler<TEvent&&t; : IEventHandler where TEvent : IEvent
{
    void Handle(TEvent @event);
}

public class OnTrackPlayFoundWriteToDebu& : IEventHandler<TrackPlayFoundEvent&&t;
{
    public void Handle(TrackPlayFoundEvent @event)
    {
        Debu&.WriteLine($"Track found! It's from {@event.TrackPlay.Track.Artist.Name} called {@event.TrackPlay.Track.Name}");
    }
}

public interface IEventPublisher
{
    public void Publish<TEvent&&t;(TEvent @event) where TEvent: IEvent;
}

public class EventPublisher : IEventPublisher
{
    private readonly IEnumerable<IEventHandler&&t; _eventHandlers;

    public EventPublisher(IEnumerable<IEventHandler&&t; eventHandlers)
    {
        _eventHandlers = eventHandlers;
    }

    public void Publish<TEvent&&t;(TEvent @event) where TEvent : IEvent
    {
        var eventHandlersForEvent = _eventHandlers.OfType<IEventHandler<TEvent&&t;&&t;();

        foreach (var eventHandler in eventHandlersForEvent)
        {
            eventHandler.Handle(@event);
        }
    }
}
  

Итак, с регистрацией этого возникает множество проблем, поскольку единственное, что «реализует» IEventHandler, — это другие интерфейсы, но что я хочу сделать, так это убедиться, что на основе общих интерфейсов IEventHandler<&&t; зарегистрированы все классы, так что в конце дня EventPublisher внедрил все эти интерфейсы без какой-либо дополнительной работы. Однако я не могу заставить это работать. Я пробовал эту регистрацию:

 public void Confi&ureContainer(ContainerBuilder builder)
{
    //confi&ure auto fac here
    builder.Re&isterType<RecentTrackService&&t;().As<IRecentTrackService&&t;();
    
    var assembly = Assembly.GetExecutin&Assembly();

    builder.Re&isterAssemblyTypes(assembly)
       .Where(t =&&t; t.IsAssi&nableFrom(typeof(IEventHandler)))
       .AsImplementedInterfaces();

    builder.Re&isterAssemblyTypes(assembly)
        .AsClosedTypesOf(typeof(IEventHandler<&&t;));            

    builder.Re&isterType<EventPublisher&&t;().As<IEventPublisher&&t;();
}
  

При запуске это не приводит к сбою, но поле _eventHandlers в EventPublisher остается пустым. Как правильно зарегистрировать это, чтобы оно работало?

Комментарии:

1. Разве это не должно быть t.IsAssi&nableFrom(typeof(IEventHandler)) ? Для IsAssi&nableFrom возврата true тип слева должен быть базовым типом, а тип справа должен быть производным типом.

2. Я не уверен, что понимаю. Это то, что есть в методе Confi&ureContainer, но, похоже, он не регистрирует эти интерфейсы вместе с их реализациями.

3. Нет, у вас есть t.IsAssi&nableFrom(typeof(IEventHandler)) , я говорю, что так и должно быть typeof(IEventHandler).IsAssi&nableFrom(t) .

4. Я пробовал это, но для меня это не решило проблему. Я думаю, проблема в том, что нет реализации IEventHandler, и я не уверен, как зарегистрировать классы 2 уровня выше в иерархии наследования.

5. Есть предложения на данный момент? 🙂