Reputation: 52922
Just trying to wrap my head around IoC at the moment, and I am part of the way there. An example I found on another post on SO was this:
http://blog.vascooliveira.com/unity-tutorial-and-examples/
The line I don't quite get is this:
ILogger myExampleInstance = myContainer.Resolve(loggerType);
I am not sure what loggerType is as it doesn't mention it anywhere.
I can see that IoC in this case allows us to create a way of writing a log. Rather than instantiate in the code a specific type of logger, we use IoC to create an ILogger interface, and we code to that. This means I assume that we don't care specifically what type of Logger is being used. If we don't care, I am curious to know why we need to pass in a loggerType, or how we know what the loggerType is due to seperation of concerns.
I am half way to understanding it but I just need a final push! =)
Upvotes: 0
Views: 837
Reputation: 33143
What you see there is actually an anti-pattern called Service Locator. The example code directly references the container, calling its Resolve() method.
In 99% of cases you should not ever reference your container within your code - there should only be a single application wide reference to the container at the very highest level of your code. (the final 1% of cases are almost exclusively where a framework you are using doesn't allow dependency injection)
In that single reference to your container you new up objects as needed with all their dependencies injected in a valid state. All your objects receive their dependencies as parameters (most often passing to the constructor).
There are lots of blog posts (here are two I found with some quick googling: Thou Shalt Not Reference The IoC Container and Service Locator Is An Anti Pattern around explaining the various reasons why ServiceLocator is bad.
You have found one example with your question about what loggerType should be, using proper IoC your application should not care - the Service Locator approach tends to mean your application starts to become aware of the details of its dependencies again, which goes against the entire point of using IoC and dependecy injection in the first place.
For further reading on IoC I'd suggest browsing through blog posts by Jeremy Miller, the creater of StructureMap. Don't take that as me saying use StructureMap instead of Unity, but since he wrote a container from scratch most of what he says on the subject is well thought out and he is a good writer.
Upvotes: 5
Reputation: 43698
While David Hall's answer is more correct, just to answer your question, loggerType
is the Type
of the logger. In reality, they probably could have done:
ILogger myExampleInstance = myContainer.Resolve(typeof(ILogger));
Or even better, use the generic extension method:
var myExampleInstance = myContainer.Resolve<ILogger>();
The Unity container will look into its list of known mappings, and see what type is mapped from ILogger
. It will then create a new instance, and return it.
As a more concise example:
IContainer container = ...;// get or create Unity container
container.RegisterType<ILogger, MyLogger>(); // tell Unity that when I ask for ILogger, I want a MyLogger back
ILogger logger = container.Resolve<ILogger>(); // logger is set to a new instance of MyLogger
I hope that helps!
Upvotes: 1
Reputation: 35895
It would be something like this
public class MyLogger : ILogger
{
//implementation
}
And then
Type loggerType = typeof(MyLogger);
ILogger myExampleInstance = myContainer.Resolve(loggerType);
output = myExampleInstance.MyInterfaceMethod("Unity rocks!");
The problem is, it is actually a ServiceLocator pattern. The DI and IoC would look like this:
public class Foo
{
private ILogger logger;
//This will be injected automatically by IoC
//once you register it somewhere in the app init e.g.
//container.RegisterType<ILogger, MyLogger>();
public Foo(ILogger logger)
{
this.logger = logger;
}
public void Bar()
{
logger.Debug("In the bar");
}
}
Upvotes: 3