iocNinject:给构造函数添加接口以外的参数

Ioc Ninject: add parameters other than interfaces to constructors

在我的实际代码中我有类似的情况:

public Interface IPerformer
{
    void Perform_A(int id, string name);
    void Perform_B(int id, string name);
    void Perform_C(int id, string name);
}


public MyClass : IPerformer
{
    private readonly IMapper _mapper;
    private readonly IManager _manager;

    public MyClass(IMapper mapper, IManager manager)
    {
        _mapper = mapper;
        _manager = manager;
    }

    public void Perform_A(int id, string name)
    { 
        _manager.DoSomething_A(id, name);
    }

    public void Perform_B(int id, string name)
    {
        _manager.DoSomething_B(id, name);
    }

    public void Perform_C(int id, string name)
    {
        _manager.DoSomething_C(id, name);
    }
}

我的 IManager 实现使用需要 int 和字符串的方法。 我被迫创建一个接口,在其所有方法签名中公开这两个参数,以便注入的 IManager 对象可以使用。

然后将在 Web api 中调用此 class,其构造函数将具有一个 IMapper 和一个 IManager 参数(显然是自动解析的)。

我想做的是删除所有出现的 id 和 name 参数并将它们传递给构造函数,但是 Ninject 不允许我这样做:

public MyClass(IMapper mapper, IManager manager, int id, string name) { ... }

然后在网络api控制器中:

public class PerformController : ApiController
{
    public PerformController(IMapper mapper, IManager manager, int id, string name)
    {
        ...
    }   
}

当然,我希望我的 IPerformer 界面听起来像:

public Interface IPerformer
{
    void Perform_A();
    void Perform_B();
    void Perform_C();
}

而我的参数 Id 和名称的知识只是 IManager 对象。

是否可以变通?

有两种方法可以实现:

使用ToConstructor方法:

kernel.Bind<IPerformer>()
.ToConstructor(c => new MyClass(c.Inject<IMapper>(), c.Inject<IManager>(), 1, "test"));

或使用 WithConstructorArgument 方法的重载之一:

kernel.Bind<IPerformer>().To<MyClass>()
.WithConstructorArgument("id", 1)
.WithConstructorArgument("name", "test");

kernel.Bind<IPerformer>().To<MyClass>()
.WithConstructorArgument(typeof(int), 1)
.WithConstructorArgument(typeof(string), "test");

编辑

为了动态参数的传递,创建工厂并注入这个工厂。

public interface IPerformerFactory
{
     IPerformer Create(int id, string name)
}

kernel.Bind<IPerformer>().To<MyClass>();
kernel.Bind<IPerformerFactory>().ToFactory();