简体   繁体   English

在Ninject中重新绑定通用接口

[英]Rebind generic interface in Ninject

I have several projects referencing a package containing generic interface 我有几个项目引用了包含通用接口的程序包

public interface IHandler<T> where T : class
{
    void Handle(T data);
}

These projects contain IHandler<> implementations and Ninject modules with bindings from interface to implementations. 这些项目包含IHandler<>实现和Ninject模块,以及从接口到实现的绑定。

I want to create decorator for all IHandler<> implementations 我想为所有IHandler<>实现创建装饰器

public class HandlerDecorator<T> : IHandler<T> where T : class
{
    private readonly IHandler<T> decorated;

    public HandlerDecorator(IHandler<T> decorated)
    {
        this.decorated = decorated;
    }

    public void Handle(T data)
    {
        // some logic 
    }
}

and decorate all registered bindings of IHandler<> automatically. 并自动IHandler<>所有已注册绑定。 Eg if there exists binding of IHandler<string> and StringHandler then target should be changed to new HandlerDecorator<string>(stringHandlerInstance) . 例如,如果存在IHandler<string>StringHandler绑定, IHandler<string>将目标更改为new HandlerDecorator<string>(stringHandlerInstance)

Is it possible in Ninject? Ninject有可能吗? Or I should rewrite all Ninject modules code? 还是应该重写所有Ninject模块代码?

As you can not access any meaningful binding information once the bindings are created, there is no direct way to accomplish this. 创建绑定后,由于无法访问任何有意义的绑定信息,因此没有直接的方法来完成此操作。 You could, however, use Ninject.Extensions.Conventions to search for all IHandler<T> implementations and bind / re-bind them with the decorator. 但是,您可以使用Ninject.Extensions.Conventions搜索所有IHandler<T>实现,并将它们与装饰器绑定/重新绑定。 In Ninject, using a decorator requires a binding for the decorator and one for the decorated implementation. 在Ninject中,使用装饰器需要为装饰器绑定一个绑定,并为装饰的实现绑定一个绑定。 In case you always use the same decorator, it can be simplified by using a generic binding for the decorator. 如果您始终使用相同的装饰器,则可以通过对装饰器使用通用绑定来简化它。 This would be: 这将是:

kernel.Bind(typeof(IHandler<>)).To(typeof(HandlerDecorator));

(Or using Rebind instead of Bind - as needed). (或使用Rebind ,而不是Bind -如需要)。

And the binding created by using the conventions extension should equal to: 使用约定扩展名创建的绑定应等于:

kernel.Bind<IHandler<string>>()
      .To<StringHandler>()
      .WhenInjectedInto<HandlerDecorator<string>>();

This is achieved by doing something along the lines of: 这可以通过以下方式实现:

kernel.Bind( x => x
   .FromThisAssembly()
   .SelectAllClasses()
   .InheritedFrom(typeof(IHandler))
   .Excluding(typeof(HandlerDecorator<>))
   .BindDefaultInterface()
   .Configure(b => b.WhenInjectedInto(typeof(HandlerDecorator<>)));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM