1
votes

I'm fairly new to Dependency Injection, and I'm looking for some advice on best practices. Sorry if this has been asked before, but I haven't been able to find a good solution yet.

Assume I have a MVC4 web app and a separate business layer. The MVC app is already set up using the Ninject NuGet package, so I have NinjectWebCommon, and it works fine.

My question is: How can I use Ninject when I need dependencies set up in other layers?

Assume I have this repository:

public class WidgetRepository : IWidgetRepository
{
    // using an entity framework db context.
    WidgetDbContext context = new WidgetDbContext();

    public IQueryable<Widget> Widgets
    {
        get
        {
            return context.Widgets;
        }
    }
}

Each widget returned by the repository needs to perform calculations using a calculator object that I need to inject:

public class Widget
{
    // how can I get Ninject to inject a calculator object 
    // when Widgets are loaded form the database?

    public ICalculator calculator;

    public int MyValue { get; set; }

    public int CalculateSomething
    {
        get
        {
            return calculator.Calculate(MyValue);
        }
    }
}

What is the best practice to inject an ICalculator into each Widget instance, when Ninject is set up in the MVC web app, but the Widget objects are created in the business layer??

2

2 Answers

1
votes

Prevent doing constructor injection or property injection in entities. You should either:

  1. Let the service layer call the calculation on the Widget, like this:

    var widget = this.repository.GetById(wigditId);
    var value = this.calculator.Calculate(widget.MyValue);
    
  2. Or use constructor injection into your entities:

    var widget = this.repository.GetById(wigditId);
    var value = widget.CalculateSomething(this.calculator);
    

A lot has been written about this. Take a look at these articles for instance:

0
votes

If Widget and ICalculator are in the same project, just use constructor injection:

public class Widget
{
    public Widget(ICalculator calculator)
    {
      _calculator = calculator;
    }

    private ICalculator _calculator;

    public int MyValue { get; set; }

    public int CalculateSomething
    {
        get
        {
            return _calculator.Calculate(MyValue);
        }
    }
}

In NinjectWebCommon, you'll need to register your ICalculator implementation, something like this:

private static void RegisterServices(IKernel kernel)
{
  kernel.Bind<ICalculator>()
              .To<Calculator>();
}