Jul 1, 2015 at 7:13 PM
Edited Jul 2, 2015 at 4:07 AM
That's a good question and I think a common question when first looking into dependency injection.
The general approach is to register the dependencies at application startup (bootstrap). Then in the
resolve the entire object graph.
So if your class (let's call it ServiceA) has a dependency on ClassA then ClassA should be injected into ServiceA in the composition root.
It is considered bad practice (or an anti-pattern) to reference the container inside the application code. The container should ideally be only referenced during bootstrapping and in the composition root.
IClassA iclassA = new ClassA(); // Ok to use container.Resolve<IClassA>() here?
So is it ok to use container to resolve ClassA instead of using "new" here?
No, you would not use the container to resolve ClassA here.
I don't see it makes sense to have IClassA injected in ctor when i might not need it if "someCondition" is false.
Is there a better way?
If you have a class that has many dependencies and you find that many of those dependencies are only used conditionally then that might be a sign that the class has too many responsibilities and that you should refactor the code into smaller classes with less
responsibility (Single responsibility principle
You're right though -- there are conditions where you don't know if you will need to use a dependency. There are 3 approaches I can think of:
1) Inject the dependency anyway
A common example of the first scenario would be injecting an ILogger for logging. You may only use the logger if there is an error but usually the ILogger would be injected anyway.
2) Inject a Func<>
If you were concerned about the cost of creating the dependency then you could inject a Func<> for lazy loading (a factory also works). Unity supports
which will inject a Func<T> if it can resolve T.
3) Inject a Factory
You could also create and inject your own Factory class that knows how to resolve the object you need. You might do this if there is some logic involved in creation. For example:
private IFileProcessorFactory fileProcessorFactory;
public void ProcessFile(FileInfo fileInfo)
IFileProcessor processor = this.fileProcessorFactory.Create(fileInfo);
Basically, we use the factory to get some processor that knows how to process the file based on the file type (e.g. one processor can handle a CSV, one can handle Excel, etc.). The factory class may also take advantage of Unity's automatic factories as in the
example in the previous link.
I think the
Developer's Guide to Dependency Injection Using Unity
is a good introduction to Unity and Dependency Injection.