简体   繁体   中英

Instantiating a new object with Constructor parameters using Ninject

I'm trying to refactor some code to use IoC with the Ninject framework. So far I have managed to successfully inject in classes in scenarios where I do not have any constructor parameters to pass. However I am having difficulties when it comes to passing in parameters. This is the third binding in the binding class below.

Binding Class

public class Bindings : NinjectModule
    {
        public override void Load()
        {
            Bind<ILogger>().To<Logger>();
            Bind<IPlayerDatadao>().To<PlayerDatadao>();
            Bind<IPlayerScores>().To<PlayerScores>();
        }
    }

The logger class has a parameterless constructor and works fine when transferred to Ninject.

Success

    // IoC creation
    var kernel = new StandardKernel();
    kernel.Load(Assembly.GetExecutingAssembly());

    //Log User details
    var logger = kernel.Get<ILogger>();
    logger.LogVisitorDetails();

However, my attempt below threw an exception

Failure

        string priceString = Foo();
        string pointsString = Bar();

        return kernel.Get<IPlayerScores>(new[] { new ConstructorArgument("pointsString", pointsString), new ConstructorArgument("points", priceString) });

This is the class with its constructor.

Class to Inject

public class PlayerScores : IPlayerScores
{
    [Inject]
    public string points { get; set; }
    [Inject]
    public string price { get; set; }
    public PlayerScores(string Points, string Price)
    {
        points = Points;
        price = Price;
    }
}

I'm really not sure how I should be handling the parameters either in the binding class or at the point of injection

I'm really not sure how I should be handling the parameters either in the binding class or at the point of injection

At binding. You should remove any Ninject dependencies from your model:

public class PlayerScores : IPlayerScores
{
    public PlayerScores(string points, string price)
    {
        this.Points = points;
        this.Price = price;
    }

    public string Points { get; set; }
    public string Price { get; set; }
}

and then configure the kernel:

Bind<IPlayerScores>()
    .To<PlayerScores>()
    .WithConstructorArgument("points", "some points")
    .WithConstructorArgument("price", "some price");

or using ToMethod which is a bit more refactor friendly as it avoids the magic strings with the parameter names:

Bind<IPlayerScores>()
    .ToMethod(ctx => new PlayerScores("some points", "some price"));

This being said, if the 2 parameters are so volatile that they need to have a different value on each call, then you probably should not be passing them as constructor parameters but rather as parameters to some instance method that you would invoke on the class at runtime.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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