Remove Dependency on IoC Container - c#

After reading more and more about IoC containers, I read this post about not having IoC.Resolve() etc in your code.
I'm really curious to know then, how can I remove the dependency on the container?
I'll want to write code like the following:
public void Action()
{
using(IDataContext dc = IoC.Resolve<IDataContext>())
{
IUserRepository repo = IoC.Resolve<IUserRepository>();
// Do stuff with repo...
}
}
But how can I get rid of the IoC.Resolve calls? Maybe I need a better understanding of DI...
Thanks in advance.

Generally speaking, most dependencies can be injected into your class at the time it is created. However, in this particular case, you need a component that must be created on demand at the time of use. In such cases, it is very difficult to completely remove dependency on an IoC container. My approach has always been to create a factory that is injected into the class at creation time, which in turn encapsulates all direct IoC usage. This allows your factories to be mocked for testing, rather than the IoC container itself...which tends to be a lot easier:
// In Presentation.csproj
class PresentationController
{
public PresentationController(IDataContextFactory dataContextFactory, IRepositoryFactory repositoryFactory)
{
#region .NET 4 Contract
Contract.Requires(dataContextFactory != null);
Contract.Requires(repositoryFactory != null);
#endregion
_dataContextFactory = dataContextFactory;
_repositoryFactory = repositoryFactory;
}
private readonly IDataContextFactory _dataContextFactory;
private readonly IRepositoryFactory _repositoryFactory;
public void Action()
{
using (IDataContext dc = _dataContextFactory.CreateInstance())
{
var repo = _repositoryFactory.CreateUserRepository();
// do stuff with repo...
}
}
}
// In Factories.API.csproj
interface IDataContextFactory
{
IDataContext CreateInstance();
}
interface IRepositoryFactory
{
IUserRepository CreateUserRepository();
IAddressRepository CreateAddressRepository();
// etc.
}
// In Factories.Impl.csproj
class DataContextFactory: IDataContextFactory
{
public IDataContext CreateInstance()
{
var context = IoC.Resolve<IDataContext>();
// Do any common setup or initialization that may be required on 'context'
return context;
}
}
class RepositoryFactory: IRepositoryFactory
{
public IUserRepository CreateUserRepository()
{
var repo = IoC.Resolve<IUserRepository>();
// Do any common setup or initialization that may be required on 'repo'
return repo;
}
public IAddressRepository CreateAddressRepository()
{
var repo = IoC.Resolve<IAddressRepository>();
// Do any common setup or initialization that may be required on 'repo'
return repo;
}
// etc.
}
The benefit of this approach is, while you can not completely eliminate the IoC dependency itself, you can encapsulate it in a single kind of object (a factory), decoupling the bulk of your code from the IoC container. This improves your codes agility in light of, say, switching from one IoC container to another (i.e. Windsor to Ninject).
It should be noted, an interesting consequence of this, is that your factories are usually injected into their dependents by the same IoC framework they use. If you are using Castle Windsor, for example, you would create configuration that tells the IoC container to inject the two factories into your business component when it is created. The business component itself may also have a factory...or, it may simply be injected by the same IoC framework into a higher-level component, etc. etc., ad inf.

One alternative is to re-write the method to accept Func<T> delegates. This removes the dependency from the method and allows you to unit test it with a mock:
public void Action(Func<IDataContext> getDataContext, Func<IUserRepository> getUserRepository)
{
using(IDataContext dc = getDataContext())
{
IUserRepository repo = getUserRepository();
// Do stuff with repo...
}
}

I was on a project a while ago that hadn't settled on an IoC container. They managed the uncertainty by disallowing non-IoC specific features of their container and also by wrapping Resolve with their own class. This is also something I've seen advocated a few times in blog posts... remove the last dependency, the dependency on the dependency injection container.
This is a workable technique, but at some point you have to choose the tools you use and be willing to accept that you'll pay costs to switch to alternative tools. For me, IoC containers fall into the category of things you probably ought to embrace wholeheartedly, so I question this level of factoring. If you want to look into this further, I suggest the following link:
http://blog.objectmentor.com/articles/2010/01/17/dependency-injection-inversion

I blogged about this very issue recently:
How I use IoC Containers
Pulling from the container

Have a second dependency injector to inject the first one, and have the first one inject the second one.

Related

How to use Dependency Injection with the Facade pattern?

I am using autofac in my UWP application.
I am using the facade pattern for my backend and it is represented by an IFacade interface.
public interface IFacade
{
/* forwards view-models' calls to different parts of the backend */
}
The view-models of my UWP application are using an implementation of IFacade whose concrete implementation is resolved through autofac in the UWP's App instance.
public class App : Application
{
...
private IFacade InitializeDependencies()
{
var containerBuilder = new ContainerBuilder();
// Registers all the platform-specific implementations of services.
containerBuilder.RegisterType<LoggingService>().As<ILoggingService>().SingleInstance();
containerBuilder.RegisterType<SQLitePlatformService>().As<ISQLitePlatformService>().SingleInstance();
containerBuilder.RegisterType<DiskStorageService>().As<IDiskStorageService>().SingleInstance();
containerBuilder.RegisterType<IdentityProviderFactoryService>().As<IIdentityProviderFactoryService>().SingleInstance();
containerBuilder.RegisterType<DefaultVaultService>().As<IVaultService>().SingleInstance();
containerBuilder.RegisterType<LocationService>().As<ILocationService>().SingleInstance();
containerBuilder.RegisterType<NavigationService>().As<INavigationService>().SingleInstance();
// Registers all the dependencies of the Backend project.
var backendDependencies = new Dependencies();
backendDependencies.Setup(containerBuilder);
// Resolves the IFacade.
var container = containerBuilder.Build();
var lifetimeScope = container.BeginLifetimeScope();
return backendDependencies.ResolveFacade(lifetimeScope);
}
I have a lot of services in my backend and my implementation of IFacade ends up with that horrific constructor referencing a lot of services' interfaces, something would make Uncle Bob cringe.
internal sealed Facade : IFacade
{
public Facade(ISessionService sessionService, IEntitiesRepository entitiesRepository, ISynchronizationService synchronizationService, IVaultService vaultService, IIdentityProviderFactoryService identityProviderFactoryService, IDemoTapeService demoTapeService, IDiskStorageService diskStorageService)
{
/* Saves the references as read-only fields. */
}
}
Question
Contrary to the ServiceLocator, using DI forces us to make all the dependencies that are needed visible. I am not sure if I am using the Dependency Injection properly.
What can I do so that my constructor of my Facade class does not have that many parameters?
Solutions tried
Properties
I could change the Facade class and inject the services through public properties. I am not fond of lots of public get / set as my IFacade contract would now indicate that those properties could be changed after the Facade implementation is created, which is not something I want to support (and debug).
Aggregate interfaces
Another option would be to aggregate interfaces together (something that I call the SomethingContext classes) but then it is harder to understand what these groups of interfaces would mean.
Inject a ServiceLocator that is not static in the Facade constructor
The last solution that seems more acceptable (well... acceptable to me) would be to use DI to inject a non-static ServiceLocator. It is kind of solution 2). However, I know the ServiceLocator is something that is frowned upon.
So one another approach is to create some smaller Facade Services and then inject those services to the main facade.
For example you can create such smaller facade for INavigationService and ILocationService:
public class GeographyService : IGeographyService
{
public GeographyService(
INavigationService navigationService,
ILocationService locationService)
{
}
}
The same is true for ISQLitePlatformService and DiskStorageService:
public class StorageService : IStorageService
{
public StorageService(
ISQLitePlatformService databaseService,
DiskStorageService diskStorageService)
{
}
}
That's of course only an example of an idea.
Such an approach is generally considered better than aggregate services with all the dependencies aggregated (http://autofaccn.readthedocs.io/en/latest/advanced/aggregate-services.html) or ServiceLocator (anti-)pattern. You can also read some thoughts about it here: http://blog.ploeh.dk/2010/02/02/RefactoringtoAggregateServices/

Is there any practical usage of using unity container to add, resolve dependencies in the controller itself?

In the MVC application i am working with these days, they have registered and resolved all the Interface/Concrete class dependencies inside the controller itself. I read about ioc and dependency inversion and found that the thing that has been done is completely non-useful. Since it would anyway not allow the application to leverage benefits of IoC example mocking, unit testing and would also add cost of adding/resolving the dependencies unnecessarily. Below is code sample:
HomeController
using(IUnityContainer container= new UnityContainer())
{
container.RegisterType<IRepository1, Repository1>()
IRepository1 _repos1 = container.Resolve<IRepository1>();
}
I dont see any point of doing all this stuff if we dont get any benefit out of this. Can someone please tell if this could be of any use now or in future?
If not, i am planning to simply instantiate them with concrete implementations or like:
IRepository1 repos1= new Repository1();
Please ignore the syntax.
(I have editted the code snippet now.)
Using a container to first register and then resolve a concrete type doesn't make any sense, there is no benefit of that. You are still coupled to a concrete type. You could possibly argue that the container helps to match all constructor parameters with instances of respective types but this doesn't count as a real benefit in my opinion.
If you really don't plan to make use of abstractions that are resolved externally, then yes, you can safely remove the bloating container code and create concrete instances, just as you have presented.
The immediate answer to this question is your current implementation causes more overhead and performance impact then doing a standard construction, and you should remove it; or redesign your implementation of Unity.
The following is an example of the benefit of injection that occurs when resolving to a type that has a dependency of another type that is registered with the unity container.
public class UserService
{
internal readonly IRepository _repository;
public UserService(IRepository repository)
{
_repository = repository;
}
//Service Method that exposes 'Domain Logic'
public void CreateUser(string FirstName)
{
_repository.Insert<User>(new User() { FirstName = FirstName }); //Assumes there is a Generic method, Insert<T>, that attaches instances to the underline context.
}
public User GetUser(string FirstName)
{
return _repository.Query<User>().FirstOrDefault(user => user.FirstName == FirstName); // assumes there is a Generic method, Query<T>, that returns IQueryable<T> on IRepository
}
}
register the types (probably in a singleton pattern at Global.asax)
//Resolver is an instance of UnityContainer
Resolver.RegisterType<IRepository, Repository>(new ContainerControlledLifetimeManager());
Resolver.RegisterType<IUserService, UserService>();
Then the logic in your controller is like so:
var service = Resolver.Resolve<IUserService>(); //the resolver will resolve IRepository to an instance as well...
var user = service.GetUser("Grant");

Dependency injection with factory for child class with constructor argument

I've got this app that uses Ninject for DI and I've got the following construction:
public class SomeServicHost
{
private ISomeService service;
public SomeServicHost(ISomeService service)
{
this.service = service;
}
public void DoSomething(int id)
{
// Injected instance
this.service.DoWhatever("Whatever");
// Without injection - this would be how it would be instantiated
var s = new SomeService(new Repo(id));
s.DoWhatever("Whatever");
}
}
interface ISomeService
{
void DoWhatever(string id);
}
class SomeService : ISomeService
{
private IRepo SomeRepo;
public SomeService(IRepo someRepo)
{
this.SomeRepo = someRepo;
}
public void DoWhatever(string id)
{
SomeRepo.DoSomething();
}
}
interface IRepo
{
void DoSomething();
}
class Repo : IRepo
{
private int queueId;
public Repo(int queueId)
{
this.queueId = queueId;
}
public void DoSomething()
{
// Whatever happens
}
So normal injection is not going to work. I'm going to need a factory. So I could do something like:
interface IServiceFactory
{
ISomeService GetService(int id)
{
return new SomeService(new Repo(id));
}
}
Which I acually have already. But if I do that, I lose all of the DI goodness, like lifecycle management, or swap out one implementation with another. Is there a more elegant way of doing this?
Keeping the factory as you describe it, seems fine to me. That's what they are for, when you have services that can only be instantiated at runtime depending on some runtime value (like id in your case), factory is the way to go.
But if I do that, I lose all of the DI goodness, like lifecycle
management, or swap out one implementation with another.
DI is not an alternative for factories. You need both worlds which lead to a flexible, loosely coupled design. Factories are for new-ing up dependencies, they know how to create them, with what configuration and when to dispose them, and if you want to swap implementations, you still change only one place: only this time it's the factory, not your DI configuration.
As a last note, you might be tempted to use the service locator anti-pattern, as proposed in another answer. You'll just end up with worse design, less testable, less clear, possibly tightly coupled with you DI container and so on. Your idea for using a factory is far better. (here are more examples, similar to yours).
Instead of doing
new SomeService(new Repo(id));
you can do
IResolutionRoot.Get<Repo>(new ConstructorArgument("id", id));
IResolutionRoot is the type resolution interface of the kernel, and you can have it constructor injected. This will allow you to benefit from the "DI goodness", as you called it. Please note that you might also want to use the ninject.extensions.contextpreservation extension.
The ninject.extensions.factory, that #Simon Whitehead pointed out already, helps you eliminate boiler plate code and basically does exactly what i've described above.
By moving the IResolutionRoot.Get<> call to another class (.. factory...) you unburden SomeService from the instanciation. the ninject.extension.factory does exactly that. Since the extension does not need an actual implementation, you can even save yourself some unit tests! Furthermore, what about if SomeService is extended and requires some more dependencies, which the DI manages? Well no worries, since you are using the kernel to instanciate the class, it will work automatically, and the IoC will manage your dependencies as it should.
If you wouldn't be using DI to do that instanciation, you might end up with using very little DI at the end.
As #zafeiris.m pointed out this is called Service Locator. And is also often called an anti pattern. Rightly so! Whenever you can achieve a better solution, you should. Here you probably can't. Suffice it to say it's better so stick with the best solution no matter what people call it.
There may be ways to cut down on the usage of service location. For example, if you have a business case, like "UpdateOrder(id)", and the method will create a service for that ID, then another service for that ID, then a logger for that ID,.. you may want to change it to creating an object which takes the ID as inheritable constructor argument and inject the ID-specific services and logger into that object, thus reducing the 3 factory/service locator calls to 1.

Getting an instance of a class that uses dependency injection

I've been reading about dependency injection, and I'm getting the basics. Most of the examples on the internet explain it till here:
public class MyClass
{
private IDependency _dependency;
public MyClass(IDependency dependency)
{
_dependency = dependency;
}
}
This way, we inject the dependency through the constructor. But I don't think it's a good idea to keep writing:
var myClassInstance = new MyClass(someArgument);
all throughout the code. Should I use the factory pattern to get instances?
public static class MyClassFactory
{
private static IDependency dependency = DependencyFactory.GetInstance();
public static MyClass GetInstance()
{
return new MyClass(dependency);
}
}
Is this the way to go?
I know that using a DI container solves the problem, but I'd like to learn how to incorporate dependency injection in my code, before using a DI container.
The dependency injection is just a pattern - you implement it on the first portion of code (constructor injection)
Now you can configure the dependency manually (as you did on the first example) or by using a framework which will help you (behind the scene it will do more or less the same thing).
The value of the pattern is not to avoid writing the below
var myClassInstance = new MyClass(dependencyObject);
but is to decouple layers of software that otherwise would be coupled
Yes, a factory would be the way to go. In fact, a DI container is really just a glorified factory that can be configured via xml (in the case of spring for example) or code (for something like structure map)

What's the best way to create unit tests for services that uses IoC.Resolve()

I'm using an IoC container instead of DI via constructor injection. Some may ask why I'm using IoC containers instead of constructor injection. Well for reasons stated here: Why do I need an IoC container as opposed to straightforward DI code?.
However, I'm finding it difficult to create unit tests for my services. I'm not sure how to mock the repositories used by my services during runtime since I'm not using constructor injection (a conundrum). Anyone have any solutions?
For example:
public class SomeService
{
private ISomeServiceRepository someServiceRepository;
public GetSomeThing()
{
//how do I mock this repository in my unit test
someServiceRepository = IoC.Resolve<ISomeServiceRepository>();
someData = someServiceRepository.getData();
someOtherService = new SomeOtherService();
someThing = someOtherService.GetSomeThing();
return FigureOutSomeThingElse(someData, someThing);
}
public FigureOutSomeThingElse(someData, someThing)
{
//do some figuring
return somethingElse;
}
}
public class SomeOtherService
{
private ISomeServiceRepository someOtherServiceRepository;
public GetSomeThing()
{
//how do I mock this repository in my unit test
someOtherServiceRepository = IoC.Resolve<ISomeOtherServiceRepository>();
var someData = someOtherServiceRepository.getData();
return someData;
}
}
You really should not be using IOC.Resolve inside of your class methods. It is very close to newing up your code anyway, which is part of what you are trying to avoid using DI. A better, and more testable way to write this would be something like this.
Public Class SomeService
{
ISomeServiceRepository someServiceRepository;
public SomeService(ISomeServiceRepository someServiceRepository)
{
this.someServiceRepository = someServiceRepository
}
Public GetSomeThing()
{
someData = someServiceRepository.getData();
...
}
}
By doing it this way, you can just mock your interface and inject it directly.
If you must use .Resolve, then Adam's approach is the best you can do
People can easily launch into a diatribe about how "you're doing it wrong" with resolve as needed, but I have experienced the pain of old code bases that cannot grok the register-resolve-release pattern altruistically. I would, however, advise against using a static container reference (as in IoC.) and try to make the container itself at least injected.
In this situation, you simply provide a test version of the IoC registration container, but instead of the normal app configuration you code a test configuration.
This won't be mocking or stubbing in any true sense and in fact these terms can confuse the solution quite a bit.
In essence it'll just be a different active configuration when in the unit tests. You'll still have to register types manually and you might have difficulty disabling the current configuration code if it is in the execution path of the unit tests.
We have a container that we resolve from as needed in an IoC pattern (for a handful of types), and for testing we simply created a new container (basically, one configuration for code and another for unit tests). Our use case was slightly different in that we injected the container into classes instead of having a static accessible type as in your case.
I got it, this is what I did...
(I'm using Unity.Net & RhinoMock)
Created a baseUnitTest class that implements the IContainerAccessor
Created and initialized a new instance of the UnityContainer in the constructor
Created a "UnityContainer" readonly public property which implements IContainerAccessor.Container
Created a unit test class that inherits baseUnitTest
Added the following code in a test method...
Mocker = New Rhino.Mocks.MockRepository()
SomeRepository = Mocker.DynamicMock(Of ISomeRepository)()
MyBase.UnityContainer.RegisterInstance(Of ISomeRepository)(SomeRepository)
Rhino.Mocks.Expect.Call(Of SomeResult)(SomeRepository.SomeMethod("someArg")).Return(New SomeResult())
Mocker.ReplayAll()
someService = New SomeService()
'this method uses IOC.Resolve(ISomeRepository) and calls the SomeRepository.SomeMethod
someResult = someService.someMethod()
Assert.IsNotNull(someResult)
Done

Categories