Is anyone aware of a set of classes to abstract away the specific Dependency injection library (Spring, Castle, StructureMap, Ninject... etc.) ?
We all use a DI container to abstract away a specific implementation of our code, but we could also use the same interface / strategy pattern to write a generic interface based DI container using specific implementations such as Castle.Windsor, Unity... etc.
In general the basic pattern of "Getting and Object" from a container is pretty universal. For example:
IService service = IocContainer.Get<IService>();
Where IocContainer is a generic wrapper class around a specific library implementation such as Castle.Windsor, Unity... etc.
Of course in addition to writing specific implementations that you could 'plug-in' and of course, each implementation would have its own configuration file format.
Anyone have suggestions on existing well tested wrapper classes for DI containers?
The problem with all these wrappers and container abstractions is that they restrict you to the common subset of the functionallity that all the containers share. That's why you shouldn't do it. Instead use the container of your choice correctly:
Have just one "Get" in your application - in the composition root
Configure the container with conventions rather than usein a one by one service registration. This makes the configuration small.
Use factory interfaces wherever you have to create instances after the initial composition of your application and implement them as part of the container configuration (Some container do this implementation automatically for you)
With these simple rules your container is known in one place only - the composition root - which makes any abstraction of the container obsolete. That way you can use the full power of the container.
Related
I have used Unity for my last project and was generally pleased. But benchmarks have me thinking I may go with Simple Injector for my next project.
However, Simple Injector does not seem to have an interface for its Container class. This means that anytime I want to use the container in a method, I cannot mock the container for unit testing.
I am confused how a tool that really functions based of interfaces, would not itself make an interface to the container. I know that the classic methods of dependency injection do not need the container for anywhere more than the startup. (The rest uses constructor injection.) But I have found that when the rubber hits the road that cannot always be true. Sometimes you just need the container in order to do a "resolve" in the code.
If I go with Simple Injector then that code seems to gets harder to unit test.
Am I right? Or am I missing something?
Simple Injector does not contain an IContainer abstraction, because:
It would be useless for Simple Injector to define it,
because in case of depending on IContainer instead of Container, your code would in that case still depend on Simple Injector, and this causes a vendor lock-in, which Simple Injector tries to prevent.
Any code you write, apart from the application's Composition Root, should not depend on the container, nor on an abstraction over the container. Both are implementations of the Service Locator anti-pattern.
You should NOT use a DI library when unit testing. When unit testing, you should manually inject all fake or mock objects in the class under test. Using a container only complicates things. Perhaps you are using a container, because manually creating those classes is too cumbersome for you. This might indicate problems with your code (you might be violating the Single Responsibility Principle) or your tests (you might be missing a factory method to create the class under test).
You might use the container for your integration tests, but you
shouldn't have that many integration tests in the first place. The focus should be on unit tests and this should be easy when applying the dependency injection pattern. On top of that, there are better ways of hiding the container from your integration tests, compared to depending on a very wide library-defined interface.
It is trivial to define such interface (plus an adapter) yourself, which justifies not having it in the library. It is your job as application developer to define the right abstractions for your application as stated by the Dependency Inversion Principle. Libraries and frameworks that tend to do this will fail most of the time in providing an abstraction that works for everyone.
The library itself does not use that abstraction and a library should, according to the Framework Design Guidelines, in that case not define such abstraction for you. As stated in the previous point, Simple Injector would get the abstraction wrong anyway.
Last but not least, the Simple Injector container does actually implement System.IServiceProvider which is defined in mscorlib.dll and can be used for retrieving service objects.
I think the answer given here is entirely founded upon accepting that ServiceLocator is an anti-pattern, which in turn I don't believe is globally accepted as true. See Windows Workflow Foundation's Extensions support.
The anti-pattern link (and its two updates) may also be weak... the latest update claims violation of encapsulation ("relieving you of the burden of having to understand every implementation detail of every piece of code in your code base.") while then at the same time claiming that up-front knowledge of dependencies is somehow different for that claim than discovering them via unit tests. Either way, you're going to need to know what to give it.
All in all, if you want to follow the Locator pattern, either leverage its IServiceProvider, or simplify your container population (to a singleton) and create a static wrapper for it.
When using inversion of control in a .Net application, is it acceptable to add a reference to your data layer in your host application?
Say I have the following individual projects:
MyApp.Data (EF classes)
MyApp.Business (Service factory / repository)
MyApp.Services.MyWCFService (Host)
MyApp.Presentation.MVC (Host)
MyApp.Business.Tests (Host)
In this situation, I have historically used IoC between MyApp.Business and the host apps - creating interfaces for each service factory / repository, and using DI in the host application. Each application then has the choice to inject its own implementation of my business factories. I've never had an issue with this, as my host apps only ever rely on the business layer, and I never have to reference the MyApp.Data assembly (my MyApp.Business generally deals with all calls to the MyApp.Data assembly, and renders the results in to composite business objects).
What I'm trying to achieve with my latest project is to use IoC at every level - i.e. creating interfaces in MyApp.Data, so I can apply mocking and proper unit tests to MyApp.Business. It seems to me that the only way to achieve this is to create an assembly reference to both MyApp.Business and MyApp.Data in the host application, then use DI to inject both the MyApp.Data and MyApp.Business implementations.
This is contrary to everything I've been taught with conventional nTier applications, though I understand that it's DI that's doing all the work, and the reference is basically for resolution only. Am I right in assuming this is the right way to approach it? Is there a better way?
In short: Yes, it is acceptable to reference each and any part of your app from the main entry point of your application.
The concept is called Composition Root.
Suppose I have a BaseForm which depends on an ILogger or IResourceManager or something like that. Currently it resolves the correct implementation of the required service using the service locator which I know is an anti-pattern.
Is using the constructor injection the right way to resolve this kind of dependency?
Do I have to register my BaseForm (and its' derived types) in the container in order to create instances of them with resolved dependencies? Doesn't that complicate everything?
Is it bad to use a static factory wrapped around a service locator?
Unit-testing aside, will I really be punished because of using service locator anti-pattern?
Sorry about asking many questions at once. I've read the following SO questions and many others but reading them only added to my confusion:
How to use Dependency Injection and not Service Locator
What's the difference between the Dependency Injection and Service Locator patterns?
How to avoid Service Locator Anti-Pattern?
If possible, you should always go with dependency injection, since it has a few clear strength. With UI technologies however, it is not always possible to use dependency injection, since some UI technologies (in .NET space, Win Forms and Web Forms, for instance) only allow your UI classes (forms, pages, controls, etc) to have a default constructor. In that case you will have to fall back to something else, which is service locator.
In that case I can give you the following advice:
Only fall back to Service Locator for UI classes that can't be created by your container using dependency injection, and for stuff that you aren't unit testing anyway.
Try to implement as less logic as possible in those UI classes (as Humble objects with only view related stuff). This allows you to unit test as much as possible.
Wrap the container around a static method to hide the container from the rest of the application. Make sure that a call to this static method fails, when the dependency cannot be resolved.
Resolve all dependencies in the (default) constructor of that type. This allows the application to fail fast when one of its dependencies cannot be resolved when that type is created, instead of later on when some button is clicked.
Check during app start-up (or using a unit test), if all those UI types can be created. This saves you from having to go through the whole application (by opening all forms) to see if there is an error in the DI configuration.
When types cannot be built by the container, there is no reason to register them in the container. If they can be created by the container (such as with ASP.NET MVC Controller classes), it can be useful to register them explicitly, because some containers allow you to verify the configuration up front, which will detect configuration errors in those types right away.
Besides unit testing, there are two other important arguments against the use of the Service Locator, which are given by Mark Seemann in his famous blog post Service Locator is an Anti-Pattern:
Service Locator "hides a class’ dependencies, causing run-time errors instead of compile-time errors"
Service Locator is "making the code more difficult to maintain"
I am trying to figure out how to create multiple objects when using Dependency Injection. As far as I understand the standard approach is to inject a Factory which is then used to create the objects. The part I struggle with is how the Factory creates the objects. So far I see two possible solutions:
The Factory just uses new() to create the object.
Isn't DI supposed to free me of the use of new for non value objects?
What happens if the Object to be created has dependencies that could be resolved by the IoC?
Use the Container as Serviclocator
solves the problems of just newing objects at the cost of introducing an antipattern or is it no longer an antipattern if the use of the serviclocater is constraind within the factories?
It feels like i can coose between a bad and a bad solution. Is there something I am missing or do I understand somthing wrong here?
Edit Currently I am not using an Ioc at all but thinking about Ninject. Although the Autofac DelegateFactories sound very promising.
For starters, I don't consider using a container as service locator in factories an anti-pattern. There are genuine circumstances where it is entirely appropriate. Come to think about it, container aware factories are really container extensions, and those seem to be excluded from service locator bashing. Even the most pure IoC frameworks like AutoFac or Ninject have extensive extension capabilities. A most typical use case for this pattern is resolving to different implementations based on where the service is used.
With regards to using new to create instances inside factories, that is acceptable as well. The IoC/DI message got a bit distorted there and never using new is really a side effect, rather than the goal of DI. The first imperative of Dependency Injection is to externalise creation of dependencies from the component. A factory satisfies that imperative as long as it itself gets injected into component. The questions you need to ask yourself when evaluating such scenarios are:
Does the component itself create its dependencies? A: No, the factory does.
Can you make the component work with different dependencies without modifying it? A: Yes, by injecting a different factory.
I said this before, IoC containers are just factories on steroids. For 80% use case they work out of the box. The other 20% might require tweaks of the above two varieties. I tend to use container aware factories when I want to create components that require both registered dependencies and some input at run-time and new-ing factories when I create Domain objects that don't have dependencies on other services, but take all their construction parameters at run time.
Although the interface for your factory will be defined at the application level, you would typically define the implementation of that factory class close to your DI configuration, thus as part of your composition root. Although calling the container directly from your code is an implementation of the Service Locator anti-pattern, any code that is defined inside the compostion root is merely mechanics and is therefore not Service Locator. As long as newing up objects or calling into the container is done inside (or very close to) the composition root, this is not a problem, because the application will still be clean from any locator / container.
In other words: use the factory approach. Whether or not you need to new up objects directly inside your factory or make use of the container, depends on the objects. Letting the container create the objects is preferable, especially when they got dependencies on their own, but not all objects can be created by the container. In that case you need to revert to the new operation. Both are fine when the code is part of the composition root and not of the application. The factory itself can have dependencies of its own. This should not be a problem. You can let the container wire-up the factory instance.
I am hearing people say you should not use Service Locator for your Dependency Injection. So how exactly do you inject the dependencies without relying on a service locator? I want to try out IoC containers, but don't want to land into an anti-pattern.
Should you just set everything up so there is one place where all classes always have a dependency chain to the deepest classes? (if I/that makes sense at all)
I isn't right to have all your code littered with dependencies on the IoC container of choice, is it?
So where do you "use" your the container (for rexolving)? And how do you get it to resolve everything, as deep as your code goes? Is it a part of designing everything the right way by using interfaces through every layer up till the front layer?
Or am I just missing a point?
Let me remind you that I just don't want to fall into an anti-pattern and need some tips / a heads up on it.
Should you just set everything up so
there is one place where all classes
always have a dependency chain to the
deepest classes? (if I/that makes
sense at all)
Yes, this is called the composition root of your application, and it's where you would configure your IoC container and resolve your root type.
It isn't right to have all your code
littered with dependencies on the IoC
container of choice, is it?
Correct, it is better to not pass references to your IoC container around your types, as this will make them less reusable, and couple the types to the concept of IoC containers in general.
So where do you "use" your the
container (for rexolving)? And how do
you get it to resolve everything, as
deep as your code goes? Is it a part
of designing everything the right way
by using interfaces through every
layer up till the front layer?
You would use your container at your composition root, and anywhere in your code that needs to instantiate types (i.e. from factory types) via the container (usually for dependency chain support).
Many IoC containers can generate these factory types for you, so you only need to pass, e.g. IMyFactory as a dependency, or in some IoC container's case, a Func<IMyService>. That means that you don't need to create factory types that have a dependency on your IoC container.
In terms of using interfaces, the Dependency Inversion Principle states that you should depend on abstractions, not on concretions, so you will need to factor your code with this concept in mind if you wish to adopt dependency injection.