How do you build an application around dependency injection?

Sep 22, 2008 at 5:13 PM

Hi,

I hear everyone talking about dependency injection and I think I even understand how to implement it.  What I don't get is how to build an application around it or why it is necessary.

So here is a very simple case

//Dependency is on the database.  Using constructor injection
public class form1{
    public form1(IDatabase database)
    {
        ...
    }
}

static class program
{

    [STAThread]
    static void Main()
    {
        UnityContainer container = new UnityContainer();
        container.RegisterType<IDatabase, myProj.Database>();
        IDatabase db = container.Resolve<IDatabase>();
        //or form1 form = container.Resolve<form1>();  doesn't really matter as far as my point is concerned

        Application.Run(new form1(db));
    }
}

So here is my issue.  All examples are like this which makes no sense because everytime I want an IDatabase, I have to create a unity container and then reference myProj.Database which is stupid because then I still have the dependency on myProj.Database spread throughout the program.  So then I thought that maybe container is supposed to be some global variable that all classes reference to resolve types.  Is that correct?

Finally, when I was making container a global var is some static class, I thought why not just include a GetDatabase() function in that static class and return a reference to IDatabase.  That then  bypasses the who DI framework.  I guess that would be sort of like a factory.  So, that is where I am.  I don't know how DI fits in terms of global variables.

 

Sep 24, 2008 at 1:50 PM
Hi noodle23,

I created a demo for you HERE and blog on the topic (to answer your questions).  I also was where you are at, not to long ago, and can't emphasize enough the importance of getting DI under your belt.  I think you'll see why when you review the link and demo app I wrote you.
Sep 24, 2008 at 6:38 PM
Hi bill,

Thanks so much for such a thorough explaination.  I downloaded the demo and it made sense.  The issue I had been having is why do this

container =

new UnityContainer()

 

 

// Register IFoo as a singleton

 

.RegisterType<

IFoo,Foo>(new ContainerControlledLifetimeManager());

 

 

// Instantiate IFoo and set optional suffix

 

 

IFoo myFoo = container.Resolve<IFoo>();

Because we still have the dependency on a specific definition of IFoo (Foo).  ie, I could have just as easily written IFoo myFoo = new Foo() (ignoring the singleton for the moment).  So the dependency was still there.  But then later on in your code I saw

 

container.Resolve<

A>().DoSomething();

And then realized that any dependency A had on IFoo now gets resolved to the proper definition.  perfect!


I have two more questions

1) Is the [Dependency] attribute required with unity?  If I used another framework, would something similar be required?  I think that the [Dependency] attribute is for setter injection and if I just use constructor injection, I don't have to worry about it. 
2) What about a global unity container variable?  This makes sense to me because then you could register all your dependencies in one spot rather than have to re-register in each constructor.  How do you handle creating unity containers in complex projects with lots of dependencies spread throughout

 

Sep 24, 2008 at 6:41 PM
for (2), I suppose I could also go with a static ConfigureContainer() function to register the dependencies and return a container but I'm not sure that is that much better.
Sep 24, 2008 at 7:39 PM
1.  No, I used the dependency attribute because it reduced the number of lines of code (for my blog); typically I'll use Injection Constructor.  I'm not familiar with any other frameworks - I was (am) a newbie with Unity

2.  You may find this Blog interesting :)  It also has a demo application.
Sep 25, 2008 at 4:05 PM
That was interesting.  I also found this http://msdn.microsoft.com/en-us/library/cc816062.aspx which has a good example.  They just used a global variable (well, a variable in a global dictionary) which is kind of what I want to do since it is simplier.