代码之家  ›  专栏  ›  技术社区  ›  Mehrdad Kamelzadeh

带有Ninject的装饰图案

  •  2
  • Mehrdad Kamelzadeh  · 技术社区  · 10 年前

    我正在申请 this 制作验证包装器的方法。我已经创建了以下接口,我正在使用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(typeof (IValidator<>)).To(typeof (OsiRequestValidator));
    
            kernel.Bind(typeof (ICommandHandler<>))
                .To(typeof (SaveOsiRequestCommandHandler))
                .WhenInjectedInto(typeof (ValidationCommandHandlerDecorator<>));
    
            kernel.Bind(typeof (ICommandHandler<>))
                .To(typeof (ValidationCommandHandlerDecorator<>))
                .WhenInjectedInto(typeof(SaveNewOsiRequestController));
    

    代码运行良好,没有任何问题。然而,问题是我如何使用Ninject为另一个控制器进行相同的注射?为了简单起见,我想注射另一种 Validator 和另一个 CommandHandler 到另一个 Controller 这样地:

            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));
    
    1 回复  |  直到 10 年前
        1
  •  1
  •   Erik Funkenbusch    10 年前

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

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

    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>();