views:

32

answers:

2

Hi

I have a requirement to use a plug in model where I need to allow types of ITask to be created by structuremap but where I only have a string of the type name at runtime. These types need to use Ctor injection to be composed, so I can't build up an existing type.

Also, I don't want to get all types and then query the type name as they could be expensive to construct.

Is there any built in functionality I am missing?

A: 

You can use ObjectFactory.GetNamedInstance<IPerson>("Customer");

The recommended approach is to hide this behind a Factory class:

public interface IPersonFactory
{
    IPerson GetPersonInstance(string name);
}

public class StructureMapPersonFactory : IPersonFactory
{
    public IPerson GetPersonInstance(string name)
    {
        return ObjectFactory.GetNamedInstance<IPerson>(name);
    }
}

Then you could do something like this:

public class SomethingThatNeedsNamedInstance
{
   IPersonFactory _factory;
   IPerson _personInstance;

   public SomethingThatNeedsNamedInstance(IPersonFactory factory)
   {
      this._factory = factory; // regular DI greedy constructor, setup in registry.
   }

   public void DoSomething()
   {
       this._personInstance = _factory.GetPersonInstance("Customer");
       _personInstance.CallSomeMethod();
   }
}
RPM1984
A: 

I haven't tried this, but maybe you could use Type.GetType, like...

var task = (ITask)ObjectFactory.GetInstance(Type.GetType("Assembly.Qualified.Name.Of.Type"));

This assumes you know the assembly/namespaces of the types.

see http://msdn.microsoft.com/en-us/library/w3f99sx1.aspx

Another possibility...

In your scanner add this

Scan(x =>
{
    x.AddAllTypesOf<ITask>();
}

Then, in some resolver class...

private Dictionary<string, Type> typeLookup;
public ITask GetInstance(string typeName)
{
    if (typeLookup == null)
    {
        typeLookup = new Dictionary<string, Type>();
        var tasks = ObjectFactory.GetAllInstances<ITask>();
        foreach (var task in tasks)
        {
            typeLookup.Add(task.GetType().Name, task.GetType());
        }

    }
    return (ITask)ObjectFactory.GetInstance(typeLookup[typeName]);
}
jayrdub
I ended up doing something similar, I queried the Model property and used link to get my tasks from there and then used Get to create the concrete implementation
Kev Hunter