编辑:
事实上它很容易被“黑”,但我不明白为什么我们能够做到这一点?
在这里,我删除了TService 泛型参数的IMessageHandler 接口要求,因此我可以在其实现中使用任何接口。
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 ??
原帖:
我终于找到了基于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);
});
...
我的通用处理程序:
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>
});
它就像一个魅力!