You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 14:48:25