I'm a bit confused with DI and IoC. I have set up MVC and I use Ninject for properties injection and it works perfectly. My application is set to use Portable Areas from MvcContrib and each area is contained from providers, services, models and controllers.
Providers from one area can access other providers in same or sub assemblies. To resolve dependency in provider I use DependencyResolver.Cur... which is registered to use Ninject as well. I would like to know if this is a good approach since I don't want to pass all other providers from controllers to last layer, but I want to access them directly from provider. Should I create an instance of kernel in lowest assembly like Core so I can access it directly from anywhere?
Thnx in advance
UPDATE:
I would also want to know if it is possible to use property injection in normal class.
When you design all your services (reposities, application services, controllers, etc) around the constructor injection pattern, there is no need to call DependencyResolver.Current.GetService from within a class and there is no need to make an instance of the kernel available in the lowest assembly.
When all your services use constructor injection, your container will be able to construct an object graph of dependent services when a root type is requested: in your case a controller class. When you do this, no code needs to access the DependencyResolver or the Kernel directly, which ensures your code will be more testable, flexible, and maintainable. Any code that accesses the DependencyResolver or static Kernel instance is hard to test, hides its dependencies, and makes it difficult to verify the container's configuration in an automated fashion.
Instead of using constructor injection, you can achieve the same with property injection. However, since the convention is that properties are for optional dependencies, Ninject (and any other container) will skip a property it can't inject (implicit property injection), instead of throwing an exception, as would happen with a missing constructor argument dependency. This again makes it much harder to find configuration errors in your application. So, whenever possible, stick with constructor injection.
Related
I have read that dependency injection is good for testing, in that a class can be tested without its dependencies, but the question comes to my mind if Class A depends on Class B or C or any class, testing Class A independent of some class is yielding a test result of zero, not a failed or past test.
Class A was created to do something and if it is not fed anything whether using new key word or setting up the extra files in Spring, Class A won't do any work.
About the idea of making code modular, readable and maintainable: so business classes became cleaner, but all we did was shift confusion from dirty Java business classes to convoluted XML files and having to delete interfaces used to inject to our loosened objects.
In short, it seems we have to make edits and changes to a file somewhere,right?
Please feel free to put me in my place if my understanding is lacking, just a little irritated with learning Spring because I see the same amount of work just rearranged.
Dependency injection is good for unit testing because you can individually test each method without that method depending on anything else. That way each unit test can test exactly one method.
I would say that if the xml is what’s annoying you check out Spring boot. It’s based on a java configuration so no xml and it simplifies a lot of configuration for you based on your class path. When I first started spring I found the xml very daunting coming from a java background but the annotation based configuration and the auto configuring done by spring boot is extremely helpful for quickly getting applications working.
IMO biggest advantage of using the spring is dependency injection which makes your life easy. For example if you would like to create a new service with three dependencies, then you can create a class very easily using Spring. But without spring, you will end up writing different factory methods which will return you the instances you are looking for. This makes your code very verbose with static method calls. You may want to take a look at the code repositories before spring era.
Again if you would like to use Spring or not is your personal call based on project complexity. But it's other features/advantages cant be overlooked.
And XML files or Java configs are the ways of achieving spring configuration - where you would like to add your business logic is personal flavour. Only thing is you should be consistent all across your project.
I would suggest that you read Martin Fowler's great article on Inversion of Control and Dependency Injection to gain a better understanding of why frameworks like Spring can be really useful to solve a well known set of common dependency injection problems when writing software.
As others have mentioned, there is no obligation to use Spring; and whatever you can do with Spring, you can probably do it by other means like abstract factories, factory methods, or service locators.
If your project is small enough, then you probably wouldn't mind solving the dependency injection issues on your own using some design patterns like those mentioned above. However, depending on the size of your project, many would prefer to use a framework or a library that already packs a bunch of solutions to these recurrent head scratchers.
In regards to the advantages of dependency injection frameworks when doing unit testing is the idea that you don't need to test the dependencies of your class, but only your class.
For example, most likely your application has a layered design. It is very common to have a data access class or a repository that you use to retrieve data from a datasource. Logically, you also have a class where you use that DAO.
Evidently, you already wrote unit testing for your DAO, and therefore, when you're testing your business class (where the DAO is being used) you don't care about testing your DAO again.
Fortunately, since Spring requires some form of dependency injection for your DAO, this means your class must provide a constructor or a setter method through which we can inject that DAO into our business class, right?
Well, then during unit testing of your business class, you can conveniently use those injection points to inject your own fake DAO (i.e. a mock object). That way, you can focus on the testing of your business class and forget about retesting the DAO again.
Now compare this idea with other solutions you may have done on your own:
You inject the dependency directly by instantiating the DAO within your business class.
You use a static factory method within your code to gain access to the DAO.
You use a static method from a service locator within your code to gain access to the DAO.
None of these solutions would make your code easy to test because there is no simple manner to get in the way of choosing exactly what dependency I want injected into my business class while testing it (e.g. how do you change the static factory method to use a fake DAO for testing purposes?).
So, in Spring, using XML configuration or annotations, you can easily have different dependencies being injected into your service object based on a number of conditions. For example, you may have some configurations for testing that evidently would be different than those used in production. And if you have a staging environment, you may even have different XML configurations of dependencies for your application depending on whether it is running in production or integration environments.
This pluggability of dependencies is the key winning factor here in my opinion.
So, as I was saying, my suggestion to you is that you first expand your understanding of what problems Spring core (and in general all dependency injection frameworks) is trying to solve and why it matters, and that will give you a broader perspective and understanding of these problems in a way that you could to determine when it is a good idea to use Spring and when it is not.
I have just started learning Java Spring and the concept of Dependency Injection (DI) and Inversion of Control (IoC).
I learned that all objects whether it is singleton, prototype or request and sessions, are all retrieved from the container.
The container manages the dependencies between classes and the lifecycle/scope of the object.
The fundamental idea behind this is there are no "new" operators for application using Spring Framework as the backbone of the system. (Please correct me if I am wrong).
I wanted to modernize legacy applications coded without the Spring framework and manages the 3rd party libraries classes and injects them using Spring.
How should I approach this?
I learned that all objects whether it is singleton, prototype or request and sessions, are all retrieved from the container.
That is not quite right. Not all objects, but those you have the cotainer told to resolve, are retrieved from the container. In general you use the #Component annotation to mark which of your objects should the container know of. Besides #Component there are other annotations which do in principle the same, but allow a more finegrained semantics, e.g. #Repository annotation, which is at its base #Component and put #Target, #Retention, #Documented on top.
The container manages the dependencies between classes and the lifecycle/scope of the object.
Yes. The container does the wiring up for you, i.e. resolving dependencies annotated with #Ressource, #Autowired or #Inject depending on which annotation you prefer.
During the lifecycle there are possible events, which allow usage of lifecycle callbacks.
Also: You could determine the bean scope.
The fundamental idea behind this is there are no "new" operators for application using Spring Framework as the backbone of the system. (Please correct me if I am wrong).
The fundamental principle is, that you delegate the creation of objects of a certain kind to the container. Separation of creation and consumption of objects allows greater flexibility and in consequence better testability of your application.
Besides the "components" of your application, there are e.g. the typical containers like ArrayList or HashMap, upon which you use the new-operator as before.
I wanted to modernize legacy applications coded without the Spring framework and manages the 3rd party libraries classes and injects them using Spring.
How should I approach this?
From what was said above, it should be "simple":
1) Go through each class file and look for its dependencies
2) Refactor those out and put #Component on top of the class
Special case: 3rd party objects, where you do not have access to the source. Then you have to wrap its construction yourself into a factory e.g. with #Bean.
3) Add the missing dependencies via #Autowired (the spring specific annotation for marking dependencies)
4) Refactor components of the service layer with #Service annotationinstead of #Component.
5) Refactor the data access layer, instead of using #Component, you can use #Repository.
This should give you a base to work with.
In MVC, a ModelValidatorProvider is instantiated and called to validate a model on each request. This means that in a DI environment, it can take dependencies on objects scoped within a single request, such as a Unit of Work or Database context. In Web API, this appears to have been significantly changed. Instead of being instantiated per-request, the ModelValidatorProvider appears to be long-lived and instantiated within the application startup. The WebAPI then caches the results from the ModelValidatorProvider per-type, meaning that the ModelValidator cannot take any dependencies from DI.
I am trying to implement my ModelValidator to use a factory using a Service Locator (please, no automatic 'anti-pattern' comments!). This would allow me to construct an internal validator object within each request, which would be able to take dependencies from the container. However, I cannot get hold of a Dependency Resolver or container scoped to the current request from within this ModelValidator which is essentially scoped as a Singleton. I've tried to use GlobalConfiguration.Configuration.DependencyResolver, but this only returns globally-scoped services (from the root scope, also mentioned here)
I'm working in Autofac, so an autofac-specific solution would be suitable (e.g. MVC has AutofacDependencyResolver.Current, which internally uses DependencyResolver.GetService). There is no equivalent available in the WebAPI integration, presumably because of the reason mentioned above where the global DependencyResolver only returns globally-scoped services.
The reason I'm trying to do this (as well as for my own use) is to implement the Web API integration for FluentValidation, which currently does not exist. There have been two attempts so far, but neither of these handle the Dependency Injection issue and instead result in a single static ModelValidator.
Things I've tried so far:
Using GlobalConfiguration.Configuration.DependencyResolver (returns objects from the root scope)
Taking a dependency on Func<IComponentContext> (always returns the root context)
In an answer which has since been removed, it was suggested to remove IModelValidatorProvider service from the Web API config. This had to be done using reflection since the interface and the implementing classes are all defined as internal, but it did make the validators work better (because the ModelValidator was constructed per request). However, there is a significant performance hit to doing it this way due to the use of reflection to check for validators on the model and every property it has, so I don't want to take this option.
Filip W's answer suggests using HttpRequestMessage to get the Dependency Scope, but I've not found anything such as HttpRequestMessage.Current which would provide access to this object from within a long-lived object - if that could be achieved I believe everything would fall into place.
To get current dependency scope, you have to use (surprise, surprise :) GetDependencyScope() of the current HttpRequestMessage (more about which you can read up on MSDN) instead of GlobalConfiguration.
I blogged about Web API per-request dependency scope a while ago - that should be helpful.
I have seen this line of code in several tutorials for using Unity in asp.net mvc3. I was under the impression that Service Locator is an anti-pattern and not best practice. Is this Service Locator something other than the anti-pattern defined, or is this line of code / this implementation considered bad practice.
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(Container));
Old question, but for the benefit of others:
While I absolutely agree with the mantra "Service Location is an anti-pattern", there are definitely exceptions to that rule.
When you use Dependency Injection (like Unity) then, yes, certainly don't use ServiceLocator and only use constructor injection for all your service classes. (Also don't use "new" for anything other than value objects like DTOs.)
However, there are cases where you simply can't use constructor injection and then the only way to get access to a service is to use a workaround to access your Unity container directly, and in such cases, ServiceLocator is a good standard way to accomplish that. This is the case when the class isn't instantiated by you (or more specifically, it isn't instantiated by Unity) but by the .NET framework for example.
A few simple examples of where ServiceLocator might be useful, is to get access to services registered in your Unity container from:
an implementation of a WCF IEndpointBehavior or IClientMessageInspector
an implementation of a WPF IValueConverter
or you may not necessarily even want to get access to "services" from the class, but you simply want to write code that is unit-testable, but for some reason the class can't be instatiated at all (or not easily) because it would normally be constructed by the .NET Framework, so you extract your custom code into a class that is testable, and resolve it in the non-testable class using the ServiceLocator.
Note that this line is not ideal:
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(Container));
The ServiceLocator.Current property is going to execute the delegate provided every time you access Current, i.e. a new UnityServiceLocator is going to get created every time. Instead, you probably want to do this:
IServiceLocator locator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => locator);
If you create a framework which is designed to be container agnostic the service locator (although it should be a No-Go in an application) is an additional layer of indirection that allows you to swap out Unity for something different. In addition the use of the service locator does not enforce the use of DI for applications that use that framework.
It is the same anti-patten that people talk about. All that line is doing is setting the service locator provider to be an instance of UnityServiceLocator, i.e. to use the Unity implementation of the ISerivceLocator. Optionally if you would like you can have your own implementation is IServiceLocator and use that instead of UnityServiceLocator.
Using Service Locator is considered a bad practice for various reasons as listed here
I updated Ninject.MVC3 package from 2.2.1.0 to 2.2.2.0. Before I had access to the Kernel object through BootStrapper.Kernel property but in the new version Kernel property is marked as obsolete. I get a warning saying
'Public ReadOnly Property Kernel As Ninject.IKernel' is obsolete: 'Do not use Ninject as Service Locator'.
Is there a different way to access the kernel in the new version?
If you have a class that (for some reason) needs to retrieve objects from the Ninject kernel, you can include the kernel as one of the injected properties/constructor parameters on the class. This pattern is better in the sense that you're explicitly declaring that a particular class is using the kernel, rather than always having it available as the service locator pattern does.
This assumes that Ninject automatically adds an instance binding of the kernel to itself. I know that it used to do this, but if it doesn't you can add the binding manually.
The reason why this has been marked Obsolete and will be changed to internal in future is that people tend to use Ninject as a service locator if it is possible to do so. But Service Locator is an antipattern that should not be used. And as we don't want to provide functionality that helps building badly designed software it will be removed in future.
If this needs a lot of changes in your code this is sign that your code is suffering from this malaise Dependency Injection wise and you really should change it to a better design.
Limit your access to the kernel to a mimimum. There is almost no situation in MVC where you need something other than plain constructor injection. Therefore my first advice is to refactor to constructor injection where possible.
For these very rare cases where you need access to the kernel to create other objects you should inject a factory to the class that needs the new instance and inject the kernel into this factory (if the Constructor has a Kernel parameter, it'll receive the instance doing the injecting).
If you really want to stay with service locator even if almost everyone will tell you not to, you will have to keep a static reference yourself.
In ASP.NET MVC 3, I think DepedencyResolver is a clean way to get a service locator.
You could use the Common Service Locator as a service location hook into Ninject. The Common Service Locator only allows you to retrieve objects though, not inject objects that you already have. Of course you could hack around this restriction, but you could just as easily create a static class that exposes the Ninject kernel and reference that rather than the BootStrapper.