How to pass parameters down the dependency chain using Ninject

半城伤御伤魂 提交于 2019-12-06 09:50:01

Yannick's answer is a good, however, here's an alternative: create an IAccountService that has the logic to find and return the AccountId. Then inject that service into your IPhotoService.

There's the concept of a ConstructorArgument in Ninject, which allows you to pass through variables only known at runtime. The typical example of this would be:

var photoService = kernel.Get<IPhotoService>(new ConstructorArgument("accountId", <your value here>));

Now the caveat with this is that this only goes one level deep. There is however a contructor that accepts a bool flag called shouldInherit, which allows your values to propagate to the children when resolving the concrete types:

var photoService  = kernel.Get<IPhotoService>(new ConstructorArgument("accountId", <your value here>, shouldInherit:true));

While I have found that it is overkill in some situations, using a factory will help provide constructor-like features while preserving the style of writing for injection. This is provided by the Ninject.Extensions.Factory extension.

At a basic level, you create a factory interface which has a matching subset of the constructor arguments. It can both resolve bound components, and require input itself. Here is a slightly modified example from the wiki;

public class Foo
{
    readonly IBarFactory barFactory;

    public Foo(IBarFactory barFactory)
    {
        this.barFactory = barFactory;
    }

    public void Do()
    {
        var bar = this.barFactory.CreateBar("doodad");
        //Do Foo things
        bar.Stuff();
    }
}

public interface IBarFactory
{
    IBar CreateBar(string someParameter);
}
public interface IBar
{
    void Stuff();
}

public class Bar : IBar
{
    public Bar(IDependancy aDependancy, string someParameter)
    {
        //Initialise Object
    }
    public void Stuff()
    {
        //Do Stuff
    }
}

Then by binding a factory with;

_kernel.Bind<IBarFactory>().ToFactory();

the extension will do some magic behind the scenes.

In this example, assuming IDependancy is bound correctly, calling the CreateBar method of the factory will resolve any dependancies in parallel with inserting your parameter.

One word of caution, however, is that the parameter names need to be the same.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!