Passing an object to constructor when using StructureMap 3

405 Views Asked by At

I have some UserControls in my c# project and use Structuremap 3 as my IoC container, when I want to access the UserControls I use following code:

var uc = new UserControlFactory().Create<MyUserControl>();
....

and this is UserControlFactory code:

public class UserControlFactory:IUserControlFactory
{
    public T Create<T>() where T : UserControl
    {
        return (T) ObjectFactory.GetInstance(typeof(T));
    }
}

It work fine when I have some interfaces as my UserControls constructor parameters:

public class MyUserControl:UserControl
{
    public MyUserControl(IMyInterface myInterface)
    {
    }
}

But now I want to pass an object through the UserControl constructor:

public class MyUserControl:UserControl
{
    public MyUserControl(IMyInterface myInterface,MyClass object1)
    {
    }
}

How can I do that?

3

There are 3 best solutions below

0
On

You could try to pass parameter to the constructor as follows:

public class UserControlFactory:IUserControlFactory
{
    public T Create<T>(MyClass object1) where T : UserControl
    {
        return (T) ObjectFactory.With("object1").EqualTo(object1).GetInstance(typeof(T));
    }
}
0
On

You should be able to resolve such type:

public class MyUserControl : UserControl
{
    public MyUserControl(IMyInterface myInterface, MyClass object1)
    {
    }
}

as StructureMap auto-wires concrete types (so you don't need to register MyUserControl and MyClass). All you need for this code to work is just to have IMyInterface registered:

c.For<IMyInterface>().Use<MyInterface>();

What error do you get when you try to resolve MyUserControl?

Side note

You can easily refactor this:

public class UserControlFactory : IUserControlFactory
{
    public T Create<T>() where T : UserControl
    {
        return (T) ObjectFactory.GetInstance(typeof(T));
    }
}

To use generic API provided:

public class UserControlFactory : IUserControlFactory
{
    public T Create<T>() where T : UserControl
    {
        return ObjectFactory.GetInstance<T>();
    }
}

Hope this helps.

0
On

You can configure StructureMap to know what to use for the constructor arguments like this:

            c.For<IFoo>().Use<Foo>().Ctor<Bar>(bar);

In your case, it would probably look more like this:

            var myClass = new MyClass();
            c.For<MyUserControl>().Use<MyUserControl>().Ctor<MyClass>(myClass);

This will use the same instance of MyClass for each MyUserControl, though. If you want greater control over what object gets used each time, then I'd go with ialekseev's answer.