views:

340

answers:

3

I'm new to the world of IoC and having a problem with implementing it in a Winforms application. I have an extremely basic application Winform application that uses MVC, it is one controller that does all the work and a working dialog (obviously with a controller). So I load all my classes in to my IoC container in program.cs and create the main form controller using the container. But this is where I am having problems, I only want to create the working dialog controller when it's used and inside a using statement.

At first I passed in the container but I've read this is bad practice and more over the container is a static and I want to unit test this class.

So how do you create classes in a unit test friendly way without passing in the container, I was considering the abstract factory pattern but that alone would solve my problem without using the IoC.

I'm not using any famous framework, I borrowed a basic one from this blog post http://www.kenegozi.com/Blog/2008/01/17/its-my-turn-to-build-an-ioc-container-in-15-minutes-and-33-lines.aspx

How do I do this with IoC? Is this the wrong use for IoC?

A: 

I generally just pass in an interface to a factory class.

TrueWill
I thought about that but doesn't that remove the need for IoC altogether
L2Type
@L2Type: IoC/DI doesn't require a container library - this is IoC. When you have classes with multiple dependencies that themselves have dependencies, though, you'll appreciate the wiring-up that the container library buys you.
TrueWill
A: 

The only reasonable solution I came around with is making your container Singleton. Some of the IoC frameworks do that for you, but you might have to roll out your own implementation of Singleton. Have a look at Jon Skeet's ideas.

Good luck with MVC in Winforms. It is a steep learning curve, that I am only beginning to ascend on.

Tomas Pajonk
I've tried to implement MVC in WinForms before at work but we ended up with a hybrid solution that is not quite MVC and quite anything really. It is one uphill struggle.
L2Type
One of the benefits of an IoC container is getting rid of Singletons. Lifetime management is handled by the container. If you make the container a Singleton, you couple all your classes to the container and can no longer see a class's dependencies at a glance.
TrueWill
I am not quite sure how I can't see my class dependencies ? I find it extremely hard to not have a single singleton in the app :) I know one must use singleton's wisely, but I feel that it is justifiable in some cases such as winforms app (and even moderate complexity ones.)do you think there is an another options apart from passion the container everywhere and polluting your code by it and having a singleton container ?
Tomas Pajonk
Tomas, check out Autofac's "generated factories", Castle's "TypedFactory facility" or MEF's "PartCreator<T>", all solutions to this problem that avoid static/singleton container references.
Nicholas Blumhardt
@Nicholas Blumhart Thanks. I am using Ninject now, but I will look at the ideas.
Tomas Pajonk
+4  A: 

Ken's post is very interesting, but you're at the point where it is worth learning more about the "production" IoC containers, as a few now support this scenario.

In Autofac for example, you can 'generate' a factory as a delegate:

builder.RegisterGeneratedFactory<Func<IDialogController>>();

Then in your main form:

class MainForm ... {

  Func<IDialogController> _controllerFactory;

  public MainForm(Func<IDialogController> controllerFactory) { ... }

  void ShowDialog() {
    using (var controller = _controllerFactory())
    {
    }
  }

Autofac will fill in the controllerFactory constructor parameter at runtime. In your unit tests you can easily provide a lambda to the constructor instead.

Nicholas Blumhardt