Related
I'm sorry if that question was already discussed, but I didn't find exactely what I wanted. The problem I'm facing is more about patterns and design choices than about .NET itself. I just would like to have your advice to know where to start my refactorings.
Today I opend one of the classes in my actual application and found that it has 13 dependencies injected by constructor !!! In fact each developper added the dependecy it needed in method that he was writing.
One point of my understanding of DI is that when we inject a dependency by constructor it means that it's a mandatory dependency and should be used in all methods of the class. If we need a particular dependency just in one method of the given class, what does it mean for you ?
The given class does too much ? I should consider to create a new type just with a needed dependency ?
I should inject by property ? But in that particular method a dependency is mandatory so I don't think it's a good choice.
I should inject by method ?
What's difficult is to find the right balance. In reallity sometimes it's not possible to encapsulate the bahaviour in the clean way.
I was considering to create something like service aggregator to hind related dependency behind one of them but would like if you have other advices. Thanks in advance.
You are correct: if you need to inject 13 dependencies into a class, it's a pretty sure sign that you are violating the Single Responsibility Principle. Switching to Property Injection will not help, as it will not decrease the number of dependencies - it will only imply that those dependencies are optional instead of mandatory.
Basically, there are two ways to deal with this type of problem:
Refactor to Facade Services. This is basically a non-breaking refactoring as it maintains the functionality of the Controller. However, it changes the responsibility toward coordinating/orchestrating the interaction between services instead of managing the nitty-gritty details of the implementation.
Split up the class into independent classes. If each of the services were introduced by different developers to support a subset of the methods, it's a sign of low cohesion. In this case, it would be better to split up the class into several independent classes.
Specifically for ASP.NET MVC you may not want to split up an Controller because it will change your URL scheme. That's fair enough, but consider what this implies: it means that the single responsibility of the Controller should be to map URLs to application code. In other words, that's all a Controller should do, and it then follows that the correct solution is to refactor to Facade Services.
Just because a dependency is mandatory doesn't mean it should be used in all the methods of a class, IMO. It should just be logically part of the configuration of the class itself.
On the other hand, if a class has 13 dependencies it may well be doing too much. Do any of those dependencies logically belong together? Perhaps the dependencies themselves should be "chunkier" - or quite possibly your class should do less.
This sounds like a case of a class having too many dependencies i.e. it's a God class. Try and break it down into more discrete responsibilities.
If your class has 13 dependencies you definitely have a problem. Clearly your class serves too many responsibilities. Marc Seemann has discussed this problem in his book "Dependency injection in .NET" paragraph 6.4. If your class starts to have 3 parameters in the constructor you must start to wonder. Is my class still serving one responsibility? If you start to have 4 or more parameters in your constructor refactor your class by start using the facade or composition pattern.
Its just the way DI works. Its a fact. So accept it. Its fully legit in a service like a Pdf Service, Look at this code:
public PdfService(ILocalizationService localizationService,
ILanguageService languageService,
IWorkContext workContext,
IOrderService orderService,
IPaymentService paymentService,
IDateTimeHelper dateTimeHelper,
IPriceFormatter priceFormatter,
ICurrencyService currencyService,
IMeasureService measureService,
IPictureService pictureService,
IProductService productService,
IProductAttributeParser productAttributeParser,
IStoreService storeService,
IStoreContext storeContext,
ISettingService settingContext,
IAddressAttributeFormatter addressAttributeFormatter,
CatalogSettings catalogSettings,
CurrencySettings currencySettings,
MeasureSettings measureSettings,
PdfSettings pdfSettings,
TaxSettings taxSettings,
AddressSettings addressSettings)
I have ended up with a constructor that looks like this whilst attempting to end up with an object i can easily test.
public UserProvider(
IFactory<IContainer> containerFactory,
IRepositoryFactory<IUserRepository> userRepositoryFactory,
IFactory<IRoleProvider> roleProviderFactory,
IFactory<IAuthenticationProvider> authenticationProviderFactory,
IFactory<IEmailAdapter> emailAdapterFactory,
IFactory<IGuidAdapter> guidAdapterFactory,
IRepositoryFactory<IVehicleRepository> vehicleRepositoryFactory,
IRepositoryFactory<IUserVehicleRepository> userVehicleRepositoryFactory,
IFactory<IDateTimeAdapter> dateTimeAdapterFactory)
This is all the dependencies the object will have and is the busiest constructor i have. But if someone saw this would it really raise a big wtf?
My aim was to end up with logic that is easy to test. Whilst it requires a good amount of mocks it is certainly very easy to verify my logic. However i am concerned that I may of ended up with too much of a good thing.
I am curious if this is normal for most people implementing ioc.
There are several simplifications I can make - such as I don't really need to pass in the factories for several of the adapters as i could just pass the adapter in directly as it has no internal state. But I am really asking in terms of the number of parameters.
Or more to the point i am looking for assurance that I am not going overboard ;)
But I am beginnign to get the impression that the UserProvider class should be broken down a bit - but then I end up with even more plumbing which is what is driving this concern.
I guess a sub question is maybe should I be considering using a service Locator pattern if I have these concerns?
When using DI and constructor injection violation of the SRP becomes very visible. This is acutally a good thing, and it is not DI / IOC's fault. If you were not using constructor injection, the class would have the same dependencies, it would just not be as visible.
What you could do in your concrete example is hide some of the related dependencies behind facades. For example IVehicleRepository and IUserVehicleRepository could be hidden behind an IVehicle facade. It might also make sense to put IUserRepository, IRoleProvider and IAuthenticationProvider behind a facade.
In my opinion that is a lot of parameters for a constructor. Here's how I would handle this to get good testability and reduce "code smell."
Instead of passing in the factories to create instances of your classes just pass in the classes themselves. This automatically cuts your dependencies in half because the UserProvider would not be concerned with creating any objects that it needs (and subsequently disposing of them if necessary) it would just use what is given to it instead of using the factories that it needs to create object instances that it needs.
Remove your adapters from the constructor and just create instances of these interfaces inside of the UserProvider. Think about how often are you going to need to change the way you format a guid for example. This would still be testable as long as your adapters don't have a lot of dependencies.
The point I'm making is to get a good balance of testability and practicality. When implementing Ioc try and determine where you've had trouble with testability in the past and where you've had issues maintaining and changing code because there were too many dependencies. That is where you'll see the most benefit.
I don't know if this actually qualifies as DI, since I'm not talking about injecting a concrete implementation of an abstract dependency. I'm just talking about injecting stuff that's needed period.
In my game engine, I want to clean up the part that handles the state of the game (menu, stage select, in-game, cutscenes, etc). All of these things implement a common interface. But one of them, in-game, is also referenced specifically as the current level being played.
There are right now 43 references in my project to the current level, as accessed through the game, a singleton. For example, Game.CurrentGame.CurrentMap.Something. The references are in screens, entities, behavior components, even in the main form (for debugging tools).
I want to get rid of this reference by injecting everything that's needed. But the CurrentMap itself isn't the desired dependency - other things are being accessed below it. So my initial plan is to go into each place, find the thing that's actually being used, and inject it by adding a parameter to that class constructor. This introduces another dependency one level up, so I repeat the process until everything is finished. But the problem with this is it will introduce a lot more constructor parameters, including in places that aren't using the dependency directly. A lot of classes will wind up accepting a dependency just so they can pass it on to another object below them.
What would be a cleaner alternative to this?
You are talking about a scenario where the dependencies must make their way down through a few layers of objects to get where they are really needed. This does not need to happen.
If an object creates dependencies itself you end up with this problem. If objects are given the dependencies it needs by a factory or DI container (which is just a fancy factory) then you will not have this problem. So to avoid this problem, you need to decide if each class is concerned with game logic or creating classes.
Let's say you have object a, which calls object b, which calls object c and object c needs the current level and object b does not.
The wrong way to do it is to call new C(level); from within b. As you have pointed out, b does not need to know about the level so it seems things are getting worse not better. You have not gone far enough with the dependency injection. Instead of creating c within b, just ask for c in the constructor of b. Now class b only knows about c and knows nothing about level.
Misko has explained this better than I can here http://misko.hevery.com/2009/03/30/collaborator-vs-the-factory/
Code in the factory looks like this:
Level level = new Level();
C c = new C( level );
B b = new B( c );
A a = new A( b );
The class B only knows about it's direct collaborators (c) and has no dependency on Level. Because we are creating things in the factory, it is not necessary to pass the leaves of the object graph down through the object graph.
If class B had the responsibility for creating c then it needs to know all about how to make an instance of class c. This is wrong.
Look at using a DI Framework, like Castle Windsor, Structuremap or Unity (there are plenty of others that are perfectly solid as well).
The problem you are describing is not the only problem that these frameworks solve, but it's a big part of the type of friction that they almost completely eliminate.
The fact that the dependencies are concrete implementations and not higher level abstractions is irrelevant. See this question (asked by yours truly):
IOC/DI: Is Registering a Concrete Type a Code Smell?
Usually I inject a service that keeps track of the current state:
public interface IGameStateTracker
{
Game CurrentGame {get;}
GameMap CurrentMap {get;}
}
You should only have to inject this service in constructors of classes that will need it directly. I'm afraid I don't fully understand why you're finding that you need to inject things into classes that don't directly need it: this may be a sign that you're not using proper DI patterns. Could you provide some code samples to show an example of this problem?
I second Phil Sandler's point about using a DI framework. It will make life much easier. But it won't make up for using incorrect DI patterns in the first place.
I've been using IoC (mostly Unity) and Dependency Injection in .NET for some time now and I really like the pattern as a way to encourage creation of software classes with loose coupling and which should be easier to isolate for testing.
The approach I generally try to stick to is "Nikola's Five Laws of IoC" - in particular not injecting the container itself and only using constructor injection so that you can clearly see all the dependencies of a class from its constructor signature. Nikola does have an account on here but I'm not sure if he is still active.
Anyway, when I end up either violating one of the other laws or generally ending up with something that doesn't feel or look right, I have to question whether I'm missing something, could do it better, or simply shouldn't be using IoC for certain cases. With that in mind here are a few examples of this and I'd be grateful for any pointers or further discussion on these:
Classes with too many dependencies. ("Any class having more then 3 dependencies should be questioned for SRP violation"). I know this one comes up a lot in dependency injection questions but after reading these I still don't have any Eureka moment that solves my problems:
a) In a large application I invariably find I need 3 dependencies just to access infrastructure (examples - logging, configuration, persistence) before I get to the specific dependencies needed for the class to get its (hopefully single responsibility) job done. I'm aware of the approach that would refactor and wrap such groups of dependencies into a single one, but I often find this becomes simply a facade for several other services rather than having any true responsibility of its own. Can certain infrastructure dependencies be ignored in the context of this rule, provided the class is deemed to still have a single responsibility?
b) Refactoring can add to this problem. Consider the fairly common task of breaking apart a class that has become a bit big - you move one area of functionality into a new class and the first class becomes dependent on it. Assuming the first class still needs all the dependencies it had before, it now has one extra dependency. In this case I probably don't mind that this dependency is more tightly coupled, but its still neater to have the container provide it (as oppose to using new ...()), which it can do even without the new dependency having its own interface.
c) In a one specific example I have a class responsible for running various different functions through the system every few minutes. As all the functions rightly belong in different areas, this class ends up with many dependencies just to be able to execute each function. I'm guessing in this case other approaches, possibly involving events, should be considered but so far I haven't tried to do it because I want to co-ordinate the order the tasks are run and in some cases apply logic involving outcomes along the way.
Once I'm using IoC within an application it seems like almost every class I create that is used by another class ends up being registered in and/or injected by the container. Is this the expected outcome or should some classes have nothing to do with IoC? The alternative of just having something new'd up within the code just looks like a code smell since its then tightly coupled. This is kind of related to 1b above too.
I have all my container initialisation done at application startup, registering types for each interface in the system. Some are deliberately single instance lifecycles where others can be new instance each time they are resolved. However, since the latter are dependencies of the former, in practice they become a single instance too since they are only resolved once - at construction time of the single instance. In many cases this doesn't matter, but in some cases I really want a different instance each time I do an operation, so rather than be able to make use of the built in container functionality, I'm forced to either i) have a factory dependency instead so I can force this behaviour or ii) pass in the container so I can resolve each time. Both of these approaches are frowned upon in Nikola's guidance but I see i) as the lesser of two evils and I do use it in some cases.
In a large application I invariably find I need 3 dependencies just to access infrastructure (examples - logging, configuration, persistence)
imho infrastructure is not dependencies. I have no problem using a servicelocator for getting a logger (private ILogger _logger = LogManager.GetLogger()).
However, persistence is not infrastructure in my point of view. It's a dependency. Break your class into smaller parts.
Refactoring can add to this problem.
Of course. You will get more dependencies until you have successfully refactored all classes. Just hang in there and continue refactoring.
Do create interfaces in a separate project (Separated interface pattern) instead of adding dependencies to classes.
In a one specific example I have a class responsible for running various different functions through the system every few minutes. As all the functions rightly belong in different areas, this class ends up with many dependencies just to be able to execute each function.
Then you are taking the wrong approach. The task runner should not have a dependency on all tasks that should run, it should be the other way around. All tasks should register in the runner.
Once I'm using IoC within an application it seems like almost every class I create that is used by another class ends up being registered in and/or injected by the container.*
I register everything but business objects, DTOs etc in my container.
I have all my container initialisation done at application startup, registering types for each interface in the system. Some are deliberately single instance lifecycles where others can be new instance each time they are resolved. However, since the latter are dependencies of the former, in practice they become a single instance too since they are only resolved once - at construction time of the single instance.
Don't mix lifetimes if you can avoid it. Or don't take in short lived dependencies. In this case you could use a simple messaging solution to update the single instances.
You might want to read my guidelines.
Let me answer question 3. Having a singletons depend on a transient is a problem that container profilers try to detect and warn about. Services should only depend on other services that have a lifetime that is greater than or equals to that of their own. Injecting a factory interface or delegate to solve this is in general a good solution, and passing in the container itself is a bad solution, since you end up with the Service Locator anti-pattern.
Instead of injecting a factory, you can solve this by implementing a proxy. Here's an example:
public interface ITransientDependency
{
void SomeAction();
}
public class Implementation : ITransientDependency
{
public SomeAction() { ... }
}
Using this definition, you can define a proxy class in the Composition Root based on the ITransientDependency:
public class TransientDependencyProxy<T> : ITransientDependency
where T : ITransientDependency
{
private readonly UnityContainer container;
public TransientDependencyProxy(UnityContainer container)
{
this.container = container;
}
public SomeAction()
{
this.container.Resolve<T>().SomeAction();
}
}
Now you can register this TransientDependencyProxy<T> as singleton:
container.RegisterType<ITransientDependency,
TransientDependencyProxy<Implementation>>(
new ContainerControlledLifetimeManager());
While it is registered as singleton, it will still act as a transient, since it will forward its calls to a transient implementation.
This way you can completely hide that the ITransientDependency needs to be a transient from the rest of the application.
If you need this behavior for many different service types, it will get cumbersome to define proxies for each and everyone of them. In that case you could try Unity's interception functionality. You can define a single interceptor that allows you to do this for a wide range of service types.
I use dependency injection through parameters and constructors extensively. I understand the principle to this degree and am happy with it. On my large projects, I end up with too many dependencies being injected (anything hitting double figures feels to big - I like the term 'macaroni code').
As such, I have been considering IOC containers. I have read a few articles on them and so far I have failed to see the benefit. I can see how it assists in sending groups of related objects or in getting the same type over and over again. I'm not sure how they would help me in my projects where I may have over a hundred classes implementing the same interface, and where I use all of them in varying orders.
So, can anybody point me at some good articles that not only describe the concepts of IOC containers (preferably without hyping one in particular), but also show in detail how they benefit me in this type of project and how they fit into the scope of a large architecture?
I would hope to see some non-language specific stuff but my preferred language if necessary is C#.
Inversion of Control is primarily about dependency management and providing testable code. From a classic approach, if a class has a dependency, the natural tendency is to give the class that has the dependency direct control over managing its dependencies. This usually means the class that has the dependency will 'new' up its dependencies within a constructor or on demand in its methods.
Inversion of Control is just that...it inverts what creates dependencies, externalizing that process and injecting them into the class that has the dependency. Usually, the entity that creates the dependencies is what we call an IoC container, which is responsible for not only creating and injecting dependencies, but also managing their lifetimes, determining their lifestyle (more on this in a sec), and also offering a variety of other capabilities. (This is based on Castle MicroKernel/Windsor, which is my IoC container of choice...its solidly written, very functional, and extensible. Other IoC containers exist that are simpler if you have simpler needs, like Ninject, Microsoft Unity, and Spring.NET.)
Consider that you have an internal application that can be used either in a local context or a remote context. Depending on some detectable factors, your application may need to load up "local" implementations of your services, and in other cases it may need to load up "remote" implementations of your services. If you follow the classic approach, and create your dependencies directly within the class that has those dependencies, then that class will be forced to break two very important rules about software development: Separation of Concerns and Single Responsibility. You cross boundaries of concern because your class is now concerned about both its intrinsic purpose, as well as the concern of determining which dependencies it should create and how. The class is also now responsible for many things, rather than a single thing, and has many reasons to change: its intrinsic purpose changes, the creation process for its dependencies changes, the way it finds remote dependencies changes, what dependencies its dependencies may need, etc.
By inverting your dependency management, you can improve your system architecture and maintain SoC and SR (or, possibly, achieve it when you were previously unable to due to dependencies.) Since an external entity, the IoC container, now controls how your dependencies are created and injected, you can also gain additional capabilities. The container can manage the life cycles of your dependencies, creating and destroying them in more flexible ways that can improve efficiency. You also gain the ability to manage the life styles of your objects. If you have a type of dependency that is created, used, and returned on a very frequent basis, but which have little or no state (say, factories), you can give them a pooled lifestyle, which will tell the container to automatically create an object pool for that particular dependency type. Many lifestyles exist, and a container like Castle Windsor will usually give you the ability to create your own.
The better IoC containers, like Castle Windsor, also provide a lot of extendability. By default, Windsor allows you to create instances of local types. Its possible to create Facilities that extend Windsor's type creation capabilities to dynamically create web service proxies and WCF service hosts on the fly, at runtime, eliminating the need to create them manually or statically with tools like svcutil (this is something I did myself just recently.) Many facilities exist to bring IoC support existing frameworks, like NHibernate, ActiveRecord, etc.
Finally, IoC enforces a style of coding that ensures unit testable code. One of the key factors in making code unit testable is externalizing dependency management. Without the ability to provide alternative (mocked, stubbed, etc.) dependencies, testing a single "unit" of code in isolation is a very difficult task, leaving integration testing the only alternative style of automated testing. Since IoC requires that your classes accept dependencies via injection (by constructor, property, or method), each class is usually, if not always, reduced to a single responsibility of properly separated concern, and fully mockable dependencies.
IoC = better architecture, greater cohesion, improved separation of concerns, classes that are easier to reduce to a single responsibility, easily configurable and interchangeable dependencies (often without requiring a recompilation of your code), flexible dependency life styles and life time management, and unit testable code. IoC is kind of a lifestyle...a philosophy, an approach to solving common problems and meeting critical best practices like SoC and SR.
Even (or rather, particularly) with hundreds of different implementations of a single interface, IoC has a lot to offer. It might take a while to get your head fully wrapped around it, but once you fully understand what IoC is and what it can do for you, you'll never want to do things any other way (except perhaps embedded systems development...)
If you have over a hundred of classes implementing a common interface, an IoC won't help very much, you need a factory.
That way, you may do the following:
public interface IMyInterface{
//...
}
public class Factory{
public static IMyInterface GetObject(string param){
// param is a parameter that will help the Factory decide what object to return
// (that is only an example, there may not be any parameter at all)
}
}
//...
// You do not depend on a particular implementation here
IMyInterface obj = Factory.GetObject("some param");
Inside the factory, you may use an IoC Container to retrieve the objects if you like, but you'll have to register each one of the classes that implement the given interface and associate them to some keys (and use those keys as parameters in GetObject() method).
An IoC is particularly useful when you have to retrieve objects that implement different interfaces:
IMyInteface myObject = Container.GetObject<IMyInterface>();
IMyOtherInterface myOtherObject Container.GetObject<IMyOtherInterface>();
ISomeOtherInterface someOtherObject = Container.GetObject<ISomeOtherInterface>();
See? Only one object to get several different type objects and no keys (the intefaces themselves are the keys). If you need an object to get several different object, but all implementing the same interface, an IoC won't help you very much.
In the past few weeks, I've taken the plunge from dependency-injection only to full-on inversion of control with Castle, so I understand where your question is coming from.
Some reasons why I wouldn't want to use an IOC container:
It's a small project that isn't going to grow that much. If there's a 1:1 relationship between constructors and calls to those constructors, using an IOC container isn't going to reduce the amount of code I have to write. You're not violating "don't repeat yourself" until you're finding yourself copying and pasting the exact same "var myObject = new MyClass(someInjectedDependency)" for a second time.
I may have to adapt existing code to facilitate being loaded into IOC containers. This probably isn't necessary until you get into some of the cooler Aspect-oriented programming features, but if you've forgotten to make a method virtual, sealed off that method's class, and it doesn't implement an interface, and you're uncomfortable making those changes because of existing dependencies, then making the switch isn't quite as appealing.
It adds an additional external dependency to my project -- and to my team. I can convince the rest of my team that structuring their code to allow DI is swell, but I'm currently the only one that knows how to work with Castle. On smaller, less complicated projects, this isn't going to be an issue. For the larger projects (that, ironically, would reap the most benefit from IOC containers), if I can't evangelize using an IOC container well enough, going maverick on my team isn't going to help anybody.
Some of the reasons why I wouldn't want to go back to plain DI:
I can add or take away logging to any number of my classes, without adding any sort of trace or logging statement. Having the ability for my classes to become interwoven with additional functionality without changing those classes, is extremely powerful. For example:
Logging: http://ayende.com/Blog/archive/2008/07/31/Logging--the-AOP-way.aspx
Transactions: http://www.codeproject.com/KB/architecture/introducingcastle.aspx (skip down to the Transaction section)
Castle, at least, is so helpful when wiring up classes to dependencies, that it would be painful to go back.
For example, missing a dependency with Castle:
"Can't create component 'MyClass' as
it has dependencies to be satisfied.
Service is waiting for the following
dependencies:
Services:
- IMyService which was not registered."
Missing a dependency without Castle:
Object reference is not set to an
instance of an object
Dead Last: The ability to swap injected services at runtime, by editing an Xml File. My perception is that this is the most tauted feature, but I see it as merely icing on the cake. I'd rather wire up all my services in code, but I'm sure I'll run into a headache in the future where my mind will be changed on this.
I will admit that -- being a newbie to IOC and Castle -- I'm probably only scratching the surface, but so far, I genuinely like what I see. I feel like the last few projects I've built with it are genuinely capable of reacting to the unpredictable changes that arise from day to day at my company, a feeling I've never quite had before.
Try these:
http://www.martinfowler.com/articles/injection.html
http://msdn.microsoft.com/en-us/library/aa973811.aspx
I have no links but can provide you with an example:
You have a web controller that needs to call a service which has a data access layer.
Now, I take it in your code you are constructing these objects your self at compile time. You are using a decent design pattern, but if you ever need to change the implementation of say the dao, you have to go into you code and remove the code that sets this dependency up, recompile / test/ deploy. But if you were to use a IOC container you would just change the class in the configuration and restart the application.
Jeremy Frey misses one of the biggest reasons for using an IOC container: it makes your code easier to mock and test.
Encouraging the use of interfaces has lots of other nice benefits: better layering, easier to dynamically generate proxies for things like declarative transactions, aspect-oriented programming and remoting.
If you think IOC is only good for replacing calls to "new", you don't get it.
IoC containers usually do the dependency injections which in some projects are not a big deal , but some of the frameworks that provide IoC containers offer other services that make it worth to use them.
Castle for example has a complete list of services besides an IoC container.Dynamic proxies ,Transaction management and NHibernate facilities are some of them.
Then I think you should consider IoC contianers as a part of an application framework.
Here's why I use an IoC container:
1.Writing unit tests will be easier .Actually you write different configurations to do different things
2.Adding different plugins for different scenarios(for different customers for example)
3.Intercepting classes to add different aspects to our code.
4.Since we are using NHibernate ,Transaction management and NHibernate facilites of Castle are very helpful in developing and maintaining our code .
It's like every technical aspects of our application is handled using an application framework and we have time to think about what customers really want.