1

I have some legacy code that is creating instances of classes.

I have managed to wire up an IOC container to scan assemblies and create instances of them. However, I have spotted that in a configuation class specific classes may be created numerous times.

The logic basically loops over an array of class types and if it matches the one a user selected it calls CreateInstance.

This is fine but the only way I can think to provide that functionality is to pass the IOC Container around and call Resolve which will provide a new instance of the class.

I know this is seriously frowned upon but I can't think how to make it work.

M.Babcock
  • 18,753
  • 6
  • 54
  • 84
Jon
  • 38,814
  • 81
  • 233
  • 382
  • Is there a reason why you can't use the constructor injection pattern for these dependencies? – Dervall Feb 06 '12 at 14:21
  • There is about 50 class types, these are plugins. A user can drag a plugin onto their screen and when they do a new instance needs creating – Jon Feb 06 '12 at 14:23
  • Since you are working with legacy code, using a DI Container for this purpose may be a reasonable first step. However, it's not where you'd want to end. – Mark Seemann Feb 06 '12 at 15:27
  • Agreed which is why I'm trying to find an alternative but I may have to resort to it – Jon Feb 06 '12 at 16:05

1 Answers1

1

Create an abstract factory which provides a layer of abstraction between the IOC container and the code requiring the new instances, this will avoid the code being littered with container dependent calls.

For example, when using the 'Unity Application Block', Func<T> can be used as a factory. This Func<T> then hides the container implementation which is actually container.Resolve<T>().

Update

Here is an example:

public class TestClass
{
    readonly Func<Foo> _fooFactory;

    public TestClass(Func<Foo> fooFactory)
    {
        _fooFactory = fooFactory;
    }

    public void LoadFoo()
    {
        var foo = _fooFactory(); // This hides the call container.Resolve<Foo>()
        // Do something with foo
    }
}
Lukazoid
  • 19,016
  • 3
  • 62
  • 85
  • From reading around, I believe Autofac is capable of this exact same functionality. See [here](http://stackoverflow.com/questions/4840157/does-ninject-support-func-auto-generated-factory) – Lukazoid Feb 06 '12 at 14:51
  • Yup reading the documentation but I'm just seeing blah, blah, blah :) – Jon Feb 06 '12 at 14:53
  • AutoFac will automatically create the `Func` and the call to `Resolve` itself, you do not need to deal with it. Simply list a `Func` as a dependency, where `T` is the type you want to create and AutoFac will inject a factory which calls `Resolve` itself. – Lukazoid Feb 06 '12 at 15:01
  • Unfortunately I have found I cannot do it with constructor parameters and trying to use properties doesn't work – Jon Feb 06 '12 at 15:24
  • Can I do it so T is base class. I have many dependencies that inherit off a PluginBase – Jon Feb 06 '12 at 15:31
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/7391/discussion-between-jon-and-lukazoid) – Jon Feb 06 '12 at 15:39