views:

313

answers:

0

Dear all,

I am trying to use StructureMap ExplictArguments class to pass them on runtime and based on them, I want that structure map concludes which constructor should be launched. My test scenario is:

    public class SpecialClass : ISpecialClass //this is test class, has two constructors
{
    public SpecialClass()
    {
    }

    public SpecialClass(SpecialClass parent)
    {
        Value = 1;
    }

    public SpecialClass(SpecialClass parent, SpecialClass child)
    {
        Value = 2;
    }

    public int Value
    {
        get;
        set;
    }
}

Below is the way how I am currently configuring StructureMap:

Registry.ForRequestedType<ISpecialClass>().TheDefaultIsConcreteType<SpecialClass>();

Now I am using this method to pass my arguments to the container factory:

        public I GetInstance<I>(object parameters)
    {

        return _container.GetInstance<I>(GetExplictArgumentsFromParameters(parameters));
    }



    ExplicitArguments GetExplictArgumentsFromParameters(object parameters)
    {
        Type myType = parameters.GetType();
        Dictionary<string, object> values = new Dictionary<string, object>();
        BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
        foreach (var member in myType.GetFields(flags))
        {
            values.Add(GetName(member.Name), member.GetValue(parameters));
        }
        return new ExplicitArguments(values);
    }

    string GetName(string name)
    {
        string[] result = name.Split('<', '>');
        return result[1];
    }

And this is how my full code looks in the test case:

            var test1 =_container.GetInstance<ISpecialClass>(new {parent = new SpecialClass()});
        Assert.AreEqual(test1.Value,1);

        var test2 = _container.GetInstance<ISpecialClass>(new { parent = new SpecialClass(), child = new SpecialClass() });
        Assert.AreEqual(test2.Value, 2);

Please note, that _container is an Interface that behind is implementing the StructureMap GetInstance with Explict Arguments method.

The code above is working when I pass two arguments. When I pass one, I get key not found exception. I have tried to define default constructor even using attribute but then this one will be always used (even I pass more arguments, it will try to use this default one).

My goal is simple - I want to use IoC to construct my objects when I request for them using the Interface type, and pass to the CreateInstance method my arguments. This way my implementation class (SpecialClass) based on the arguments, can initialize itself in different way. Passing constructor arguments on runtime is crucial in my solution (at least someone will propose better one :) )

Thank you all for support!