C# 带Ninject的装饰图案

C# 带Ninject的装饰图案,c#,dependency-injection,ninject,service-layer,C#,Dependency Injection,Ninject,Service Layer,我试图应用这种方法来制作一个验证包装器。我已经创建了以下接口,并且使用Ninject作为我的DI容器 public interface ICommandHandler<TCommand> { void Handle(TCommand command); } public interface IValidator<T> { IEnumerable<ValidationResult> Validate(T command)

我试图应用这种方法来制作一个验证包装器。我已经创建了以下接口,并且使用Ninject作为我的DI容器

public interface ICommandHandler<TCommand>
    {
        void Handle(TCommand command);
    }

public interface IValidator<T>
{
    IEnumerable<ValidationResult> Validate(T command);
}

public class ValidationCommandHandlerDecorator<T>:ICommandHandler<T>
{
    private readonly ICommandHandler<T> _decoratee;
    private readonly IValidator<T> _validator;

    public ValidationCommandHandlerDecorator(ICommandHandler<T> decoratee,IValidator<T> validator )
    {
        _decoratee = decoratee;
        _validator = validator;
    }
    public void Handle(T command)
    {
        this._validator.Validate(command);
        this._decoratee.Handle(command);
    }
}

public class SaveNewOsiRequestController : ApiController
{
    private readonly ICommandHandler<OsiRequest> _osiRequestSaveHandler;

    public SaveNewOsiRequestController(ICommandHandler<OsiRequest> osiRequestSaveHandler)
    {
        _osiRequestSaveHandler = osiRequestSaveHandler;
    }
}

这里的问题是,您正在执行泛型绑定,但您正在特定情况下使用它。只有在希望泛型绑定应用于该绑定的所有情况(或者至少应用于可以有条件绑定到的所有情况)时,才需要使用泛型绑定

为此,您可以同样轻松地执行以下操作:

kernel.Bind<IValidator<OsiRequest>>().To<OsiRequestValidator>();

kernel.Bind<ICommandHandler<OsiRequest>()
        .To<SaveOsiRequestCommandHandler>()
        .WhenInjectedInto<ValidationCommandHandlerDecorator<OsiRequest>>();

kernel.Bind<ICommandHandler<OsiRequest>()
        .To<ValidationCommandHandlerDecorator<OsiRequest>()
        .WhenInjectedInto<SaveNewOsiRequestController>();
kernel.Bind().To();

谢谢你,埃里克。这是一个救命稻草。只是个问题。我是否遵循正确的方法?从体系结构的角度来看,将特定的具体类注入通用接口是否正确?@MehrdadKamelzadeh-当您在特定情况下需要特定实例时,您没有太多选择。如果您能够找到一种只使用接口中的类型调用泛型实现的方法,那么您可以简化这个过程,但是您的实现似乎没有做到这一点。此外,您还可以重用最后一个绑定,因为这是通用的。。查看我的更新。这利用了Ninject在使用
.WhenInjectedInto()
@MehrdadKamelzadeh时将遍历基类这一事实,但其他两个必须保持特定,因为无法自动将泛型类型映射到特定类型。
        kernel.Bind(typeof (IValidator<>)).To(typeof (ANOTHER_Validator));

        kernel.Bind(typeof (ICommandHandler<>))
            .To(typeof (ANOTHER_CommandHandler))
            .WhenInjectedInto(typeof (ValidationCommandHandlerDecorator<>));

        kernel.Bind(typeof (ICommandHandler<>))
            .To(typeof (ValidationCommandHandlerDecorator<>))
            .WhenInjectedInto(typeof(ANOTHER_RequestController));
kernel.Bind<IValidator<OsiRequest>>().To<OsiRequestValidator>();

kernel.Bind<ICommandHandler<OsiRequest>()
        .To<SaveOsiRequestCommandHandler>()
        .WhenInjectedInto<ValidationCommandHandlerDecorator<OsiRequest>>();

kernel.Bind<ICommandHandler<OsiRequest>()
        .To<ValidationCommandHandlerDecorator<OsiRequest>()
        .WhenInjectedInto<SaveNewOsiRequestController>();
kernel.Bind<IValidator<DifferentRequest>>().To<DifferentValidator>();

kernel.Bind<ICommandHandler<DifferentRequest>()
        .To<DifferentRequestCommandHandler>()
        .WhenInjectedInto<ValidationCommandHandlerDecorator<DifferentRequest>>();

kernel.Bind<ICommandHandler<DifferentRequest>()
        .To<ValidationCommandHandlerDecorator<DifferentRequest>()
        .WhenInjectedInto<DifferentRequestController>();
kernel.Bind(typeof (ICommandHandler<>))
        .To(typeof (ValidationCommandHandlerDecorator<>))
        .WhenInjectedInto<ApiController>();