Best way of using IoC for production and Testing - c#

When using IoC for dependency injection the most recommended use is constructor injection (as told by many articles), my question is :
Is it better to inject using the constructor parameters or passing the IoC container through the constructor to inject the classes needed, and what is more useful for unit testing ?

Although passing the container through the constructor is better than making the container accessible as a singleton for the complete application, it is still a form of Service Locator (anti-pattern), and is not recommended. This has clear disadvantages:
It makes your code much harder to follow.
It makes it much less obvious when the Single Responsibility Principle is violated (since the class hides which things it depends on).
It makes it much hard to test, since you need to pass a configured container and you need to look in the code to see what the test need.
When requesting instances from the container directly from within every class, you will disable many features that IOC containers give you, because you don't allow the container to build up the object graph. Depending on the framework of choice, certain lifestyles and features like context based injection will not be usable.
All your tests use a container instance, making your tests come complex, and all your test have a dependency on the DI framework, which makes it very expensive to switch to another framework when needed.
Just inject the dependencies into the constructor, never* the container itself.
*Exception to this rule is when such class is located inside the appliation's Composition Root. In that case it's not considered to be the Simple Locator pattern, because that class is simply an infrastructure component.

Using constructor/property injection is better. When you pass the IOC container to the constructor you are no longer doing dependency injection and inversion of control. You are doing the Service Locator pattern. This means that classes no longer get their dependencies injected by the consumer, but they try are trying to fetch them. You are also probably tying your code to some particular DI framework.

Related

IoC Instantiate latest time possible

In my application I have many services with I use the following pattern:
In the same file as the interface I define a static factory method which is controlled by the IoC container as follows:
public interface ISomethingService {
Task DoSomethingAsync(int id);
}
public class SomethingServicFactory : ServiceFactory<ISomethingService > { }
public class ServiceFactory<T>
{
public static Func<T> CreateClosure;
public T GetDefault() => CreateClosure();
}
After creating and configuring the IoC container:
SomethingServicFactory .CreateClosure = () =>
Container.GetInstance<ISomethingService >();
Later in my application when I need a SomethingService:
var somethingService= new SomethingService().GetDefault();
This allows me to defer creation until the last moment yet still control the service creation using the container. I just started using SimpleInjector.
More importantly it allows me to create an instance of the service and easily pass it parameters while giving control to the IoC.
A great example where this pattern helps me is in a WPF XAML instantiated user control that needs to populate data (i.e. lookup values from a database). In the code behind I am able to easily create a DbContext and get data from the database. However, I have come to use it throughout the application as well.
I am concerned that I am missing a significant design/architecture problem by using this pattern and I am looking for comments on this pattern by IoC experts.
Your design exposes the following code smells and anti-patterns:
Temporal Coupling: Your CreateClosure property forces you to initialize your service factory after its creation. When you forget this, the application will fail at runtime. Temporal Coupling is a code smell.
Ambient Context: The CreateClosure acts as an Ambient Context (which is much like the Singleton design pattern, but with the ability to change the value using a static method or property). This causes a class's dependencies to be hidden, instead of 'statically declared' using the class's constructor. In Dependency Injection in .NET 2nd edition, we consider Ambient Context an anti-pattern (see chapter 5).
Dependency Inversion Principle violation: Your factories are concrete classes, while the DIP promotes talking to interfaces. As a result, your code becomes strongly coupled and hard to test.
Abstract Factories are a code smell: When applying Dependency Injection, the usefulness of factories evaporates. Especially the idea of having a factory for every abstraction in your application is an absolute no-no.
Instead, with Dependency Injection, everything becomes much easier: When we apply Constructor Injection, we can simply inject ISomethingService into its consumers. This:
Makes it clear what dependencies a class has, by looking at the constructor
Allows the DI container to compose the object graph for you and do analysis and diagnostics on the graph
Allows the container to manage lifetime of objects
Removes the need for having factories (since the container will take that role)
Reduces the number of dependencies a class has. Instead of needing 2 (one for the factory and one for the service), you only need one (for the service).

Dependency injection: by hand vs autofac

Managing Dependency Injection in C# with Autofac explains in a very concise way with downloadable source code
Dependency injection by hand
var di = new EmployeeObserver(employees, new Printer(Console.Out));
di.FindExperts();
with autofac:
ContainerBuilder autofac = new ContainerBuilder();
autofac.Register(o => new EmployeeObserver(o.Resolve<IList<Employee>>(), o.Resolve<IPrinter>()));
autofac.RegisterType<Printer>().As<IPrinter>();
autofac.RegisterInstance(employees).As<IList<Employee>>();
autofac.RegisterInstance(Console.Out).As<TextWriter>();
using (var container = autofac.Build())
{
container.Resolve<EmployeeObserver>().FindExperts();
}
In some other Q&As, it says we can see the advantage usage of autofac while writing unit test.
Apart from that, could someone give reasons or details more why should I use more complicate code with autofac instead of by manual dependency injection?
It says:
May be on this particular example it's hard to see why this approach
is better than configuring dependency injection by hand, but you
should notice one important thing - with Autofac each component is
configured independently of all the others, and this is what will make
a big difference when your application become more complex.
Can you point an example of complex version of this case, that shows advantage of autofac usage vs dependency by hand that I will stuck with?
Using or not using a DI container has no effect on unit testing. When you unit test, you don't use a DI container because unit tests usually deal with a single or a few classes that you can wire together easily.
Please note that whether to use or not use a DI container to compose your objects is still a highly opinionated question. Here I provide a perspective that I have based on my experience using dependency injection in my projects.
In an article of mine, Why DI containers fail with “complex” object graphs, I define the concept of a simple object graph like this:
An object graph of any size and any depth that has the following two attributes:
a) For any interface (or abstraction) at most one class that implements such interface is used in the object graph.
b) For any class, at most one instance is used in the object graph (or multiple instances with the exact same construction parameter arguments). This single instance can be used multiple times in the graph.
When you have a simple object graph, use a DI container.
For an example of a simple object graph, consider that you have 20 service interfaces that is each implemented by a single class. E.g. IEmailService is only implemented by EmailService, and ISMSService is only implemented by SMSService, etc., and that you have 30 ASP.NET controllers each depending on any number of these service interfaces. Also some of the services depend on other service interfaces, e.g. OrderService depends on IEmailService.
When you don't have a simple object graph, i.e., you have a complex object graph (which is the case for most large applications that apply the SOLID principles), don't use a DI container and instead use Pure DI.
If you use a DI container with a complex object graph, you will end up using complex features of the container like named registrations to distinguish between different implementations of the same interface or between objects that take different construction parameters. This will make your composition root hard to maintain.
You might want to a look at this article of mine about how Pure DI can make your composition root clean.
In some other Q&As, it says we can see the advantage usage of autofac while writing unit test
You've missed the point.
The ability to mock dependency, and, hence, to write unit test, is the advantage of dependency injection as a pattern itself.
Advantage of any DI-container (not only Autofac) is ability to configure dependencies somehow and use this configuration in complex scenarios.
Imagine, that you have some class, that depends on some service, which, in turn depends on some other service, and so on.
It is hard to implement this using poor man's DI, but DI-containers can deal with this.

How do I use Structuremap 3 with objects that aren't friendly to constructor injection?

I'm moving from StructureMap 2.x to 3.x. One major change is that using ObjectFactory results in the following warning:
'StructureMap.ObjectFactory' is obsolete: 'ObjectFactory
will be removed in a future 4.0 release of StructureMap. Favor the
usage of the Container class for future
work'
So in most cases, the resolution is fairly easy: pass through IContainer as a constructor. Unfortunately this is not feasible for ASMX web serivces or attributes, both of which require a default constructor. That means I'm probably stuck with the Service Locator Pattern, property injection, or writing my own ObjectFactory implementation.
What's the preferred way to deal with this unfortunate problem?
Edit: It's worth mentioning that my container does an Assembly scan.
Per Jeremy Miller, himself:
Assembly scanning isn’t cheap and you (almost?) always wanna cache the
results. So, yeah, in that case you’re going to have to write your
own ObjectFactory. Someday all that bad old MS tech will go away.
So in this case, this implementation is what should be done.
The cleanest way I have seen to deal with this is to use .NET routing to take control of the entry point, then make a custom PageHandlerFactory implementation that takes the DI container as a dependency.
The custom page handler factory will then property inject the page/service after it is instantiated but before any of its events are called.
This is almost exactly the same way that IControllerFactory works with DI in MVC. In MVC, the container is injected into a custom IControllerFactory implementation at application startup, which effectively makes it a part of the application's composition root. In the case of ASP.NET, the IRouteHandler would effectively be part of the composition root.
I was unable to find a link to the source where I originally saw that implementation. But this one is pretty close. The primary difference is that one tries to use constructor injection, but the downside is that it requires full trust to do. I believe if you stick with property injection, you can do it with partial trust.

Proper way for property injection using Autofac

I'm building a MVC application with Autofac and EntityFramework. I have a large set of data repositories / business objects that use my logging interface (NLog). I have just started working with Autofac and would like to know the preferred way for property injection:
Pass ILogging as constructor property, for this I have to set each local property from the constructor and creates larger constructor footprints.
Register each object individually with Autofac (they do not share a generic interface)
Use an Autofac.Module to locate these objects and set the property with reflection
Create a generic interface ILoggerDependency and register this with Autofac, this way all objects are easely registred.
My preferred method (out of lazyness...) is to have a generic interface that I can register with Autofac.
I am not that familiar with Autofac, so I'll try to give you my best recommendation based on what I know.
If there is one thing a lot of people gets wrong with dependency injection, it has to be using it for automation. The goal of DI is not to remove magic from your code. If anything, it is quite the opposite.
Keeping that in mind, I would not even consider using reflection as it hides large amounts of fragile plumbing.
Next, interfaces in OOP are meant to express what an object can do. Being injected is definitely not an action an object can take, but rather something that is imposed on an object. Even though, it is a quick and dirty way to solve your issue, I would refrain from using it as it will denature the structure of your code.
I have trouble understanding what you mean by pass ILogging as constructor property. Basically, you mean to resolve the interface yourself in the constructor? This looks a lot like property injection which defeats the purpose of DI by adding a strong dependency on your container within your class. Basically, instead of depending on Log4Net, you end up depending on Autofac. To fix this, you would need to add a service locator and then you still end up with a similar problem. How do you inject your service locator?
This is why I would register each object individually. It lets your container do its job. It doesn't affect your code structure and abstractions. It doesn't uses reflection (magic). It doesn't force you to depend on your container within each class. Besides, it also gives you a centralized place to look for when adding or removing repositories from your code.

Best Practices for IOC Container

I'm using the Unity IOC container and I'm just wondering what is the best best way to access the container for multiple classes.
Should every class have an IUnityContainer member and then pass the container in by constructor? Should there be a singleton class with an IOC container?
How about asp.net development?
Could somebody guide me in the right direction? Thanks.
IMHO it is not advisable to inject the entire container into a class or to have an application wide static IoC service locator.
You want to be able to see from the constructor of a class (lets call it Foo), what kind of services/objects it is using to get the work done. This improves clarity, testability and degubability.
Lets say Foo only needs the email service, but I pass in the whole container and somewhere in the code the email service gets resolved from the container. In this case it will be very hard to follow. Instead it is better to inject the email service directly to state Foo's dependencies clearer.
If Foo needs to create multiple instances of the email service, it is better to create and inject an EmailServiceFactory (via the IoC container), which will create the required instances on the fly.
In the latter case, Foo's dependencies are still indicated as specific as possible - only the ones, that the EmailServiceFactory can create. Had I injected the whole container, it would not be clear what services provided by it are Foo's exact dependencies.
Now, if I later want to provide different instances of the email service, I swap it out inside the EmailServiceFactory. I could swap out the whole factory as well, if all the services it creates need to be swapped (e.g. during testing).
So at the cost of creating one extra class (the factory), I get much cleaner code and won't have to worry about curious bugs that may occur when global statics are used. Additionally when supplying mocks for testing, I know exactly what mocks it needs and don't have to mock out an entire container's types.
This approach also has the advantage, that now, when a module is initialized (only applies to Prism / Modularity), it doesn't have to register all of the types of objects it supplies with the IoC container. Instead it can just register its ServiceFactory which then supplies those objects.
To be clear, the module's initialization class (implements IModule) should still receive the application wide IoC container in its constructor in order to supply services, that are consumed by other modules, but the container should not invade into the module's classes.
Finally, what we have here is another fine example of how an extra layer of indirection solves a problem.
Put the IOC container at the highest level / entry point in the process and use it to inject dependencies in everything underneath it.
you can register the container in itself and have it injected like every other dependency property, like so:
IUnityContainer container = new UnityContainer();
container.RegisterInstance<IUnityContainer>(container);
classes that need to access it will have the following property:
private IUnityContainer unityContainer;
[Dependency]
public IUnityContainer UnityContainer
{
get { return unityContainer; }
set { unityContainer = value; }
}
thus, the container is injected whenever an instance of such a class is resolved/built up.
This is more flexible as it works for multiple containers within the same application, which would not be possible with the singleton pattern.
If all of your objects need a reference to the container then you should look into reworking the code some. While still preferable to calling new everywhere it still scatters the responsibility of building your object graphs throughout your code. With that kind of usage it strikes me as being used more like a ServiceLocator instead of a IoC Container.
Another option would be using the CommonServiceLocator, although it may be a pointless indirection, you may use the ServiceLocator.Current as the instance known by all classes
I have a post on this subject at my blog where I´m using something along the lines of t3mujin answer. Feel free to use it (don´t bother that it´s sharepoint related...that doesn´t matter):
http://johanleino.spaces.live.com/blog/cns!6BE273C70C45B5D1!213.entry

Categories