I have a ViewModel class which I want to resolve via the unity ServiceLocator, but my viewModel requires a parameter to the constructor. The parameter's type is one of the entities in my application (a Customer object) rather than some service implementation. I know that coding against the Unitycontainer itself I can pass a paramater like this:
_container.Resolve<CustomerDetailViewModel>(new ParameterOverrides {{"customer", customer}});
but if I dont have direct access to the container I need to go via the ServiceLocator like this:
(CustomerDetailViewModel)ServiceLocator.Current.GetInstance<CustomerDetailViewModel>();
However using the second approach I have no way to pass in any parameters to the ServiceLocator. Is there any way this can be done? Is it "wrong" to get an instance of the Container from the ServiceLocator and then use that?
The problem is that you are trying to inject an entity (Customer in this case) into a class. Entities are short lived objects and they don't tend to be good candidates for being injected.
Instead of injecting a Customer, inject a ICustomerRepository service. You can register an ICustomerRepository implementation in the startup path of the application and this way you won't have to call the container directly, which makes the application design cleaner and the unit tests easier.
If you write a wrapper for the ServiceLocator you can hold the unity container within the wrapper and the expose an additional resolve method overload that takes the ParameterOverrides property. Then the method could use the unity container to do the resolution as per your first code snippet rather than the ServiceLocator code snippet.
Related
Is there a way to use .NET Core dependency injection to create a concrete type without that type being registered as a service?
For example, say I have a SummaryReportService class. It is not registered as a service. However, its constructor takes several parameters that are registered as a service.
Is there any way to create an instance of this class and have dependency injection provide all the services needed by the constructor?
Maybe you are not doing a good design. But, I found cases in wich I had to do something like that. You will need a reference to the IServiceProvider, and do something like:
var summaryReportService = ActivatorUtilities.CreateInstance(this.serviceProvider, typeof(SummaryReportService));
It will create a instance of SummaryReportService with the required dependencies (if configured).
I'm new to DI scenarios and I'm implementing a DI scenario using Unity and asp.net mvc.
I was trying to inject a DbContex instance into my UnitOfWork class. I registered the instance but I noticed that DbContexobject had been already injected without writing the code for resolving the DbContex.
How it could be possible? Does Unity resolving the instances by default?
I thought it was my responsibility to write this "resolving code" for the DI to work.
For instance, when I'm injecting dependencies into Controllers I must write a code like this in GetControllerInstance method:
return MvcUnityContainer.Container.Resolve(controllerType) as IController;
You need to only resolve the root object, e.g., the controller class. Unity would then look at the constructor of this class and will see that it has some dependencies (constructor parameters). It will then automatically try to resolve these dependencies. If these dependencies have dependencies themselves, it will resolve these first...
This process is called auto-wiring. Without auto-wiring, why would anyone use a DI container? (Not that I think that you should use one in the first place)
Unity by default "registers" all concrete types loaded in the process - so you can call .Resolve with concrete type and get result (assuming constructor of that type actually can get called by Unity).
For interfaces you need to register mapping to concrete type/instances so.
Is there a way to instantiate a class without a constructor if I don't have a handle to the container?
If I call container.RegisterType<IMyClass , MyClass>() I know I can use unity to instantiate an object in a constructor.
Someclass(IMyClass myClass)
var s = new Someclass();
I also know I can use
container.Resolve<IMyClass>() outside a constructor if I have a handle to the container, or use the DependencyFactory, which is also the same thing.
If I am writing code for a large project that doesn't save a handle to the container, and it is not appropriate to use a constructor, is there a way to instatiate class using unity?
you should not be referencing the container in your classes. You container should be orchestrating the construction of the object graph and your class should not be calling it, it should be calling your classes.
Ideally your container should not be used outside of the Composition Root. See this answer
The point I (and Belogix) was trying to make (not very well it seems) is that you should never need to create dependent objects directly if you are using DI correctly. Passing the container around is a code smell and you should avoid this if at all possible (which it almost always is). If you require an instance of a class in a place where you 'don't have a handle to the container' you should be asking for an instance of that class through your object's constructor. Doing this allows the IoC container to know that your object has a dependency and it can then supply an instance of that dependency when the container creates an instance of the class. If you follow this principal with every dependency all the way up your chain then your composition root becomes the only place that you need to create your objects, and you can do it manually (poor man's DI), or you can configure a container to do it for you.
I suggest you read this post it really helped me understand the concept of a composition root and why not leaking your container throughout the application is a Good Idea.
If you want to create an object without calling the constructor and without a handle to the container then you can use GetUnitializedObject as outlied in this answer but you have to ask yourself, if you are swimming that hard upstream to create your objects, surely there must be a better way?
I was only trying to point out what I consider the currently accepted best practices around using a container.
It could seem a stupid question because in my code everything is working, but I've registered a singleton this way with my Unity container _ambientContainer:
_ambientContainer.RegisterType<Application.StateContext>(new ContainerControlledLifetimeManager());
In order to avoid to use my local field, I use:
get {
return ServiceLocator.Current.GetInstance<Application.StateContext>();
}
inside my get property to get an instance of my object.
This way I get always the same instance (Application.StateContext is still a singleton) or does GetInstance create a new one?
Is it better to use the local _ambientContainer field instead?
get {
return _ambientContainer.Resolve<Application.StateContext>();
}
Thank you.
Passing around instances of the container to consumer classes isn't generally a good idea, since you are no longer guaranteed to have a single place in your application where components and services are being registered (known as the Composition Root).
Classes should state their dependencies in their public API, ideally by specifying them as constructor arguments, which the container will automatically provide an instance for whenever it's been asked to resolve a specific type (a process known as Autowiring).
Dependency Injection is usually the preferred choice but it isn't always applicable. In those cases using a Service Locator, like you're doing in your example, is the next best solution to decouple a class from its dependencies.
In conclusion, if Dependency Injection is not an option, I would avoid having my classes reference the container directly and instead have them access it through a Service Locator.
Preferably you should avoid both ways of (ab)using your container.
The ServiceLocator is considered an anti-pattern in modern application architecture.
I'm assuming that the ServiceLocator type is from the CommonServiceLocator project, and that you're using the Unity adapter, in which case GetInstance invokes container.Resolve, so both lines are equivalent.
You can view the source here - http://commonservicelocator.codeplex.com/wikipage?title=Unity%20Adapter&referringTitle=Home
I have been trying to use Ninject today and have a couple of questions. First of all do I need to use the Inject attribute on all constructors that I want to use injection for. This seems like a really lame design? Do I need to create a Kernel then use that everywhere I pass in an injected class?
The best way to get started with Ninject is to start small. Look for a new.
Somewhere in the middle of your application, you're creating a class inside another class. That means you're creating a dependency. Dependency Injection is about passing in those dependencies, usually through the constructor, instead of embedding them.
Say you have a class like this, used to automatically create a specific type of note in Word. (This is similar to a project I've done at work recently.)
class NoteCreator
{
public NoteHost Create()
{
var docCreator = new WordDocumentCreator();
docCreator.CreateNewDocument();
[etc.]
WordDocumentCreator is a class that handles the specifics of creating a new document in Microsoft Word (create an instance of Word, etc.). My class, NoteCreator, depends on WordDocumentCreator to perform its work.
The trouble is, if someday we decide to move to a superior word processor, I have to go find all the places where WordDocumentCreator is instantiated and change them to instantiate WordPerfectDocumentCreator instead.
Now imagine that I change my class to look like this:
class NoteCreator
{
WordDocumentCreator docCreator;
public NoteCreator(WordDocumentCreator docCreator) // constructor injection
{
this.docCreator = docCreator;
}
public NoteHost Create()
{
docCreator.CreateNewDocument();
[etc.]
My code hasn't changed that much; all I've done within the Create method is remove the line with the new. But now I'm injecting my dependency. Let's make one more small change:
class NoteCreator
{
IDocumentCreator docCreator;
public NoteCreator(IDocumentCreator docCreator) // change to interface
{
this.docCreator = docCreator;
}
public NoteHost Create()
{
docCreator.CreateNewDocument();
[etc.]
Instead of passing in a concrete WordDocumentCreator, I've extracted an IDocumentCreator interface with a CreateNewDocument method. Now I can pass in any class that implements that interface, and all NoteCreator has to do is call the method it knows about.
Now the tricky part. I should now have a compile error in my app, because somewhere I was creating NoteCreator with a parameterless constructor that no longer exists. Now I need to pull out that dependency as well. In other words, I go through the same process as above, but now I'm applying it to the class that creates a new NoteCreator. When you start extracting dependencies, you'll find that they tend to "bubble up" to the root of your application, which is the only place where you should have a reference to your DI container (e.g. Ninject).
The other thing I need to do is configure Ninject. The essential piece is a class that looks like this:
class MyAppModule : NinjectModule
{
public override void Load()
{
Bind<IDocumentCreator>()
.To<WordDocumentCreator>();
This tells Ninject that when I attempt to create a class that, somewhere down the line, requires an IDocumentCreator, it should create a WordDocumentCreator and use that. The process Ninject goes through looks something like this:
Create the application's MainWindow. Its constructor requires a NoteCreator.
OK, so create a NoteCreator. But its constructor requires an IDocumentCreator.
My configuration says that for an IDocumentCreator, I should use WordDocumentCreator. So create a WordDocumentCreator.
Now I can pass the WordDocumentCreator to the NoteCreator.
And now I can pass that NoteCreator to the MainWindow.
The beauty of this system is threefold.
First, if you fail to configure something, you'll know right away, because your objects are created as soon as your application is run. Ninject will give you a helpful error message saying that your IDocumentCreator (for instance) can't be resolved.
Second, if management later mandates the user of a superior word processor, all you have to do is
Write a WordPerfectDocumentCreator that implements IDocumentCreator.
Change MyAppModule above, binding IDocumentCreator to WordPerfectDocumentCreator instead.
Third, if I want to test my NoteCreator, I don't have to pass in a real WordDocumentCreator (or whatever I'm using). I can pass in a fake one. That way I can write a test that assumes my IDocumentCreator works correctly, and only tests the moving parts in NoteCreator itself. My fake IDocumentCreator will do nothing but return the correct response, and my test will make sure that NoteCreator does the right thing.
For more information about how to structure your applications this way, have a look at Mark Seemann's recent book, Dependency Injection in .NET. Unfortunately, it doesn't cover Ninject, but it does cover a number of other DI frameworks, and it talks about how to structure your application in the way I've described above.
Also have a look at Working Effectively With Legacy Code, by Michael Feathers. He talks about the testing side of the above: how to break out interfaces and pass in fakes for the purpose of isolating behavior and getting it under test.
First of all do I need to use the Inject attribute on all constructors
that I want to use injection for. This seems like a really lame
design?
No you shouldn't have to do this at all actually. Since you work with ASP.NET MVC you can just install the Ninject.MVC3 Nuget package. This will get you started with a NinjectMVC3 class in the App_Start folder. You can use the RegisterServices method to register your interfaces/classes with Ninject. All controllers that have dependencies to those interfaces will then be automatically resolved by Ninject, there is no need for the Inject attribute.
Do I need to create a Kernel then use that everywhere I pass in an
injected class?
No - what you are describing sounds more like the Service Locator pattern, not dependency injection - you will want to pass in your dependencies ideally in the constructor, instead of resolving them within particular classes using the kernel. There should be just one central composition root where the resolving is done, which is within the composition root in either the RegisterServices method mentioned above or a separate Ninject module instantiated there - the later approach will allow you a little more flexibility and modularity (no pun intended) in changing how you resolve your dependencies.
Here's a good beginner's tutorial on dependency injection with Ninject and MVC3.
Don't forget there are docs, including an intro I feel would be very appropriate given the sort of questions you are asking on the Ninject Wiki. You're just annoying yourself if you're trying to use Ninject without reading it end to end.
Stick the table of contents on your bookmark bar for a bit.
I can also highly recommend Mark Seemann's Dependency Injection in .Net as a companion book for DI based architecture (even though it doesnt directly cover Ninject).