I am currently building an application using .net 4.6, MVC 5 and unity 4. I have a controller which looks like the below:
public class ExamController: Controller {
private IEducationService _eduService;
public ExamController(IEducationService eduService) {
_eduService = eduService;
}
}
And Unity injects the service with:
container.RegisterType<IEducationService, EducationService>();
Recently we are adding other Action methods to this controller which will need other services. for example, if I now have an ExperienceService, I could add to that to Unity and change the controller's constructor to take that as well:
public ExamController(IEducationService eduService, IExperienceService _expService )
problem is I don't want both available all the time, they should be available based on which Action method is called. I can make separate constructors for each, but I'm not sure then how to get Unity to make one instead of both, based on which Action method is getting called.
Using multiple constructors on injectables is anti-pattern.
Furthermore, constructors should be simple, so the worry of creating extra objects which aren't used is misguided (unless of course you are violating this rule). Creating objects is very cheap when there is nothing in the constructor but assignment statements, so injecting 1 or even 100 more is probably not going to have a huge impact on performance.
You should also limit the number of services a controller has. If you have more than 3 or 4, you are probably violating the Single Responsibility Principle and should consider refactoring to facade services that each have a single responsibility. The result is that you will have an object graph that looks more like a pyramid with a few dependencies at the top and those dependencies will each have a few more until you get to the bottom where there are none.
Related: Rebuttal: Constructor over-injection anti-pattern
Rather than have the dependencies injected and available to the entire class, you could simply resolve the dependency in the action method where you need it using the ServiceLocator:
var expService = ServiceLocator.Current.GetInstance(typeof(IExperienceService));
You would first need to register Unity's ServiceLocator:
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(container));
Example
Just a quick note: The Service Locator pattern is considered an anti-pattern.
Related
So I am working on API and using Ninject for DI & IoC. I know how the basic code works using Ninject but in the constructor of one of the classes an object of Logger is being sent. Rather than send it in constructor design item I would like to pass it in NinjectWebCommon.cs file.
public GAMonthlyAPIController() : this(new GAMonthlySQLReader(new NullLogger()))
This is the constructor.
kernel.Bind<IGAMonthlyReader>().To<GAMonthlySQLReader>();
This is the entry in NinjectWebCommon.cs I would like to bind it in NinjectWebCommon.cs rather than default value. How would I pass that? I don't even know what to search for, so I could find answers.
The most practical way to apply the dependency injection pattern is to use constructor injection. This means that the classes GaMonthlyAPIController depend on should be passed in through the constructor, rather than hard-coded inside of the controller.
public class GAMonthlyAPIController
{
private readonly IGAMonthlySQLReader gaMonthlySqlReader;
public GAMonthlyAPIController(IGAMonthlySQLReader gaMonthlySqlReader)
{
this.gaMonthlySqlReader = gaMontlySqlReader
?? throw new ArgumentNullException(nameof(gaMontlySqlReader));
}
// implementation of controller...
}
This should be the only constructor for your controller class. The controller itself doesn't know anything about GAMontlySqlReader or any of its dependencies.
The same goes for GAMonthlySQLReader - it will allow any ILogger implementation to be injected through the constructor.
The idea is that it puts the composition root of the application in charge of how the dependencies are composed together, meaning you can easily switch them around later without making any changes to the components that you are composing. So, Ninject would be used inside of your composition root to map types to their abstraction, and then will build object graphs of all of those dependencies composed together.
kernel.Bind<ILogger>().To<MyLoggerClass>();
kernel.Bind<IGAMonthlyReader>().To<GAMonthlySQLReader>();
For each of the application services, you would allow Ninject to instantiate them (so it can supply the dependencies) rather than using the new keyword inside of your application (new can be used for DTOs and Models, though).
I think you need to add Ninject.Web.WebApi using nuget to your Web Api project. Then use Ninject for creating ApiControllers:
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
And add the Bind() for GAMonthlyAPIController. No need to create a default constructor for your controller.
Have a look to this post:
http://nodogmablog.bryanhogan.net/2016/04/web-api-2-and-ninject-how-to-make-them-work-together/
Having something like a string parameter in a constructor makes dependency injection very messy. Think:
public class CurrencyActor
{
public CurrencyActor(string currency, IRepository repository)
{
...
There have been other questions (such as this one) to address this particular problem with dependency injection. Often this is solved by rethinking the design and refactoring.
However, what if it actually makes sense to have multiple versions of an object that are each responsible for different data (e.g. a CurrencyActor for each currency)? This is pretty normal when using an actor model such as Akka .NET, but makes sense even outside that domain.
What is the best way to create these multiple instances using dependency injection while passing in the initial state they need?
Having a dependency in a constructor is not messy, it's very very common. There is nothing wrong with this.
You could create a default props static method on the CurrencyActor that takes in your dependencies:
public static Props CreateProps(string currency, Irepository repo)
{
return Props.Create(() => new CurrrncyActor(currency, repo));
}
Then create as many as you like:
var usCurrency = system.ActorOf(CurrencyActor.CreateProps("US", someRepo), "US");
var swedishCurrency = system.ActorOf(CurrencyActor.CreateProps("SEK", someRepo), "SEK");
[Update]
Regarding the use of DI containers with Akka, this was listed as no. 2 out of the top 7 mistakes people make when using akka.net
https://petabridge.com/blog/top-7-akkadotnet-stumbling-blocks/
Thus it’s considered to be a good practice for actors to manage their own dependencies, rather than delegate that work to a DI framework.
So basically don't do it. And if you must, according to that article, Autofac is the best choice
[Update 2]
If you want to dynamically create new instances of the same Actor but change some initial state, then you could have a Supervisor that is responsible for creating them:
public class MatchesSupervisor : ReceiveActor
{
List<IActorRef> _matches = new List<IActorRef>();
public void MatchesSupervisor()
{
Receive<SomeCommandToStartANewMatch>(msg =>
{
// store the currently active matches somewhere, maybe on a FullTime message they would get removed?
_matches.Add(Context.ActorOf(MatchActor.Create(msg.SomeMatchId)));
}
}
}
In the above example, there is no DI container being used, and if each MatchActor needed something else, like an IRepository, then this would be passed into the MatchesSupervisor when it is created, and subsequently passed to each MatchActor when they are created.
It also kinda depends where the state is coming from, and what the mechanism is for starting a new Match - i've just presumed some other Actor is sending a message.
(I'm typing on an ipad so the above code might not actually compile but hopefully you get the idea, i also left out an implementation of MatchActor, but it would just be an Actor that gets some values passed into its constructor)
Hope this helps!
Working on an MVVM application. Each ViewModel class has a constructor which accepts a Repository class so that it can be mocked out for unit testing.
The application is designed to be operated across several windows at once. So it contains a number "View" or "Open" style methods which create new ViewModels and place them into new windows. Because these are triggered via the UI, they are often inside existing ViewModels. For instance:
public void ViewQuote(Quote quote)
{
if (quote.CreatedOn == null)
{
quote.CreatedOn = DateTime.Now;
}
NavigationHelper.NewWindow(this, new QuoteViewModel(quote, new Repository()));
}
Now, that flow control statement looks worth testing to ensure that quotes passed with a null CreatedOn date get assigned one. However, my test for this fails because although the parent ViewModel has a mocked Repository, the NewWindow method spins up a new ViewModel with a real-life Repository inside it. This then throws an error when it's used inside the constructor of that class.
There are two obvious options.
One is to pull out the date assignment into a stand-alone function to test. That'll work, but it seems too simplistic for its own function. Plus if I do it all over the application it risks creating too much fragmentation for easy readability.
The other is to somehow change the constructor code for ViewModels to not use the Repository directly. That might be an option here, but it's unlikely to be workable for every possible scenario.
Or is there a third way to design this better so I can pass a mocked Repository into the constructor of my new ViewModel?
Newing up services (or service-like objects such as repositories) is a design smell. And the problems that you're experiencing are the consequence.
In other words, you are lacking a clear and well-defined Composition Root.
Solution: Use proper dependency injection
The only clean solution to this is to inject services through the constructor. Repositories usually have a shorter lifecycle than the application itself, so in this case you would inject a factory that is able to create the repository.
Note that clear dependency trees are good design, but using a DI framework such as Autofac is only one technical solution to implement such a design. You can completely solve your problems and create a clean composition root without using a DI framework.
So although this is probably a lot of work, you should redesign your application to have a clear composition root. Otherwise, you will run into small issues over and over again, especially in the testing area.
You could work around it by adding a public Repository NewRepository property, in your ViewQuote method change it to look like this:
public void ViewQuote(Quote quote)
{
if (quote.CreatedOn == null)
{
quote.CreatedOn = DateTime.Now;
}
if(NewRepository == null) NewRepository = new Respository();
NavigationHelper.NewWindow(this, new QuoteViewModel(quote, NewRepository));
}
Then in your mock, just ensure that the public NewRepository property is assigned to before the test is run on that bit of code.
Not very elegant, but it would require the least amount of changing in my opinion.
I am working with .net c# Mvc, using ninject repository pattern. My problem is that when developing I am using reusing in the functions, and everytime I want more info from db and need access to another table, I need to pass the repositories from all the places that are calling this function. Am I doing it wrong? ot this is the way, which is alot longer to develop then just opening a connection and disposing at the end of the function.
If your class needs to have loads of repositories passed in this can sometimes be a sign that your class is doing too many things and probably breaking the Single Responsibility Principle.
Perhaps if you broke this class into smaller more specialized classes the problem would not be so bad.
On the other hand, sometimes passing in loads of repositories is unavoidable. You might consider making a factory class that creates the class suffering from 'constructor jam' for you - this should save some typing as the hefty constructor initialization is just in one place (in the factory class).
edit: A really simple 'factory' class might be as follows:
public class FactoryClass
{
public ClassWithLotsOfRepositories GetClassWithLotsOfRepositories()
{
return new ClassWithLotsOfRepositories(new repository1(),
new repository2(), new repository3() );
}
}
So you can now create an instance of ClassWithLotsOfRepositories without having to specify the repositories in the constructor each time.
ClassWithLotsOfRepositories myClassThatUsesLotsOfRepositories = new FactoryClass().GetClassWithLotsOfRepositories();
My example has concrete classes passed in through the constructor. You are using Ninject so presumably have interfaces that need resolving - I'm just keeping this example simple to illustrate the concept.
use a unit of work the new up all of the repositories. That way you can pass in the uow into your controllers and have access to all repos when needed.
Is it considered a bad practice to use optional parameters when using dependency injection frameworks with Constructor injection?
Example:
public class ProductsController
{
public ProductsController(IProductService productService = null, IBackOrderService = null)
{
}
}
I have specified both parameters as optional, but my DI framework will always inject both dependencies. If I add a new action to my controller which requires a new dependency, would it be bad to make the new dependency optional? I could potentially be breaking dozens of unit tests even though the existing tests wouldn't require the new dependency.
Edit
People seem to be confused by my question. I am never construcing a ProductsController manually in my web application. This is handled by a controller factory (which automatically injects dependencies).
What I don't like is having a unit test like this:
[Test]
public void Test1()
{
var controller = new ProductsController(new MockProductService(), new MockBackOrderService());
}
Now I decide to add a new action method to my controller. This new action needs a new dependency but none of the existing actions do. Now I have to go back and modify 100 different unit tests because I added a new parameter. I can avoid that by making the parameters optional, but I wanted to know if it was a bad idea. My gut feeling says no because the only thing it affects are the unit tests.
I completely agree with the accepted answer for all the cases on that defining a Dependency means that implementation will not work with out it.
But what if you have something that does not necessarily need a dependency but you want to be able to configure something if that dependency has been loaded. OK...? that sounds a bit weird but its a valid Meta Programming use case - and you think maybe factory pattern could help.. but even the factory may need some, none or all dependencies so Factory does not solve this problem.
Real world problem of feature flags. If a feature is turned off you
don't need that dependency.. or maybe cant even create it because
there is no concrete implementation. So its turned off. It compiles,
everything works OK. But then somebody switches the feature on and all
of a sudden we need that dependency.
I found a way to do this -- and the best part is I only realised how to do this by learning about another not so well known technique with Dependency Injection (I am using Microsoft.Extensions.DependencyInjection)
Injecting several concrete implementations for a single Interface
services.AddTransient<IWarehouseRepo, ActionRepository>();
services.AddTransient<IWarehouseRepo, EventRepository>();
services.AddTransient<IWarehouseRepo, AuditRepository>();
services.AddTransient<IWarehouseRepo, ProRepository>();
services.AddTransient<IWarehouseRepo, SuperWarehouseRepository>();
services.AddTransient<IWarehouseRepo, InferiorWarehouseRepository>();
services.AddTransient<IWarehouseRepo, MonthlyStatisticsRepository>();
I only learnt recently that this is completely valid but for this to work your constructor needs to look like this..
public WarehouseHandler(IEnumerable<IWarehouseRepo> repos)
So that is super cool! I can select a repository I need based on whatever criteria. But how does this help with Optional Dependencies?
Because this type of constructor will give you 0 or more dependencies. So if you do not add any dependencies you can branch out in the constructor using a conditional statement
if (repos.Count() == 0)
return;
This is null reference safe, does not require default values, easy to debug, easy to read and easy to implement.
You can now also use this technique as the feature switch mechanism too!
I don't think it's a good idea. Constructor injection means that the dependencies are required. You should even add the guard lines that throws if one of the parameters is null.
I think the problem is with your unit tests. For instance I have only one place where the controller is created and supporting objects are mocked (controllerContext, HttpContext, Request, Response, etc.). Then if I add a new parameter in the constructor I have to change it only in one place in the unit tests.
Maybe you should consider to code a generic base class in your unit tests, or make a usage of "setup" routine for the tests.
Consider to use The Test Data Builder pattern.
In the simplest form it could be done as static test helper method
public ProductsController BuildControllerWIthMockDependencies ()
{
var controller = new ProductsController(new MockProductService(), new MockBackOrderService());
return controller;
}
You can use AutoFixture as a generic Test Data Builder.
Further techniques for using Test Data Builders can be found in Test Data Builders: an alternative to the Object Mother pattern