views:

17

answers:

1

I have an object "TestProperty" which implements "ITestProperty". "TestProperty" takes a string constructor argument. This is configured in StructureMap using something along the lines CtorDependency or WithCtorArg.

I want to inject the an instance of "ITestProperty" (implemented with "TestProperty") into another class as a property. When I try to run the code I get an exception (StructureMap Error Code 205, "Missing requested Instance property").

Here's a simplified version that recreates the problem:

Test:

[Test]
public void Can_resolve_the_correct_property()
{
    ObjectFactory.Initialize( x => x.AddRegistry( new TestRegistry() ) );

    var instance = ObjectFactory.GetInstance<TestController>();
}

Registry Setup:

public class TestRegistry : Registry
{
    public TestRegistry()
    {
        ForRequestedType<ITestProperty>().AddInstances( 
            i => i.OfConcreteType<TestProperty>().WithName( "Test" )
                .CtorDependency<string>( "arg" ).Is( "abc" )
        );

        //ForConcreteType<TestProperty>().Configure
            .CtorDependency<string>( "arg" ).Is( "abc" );

        ForConcreteType<TestController>().Configure
            .SetterDependency( p => p.Property ).Is<TestProperty>()
            .WithName( "Test" );
    }
}

Test Objects:

public interface ITestProperty { }

public class TestProperty : ITestProperty
{
    private readonly string arg;

    public TestProperty( string arg )
    {
        this.arg = arg;
    }

    public string Arg { get { return arg; } }
}

public class TestController
{
    public ITestProperty Property { get; set; }
}

When we go to initialize the "TestController" object above the exception is thrown. Is it possible to do this with StructureMap? Assuming that it is possible, what do I need to do to get it working?

Thanks in advance.

+1  A: 

There are several ways to do this, as Josh mentioned if the named instance is important then you want this in your registry:

ForRequestedType<ITestProperty>().AddInstances(i => 
    i.OfConcreteType<TestProperty>().WithName("Test")
        .WithCtorArg("arg").EqualTo("abc"));

ForConcreteType<TestController>().Configure
    .SetterDependency(p => p.Property).Is(c => c
        .GetInstance<ITestProperty>("Test"));

Otherwise, you can do this:

ForRequestedType<ITestProperty>().TheDefault.Is
    .OfConcreteType<TestProperty>()
    .WithCtorArg("arg").EqualTo("abc");

ForConcreteType<TestController>().Configure
    .SetterDependency(p => p.Property).IsTheDefault();

Also, this is old StructureMap syntax, you might want to update to the latest version. Here is the new syntax:

For<ITestProperty>().Add<TestProperty>().Named("Test")
    .Ctor<string>("arg").Is("abc");

ForConcreteType<TestController>().Configure
    .Setter(p => p.Property).Is(c => c
        .GetInstance<ITestProperty>("Test"));
Robin Clowers
Thanks Robin. We had to upgrade and use option three but it worked perfectly. Cheers.
Zac