Ioc Ninject:向构造函数添加接口以外的参数

时间:2018-04-04 22:29:20

标签: c# .net inversion-of-control ninject ioc-container

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

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中调用此类,其构造函数将具有IMapper和IManager参数(显然会自动解析)。

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

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

然后在webapi控制器中:

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对象。

可以解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

有两种方法可以达到这个目的:

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