РЕДАКТИРОВАТЬ:
Я на самом деле легко может быть "взломан", но я не могу понять, почему мы можем это сделать? Здесь я убираю IMessageHandler
требование к интерфейсу для параметра TService
generi c, поэтому я могу использовать любой интерфейс с его реализацией.
public class DelegateHandler
{
public delegate void MyMessagebrokerDelegateHandler<TService, TImplementation>(IServiceCollection services)
where TService : class, IMessageHandler
where TImplementation : class, TService, new();
public static void MyMessagebrokerHandlerSupplier<TService, TImplementation>(IServiceCollection services)
where TService : class //, IMessageHandler <== REMOVED !!!
where TImplementation : class, TService, new()
{
services.AddSingleton<TService, TImplementation>();
}
}
Так Я могу сделать:
services.UseTheSuperMessageBroker(Configuration,
handlers: new MyMessagebrokerDelegateHandler<IMessageHandler, BaseMessageHandler>[] {
MyMessagebrokerHandlerSupplier<IHttpContextAccessor, HttpContextAccessor>, // <== HACKED !
MyMessagebrokerHandlerSupplier<IMessageHandler, myMessageHandler2>
});
Но ПОЧЕМУ я могу использовать обещание, которое не уважает прототип делегата? TService : class, IMessageHandler
в делегате и TService : where TService : class
в методе stati c ??
Исходное сообщение:
Я наконец нашел решение, основанное на generic delegates
, я не знаю если то же самое можно сделать и с Func
. Вот мой новый метод расширения:
public static IServiceCollection UseTheSuperMessageBroker<TService, TImplementation>(this IServiceCollection services, IConfiguration config, params MyMessagebrokerDelegateHandler<TService, TImplementation>[] handlers)
where TService : class, IMessageHandler
where TImplementation : class, TService, new()
{
handlers.ToList().ForEach(h =>
{
// Resolve the promise
h.Invoke(services);
});
...
Мой обработчик generi c:
public class DelegateHandler
{
public delegate void MyMessagebrokerDelegateHandler<TService, TImplementation>(IServiceCollection services)
where TService : class, IMessageHandler
where TImplementation : class, TService, new();
public static void MyMessagebrokerHandlerSupplier<TService, TImplementation>(IServiceCollection services)
where TService : class, IMessageHandler
where TImplementation : class, TService, new()
{
services.AddSingleton<TService, TImplementation>();
}
}
Базовый класс, используемый только для объявления клиента ( знаете ли вы какие-либо способ избавиться от этого? )
public sealed class BaseMessageHandler : IMessageHandler
{
public Subscribers _sub { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public void HandleMessageAsync(object sender, BasicDeliverEventArgs e)
{
throw new NotImplementedException();
}
}
И, наконец, клиент звонит:
services.UseTheSuperMessageBroker(Configuration,
handlers: new MyMessagebrokerDelegateHandler<IMessageHandler, BaseMessageHandler>[] {
MyMessagebrokerHandlerSupplier<IMessageHandler, myMessageHandler1>,
MyMessagebrokerHandlerSupplier<IMessageHandler, myMessageHandler2>
});
Работает как шарм!