我有一个旧的.NET应用程序,它使用Ninject来解析ICommandHandler的一个实例,如下所示。我还使用Db上下文来调用SaveChanges()。我现在正在尝试转换此代码,以便我可以在具有内置依赖注入的新.NET Core应用程序中使用它。
public class CommandInvoker : ICommandInvoker
{
private readonly IKernel _kernel;
private readonly IArhomaContext _context;
public CommandInvoker(IKernel kernel, IArhomaContext context)
{
_kernel = kernel;
_context = context;
}
public void Execute<T>(T command)
{
var handler = _kernel.TryGet<ICommandHandler<T>>();
handler.Handle(command);
_context.SaveChanges();
}
}
我认为我必须将以下内容添加到Startup.cs中的ConfigureServices方法中:
services.AddScoped<ICommandHandler, CommandHandler>();
但是ICommandHandler有一个类型参数。如何完成或注册?
其次,我需要解决它以创建执行命令的处理程序。如何在.NET Core中解决这个问题?
P.S。我不想在我的.NET Core应用程序中继续使用Ninject。
答案 0 :(得分:0)
根据LukeHutton给出的答案,注册使用:
services.AddScoped(typeof(ICommandHandler<>), typeof(CommandHandler<>));
要解决:
// You should only Build the provider once in your code, to do so:
var provider = services.BuilderServiceProvider(); //to protect against runtime injection, which is an anti-pattern
// to Get an Actual ICommandHandler
var commandHandler = services.GetService<ICommandHandler<MyT>>();
答案 1 :(得分:0)
我经历了同样的问题,我创建了一些事件处理结构来解决Asp.NET Core 2.0上的这个问题。 我创建了一个事件registrator来映射事件处理程序:
public class EventRegistrator : IEventRegistrator
{
private readonly IDictionary<Type, IList<Type>> dictionary = new Dictionary<Type, IList<Type>>();
public IEventRegistrator Add<Event, Handler>()
where Event : IEvent
where Handler : IEventHandler<Event>
{
var eventType = typeof(Event);
var handlerType = typeof(Handler);
if (!dictionary.ContainsKey(eventType))
{
dictionary[eventType] = new List<Type>();
}
dictionary[eventType].Add(handlerType);
return this;
}
public IEnumerable<Type> GetHandlers<Event>()
where Event : IEvent
{
if (dictionary.TryGetValue(typeof(Event), out IList<Type> handlers))
{
return handlers;
}
return new List<Type>();
}
public IEnumerable<Type> GetHandlers()
{
foreach (var item in dictionary)
{
foreach (var handler in item.Value)
{
yield return handler;
}
}
}
}
以下编码将添加到启动中:
var registrator = new EventRegistrator()
.Add<TrainerCreatedEvent, ProcessionalWelcomeMessageHandler>()
.Add<TrainerCreatedEvent, ProfessionalCreatedCertificationStartHandler>();
services.AddSingleton<IEventRegistrator>(context =>
{
return registrator; // All Event Handlers should be handled here
});
foreach (var handler in registrator.GetHandlers())
{
services.AddTransient(handler);
}
然后是调解员(派遣或举起事件的对象):
public class SimpleMediator : IMediator
{
private readonly IServiceProvider provider;
private readonly IEventRegistrator registrator;
public SimpleMediator(IEventRegistrator registrator, IServiceProvider provider)
{
this.registrator = registrator;
this.provider = provider;
}
public async Task Dispatch<T>(T target)
where T : IEvent
{
var handlers = registrator.GetHandlers<T>();
if (handlers == null) return;
foreach (Type item in handlers)
{
var instance = (IEventHandler<T>)provider.GetService(item);
if (instance == null) throw new NullReferenceException($"No type {item.ToString()} has been registred on the service collections. Add this type to the service collections.");
await instance.HandleAsync(target);
}
}
}
缺少的接口:
public interface IMediator
{
Task Dispatch<T>(T target)
where T : IEvent;
}
public interface IEventRegistrator
{
/// <summary>
/// Register a handler to the event. Multiple handlers are supported
/// </summary>
IEventRegistrator Add<Event, Handler>()
where Event : IEvent
where Handler : IEventHandler<Event>;
/// <summary>
/// Returns all handlers to a event
/// </summary>
IEnumerable<Type> GetHandlers<Event>() where Event : IEvent;
/// <summary>
/// Returns all handlers of all registered events.
/// </summary>
IEnumerable<Type> GetHandlers();
}