views:

70

answers:

2

For a new project i am using the Windsor container to provide Dependency Injection (DI). DI should provide me with loose coupling and high testability. Since i am new to the subject of dependency injection i am having trouble wrapping my head around how to use it properly.

This is what i learned for articles and googling: You should have one instant of the container running which is created at startup. The dependency's of objects should be taken care of at object creation. Well so far so good.

Now for my situation. Inside my data layer, which is in a different project, my data classes rely on some form of logging which is set inside the constructor. But since it's inside a different project it cannot access the container.

The only solution that pops to mind is creation a singleton factory-like class where the container is injected into at startup. The singleton factory holds on the the container instance and project creation of data layer class instances like a traditional factory class would do, instead now with DI.

While this would seem like a good solution, reading some articles give me the feeling like i am missing something important, that there are other options to achieve the result i want (my data layer classes created with DI). So i could use come guidance. Source code examples would be awesome, but explanations or links to other resources would also help me out a great deal.

Thanks in advance!

+1  A: 

I wrote few blogposts recently that you might find useful.

Basically the idea is - you should not have to reference your container anywhere except for Global.asax

Krzysztof Koźmic
Nice articles, but there is still something that is not clear to me. I register the container in the global.asax. I registered the logger my data layer classes use inside the container. But when i create a new instance of a data layer class, i still need to provide my logger. How do i do this since i cannot reference the container directly? There must be some concept i am missing. Any help would be greatly appreciated.
The fact that your DAL class has a .ctor with ILogger argument is enough
Krzysztof Koźmic
This is only true if you call Container.Resolve<SomeDALClass>(); since i should not interact with the container directly that is not possible. But SomeDALClass class = new SomeDALClass(); doesn't work and/or compile. So im still doing something wrong in some places.
You call neither. Like I wrote in my post, you're not supposed to pull the dal class - have explicit dependency on it via constructor and the container will handle this for you.
Krzysztof Koźmic
First of all, thanks for the patience and help so far. But i have to create an instance of my classes somewhere. Maybe it would help i give a more specific example. I use NHibernate inside my DAL layer. My NHibernate repositories have a dependency on a logging component. Both are registered at the container. But is have to create an instance of my repository in code to query data from NHibernate. So i have to create instances of my repositories, but i can't since manually creating an instance requires my to supply the logging component. How do i go about doing this?
You don't. The class that uses the repository takes it as .ctor parameter, and the container will provide it with already created, configured instance, along with the logger.
Krzysztof Koźmic
You `Resole<RootClass>()` which would be your Controller most likely. Then the controller takes its dependencies as .ctor parameters, they take theirs, and so on, and someone in that graph is your repository. Is that clear?
Krzysztof Koźmic
It starts to make sense. You resolve the root root class causing a cascading effect till the entire object graph is resolved. Got it, thanks for that. So following the MvC convention resolving would start at at the controller creation, using the WindsorControllerFactory. Inside the WindsorControllerFactory Resolve<Controller> is used only at controller creation. at that stage the entire object graph is taken care of. Am i correct? If so i finally get it :D took a while so once again thanks for the patience and help!
Yes that's correct. That's what Inversion of Control is about - your classes don't know about the framework, the control is inverted - the framework controls your classes.
Krzysztof Koźmic
A: 

This post gives a good overview of setting up your ASP.NET MVC project to use Windsor to resolve your controller dependencies. As Krzsztof noted, you should only reference the container in Global.asax.

http://blog.andreloker.de/post/2009/03/28/ASPNET-MVC-with-Windsor-programmatic-controller-registration.aspx

Patrick Steele