将基于IUnityContainer的泛型C# Mediator类重构为Ninject实现
Unity 转 Ninject:Mediator 类重构及疑问解答
疑问解答
- 是否应使用Ninject的StandardKernel替换IUnityContainer?
是的,StandardKernel是Ninject的核心容器实现,对应Unity的IUnityContainer,用来管理依赖的注册与实例解析。 - 是否需要使用Ninject的Bind方法替代Unity的Resolve方法?
不是。Bind是用来注册依赖关系的(对应Unity的Register系列方法),而Resolve是从容器获取实例的操作,Ninject用Get方法实现相同功能,和Unity的Resolve作用一致。你需要在应用启动时用Bind注册所有Handler,再在Mediator里用Get获取实例。
重构后的 Mediator.cs(Ninject 实现)
using Ninject; public sealed class Mediator : IMediator { private readonly IKernel _kernel; public Mediator(IKernel kernel) { _kernel = kernel; } public TResponse Request<TResponse>(IQuery<TResponse> query) { var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResponse)); dynamic handler = _kernel.Get(handlerType); // Ninject用Get替代Unity的Resolve return handler.Handle((dynamic)query); } public TResult Send<TResult>(ICommand<TResult> command) { var handlerType = typeof(ICommandHandler<,>).MakeGenericType(command.GetType(), typeof(TResult)); dynamic handler = _kernel.Get(handlerType); return handler.Handle((dynamic)command); } }
依赖注册示例
应用初始化时,需要用Ninject注册所有QueryHandler和CommandHandler,示例如下:
var kernel = new StandardKernel(); // 单个Handler注册 kernel.Bind<IQueryHandler<GetUserQuery, UserDto>>().To<GetUserQueryHandler>(); kernel.Bind<ICommandHandler<CreateUserCommand, Guid>>().To<CreateUserCommandHandler>(); // 批量注册(需安装Ninject.Extensions.Conventions包) kernel.Bind(x => x .FromAssemblyContaining<GetUserQueryHandler>() .SelectAllClasses() .InheritedFrom(typeof(IQueryHandler<,>)) .BindAllInterfaces()); // 注册Mediator kernel.Bind<IMediator>().To<Mediator>();
原接口定义
IMediator.cs
public interface IMediator { TResponse Request<TResponse>(IQuery<TResponse> query); TResult Send<TResult>(ICommand<TResult> command); }
IQuery.cs
public interface IQuery<out TResponse> { }
IQueryHandler.cs
public interface IQueryHandler<in TQuery, out TResponse> where TQuery : IQuery<TResponse> { TResponse Handle(TQuery query); }
ICommand.cs
public interface ICommand<out TResult> { } public interface ICommand { }
ICommandHandler.cs
public interface ICommandHandler<in TCommand, out TResult> where TCommand : ICommand<TResult> { TResult Handle(TCommand command); } public interface ICommandHandler<in TCommand> where TCommand : ICommand { void Handle(TCommand command); }
内容的提问来源于stack exchange,提问作者ADH
相关产品推荐
相关产品推荐

