Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to inject repositories into an ASP.NET controller

We have a project written in ASP.NET MVC and we use NInject to inject the repositories into the controllers. Currently we are using properties and the Inject-attribute to inject the repositories, which works well enough:

[Inject]
public IMyRepository MyRepos {get;set;}

An alternative way of injecting would be to do it "manually" using the NInjectServiceLocator:

var myRepos = NInjectServiceLocatorInstance.Resolve<IMyRepository>();

Now I was wondering about the following: the first method requires all repositories to be listed at the top (not necessarily at the top of course, but it's the most logical place) of a controller. Whenever a request is made, NInject instantiates each and every repository. This happens regardless of whether all of the repositories are actually needed inside a specific Action.

With the second method you can more precisely control which repositories are actually necessary and thus this might save some overhead when the controller is created. But you probably also have to include code to retrieve the same repository in multiple places.

So which one would be better? Is it better to just have a bunch of repository-properties or is it better to resolve the repositories which are actually necessary for a specific action when and where you need them? Is there a performance penalty involved for injecting "useless" repositories? Are there (even ;-) better solutions out there?

like image 575
Pieter Avatar asked Aug 14 '13 08:08

Pieter


People also ask

What is the right way to include a repository into a controller?

By taking advantage of dependency injection (DI), repositories can be injected into a controller's constructor. the following diagram shows the relationship between the repository and Entity Framework data context, in which MVC controllers interact with the repository rather than directly with Entity Framework.

How can we inject the service dependency into the controller?

ASP.NET Core injects objects of dependency classes through constructor or method by using built-in IoC container. The built-in container is represented by IServiceProvider implementation that supports constructor injection by default.

Can we inject the dependency to individual action method of the controller?

You can take advantage of the ServiceFilter attribute to inject dependencies in your controller or your controller's action methods.


2 Answers

I prefer constructor injection:

private readonly IMyRepository _repository;

public MyController(IMyRepository repository)
{
    _repository = repository;
}
  • All your dependencies are listed in one operation
  • Your controller does not need to know anything about NInject
  • You can unit-test your controller without NInjects involvment by stubbing interfaces straight to the constructor
  • Controller has a cleaner code

NInject or any other DI framework will do the work behind the scenes and leave you concentrating on the actual problem, not DI.

like image 117
juhan_h Avatar answered Oct 29 '22 17:10

juhan_h


Constructor Injection should be your default choice when using DI.

You should ask yourself if the controller is really dependent on that specific class to work at all.

Maybe Method injection could also be a solution for specific scenario's, if you have only specific methods that needs dependencies.

I've never used Property Injection but Mark Seeman describes it in his book (Dependency Injection in .NET):

PROPERTY INJECTION should only be used when the class you’re developing has a good LOCAL DEFAULT and you still want to enable callers to provide different implementations of the class’s DEPENDENCY.

PROPERTY INJECTION is best used when the DEPENDENCY is optional.

NOTE There’s some controversy around the issue of whether PROPERTY INJECTION indicates an optional DEPENDENCY. As a general API design principle, I consider properties to be optional because you can easily forget to assign them and the compiler doesn’t complain. If you accept this principle in the general case, you must also accept it in the special case of DI. 4

A local default is described as:

A default implementation of an ABSTRACTION that’s defined in the same assembly as the consumer.

Unless you're building an API I would suggest not to use Property Injection

Whenever a request is made, NInject instantiates each and every repository. This happens regardless of whether all of the repositories are actually needed inside a specific Action.

I don't think you should worry to much about the performance when using constructor injection

like image 41
Andrew Avatar answered Oct 29 '22 17:10

Andrew