tags:

views:

43

answers:

2

I'm new to structure map and so far having good luck. However, there's one area I'm having a bit of a problem with. This is trying to auto-wireup using named instances and the newer .For().Use() syntax.

No matter what I do, I'm getting the LAST item I've configured for a given type when I'm trying to auto-wire to create a new object. I can get the correct item using named instances without a problem when I'm just trying to get that type from the container.

For simplicity's sake, below shows ObjectFactory, but my real code is using an IContainer. Both have same result for me.

//arrange
    var expectedGreen = "Green";
    var notExpectedBlue = "Blue";
    var greenInstance = new Mock<ITestClass>();
    greenInstance.SetupGet(m => m.Data).Returns(expectedGreen);
    ObjectFactory.Configure(x => x.For<ITestClass>().Use(greenInstance.Object).Named("Green"));

    var blueInstance = new Mock<ITestClass>();
    blueInstance.SetupGet(m => m.Data).Returns(notExpectedBlue);
    ObjectFactory.Configure(x => x.For<ITestClass>().Use(blueInstance.Object).Named("Blue"));

//act
    var actual = ObjectFactory.GetNamedInstance<TestTarget>("Green");

//assert 
    Assert.AreEqual(expectedGreen, actual.TestClass.Data);

The class TestTarget has a constructor that takes an ITestClass as a parameter. My expectation is that by asking for an instance of TestTarget, I'd get a constructed TestTarget back that would reference the ITestClass named "Green".

Ultimately, my goal is to simulate a case where I have two objects of the same type that would be accessed in the container (such as an app that worked with two databases). An alternative approach for solving that type of problem would be a good answer too. However, I want to stick to the 2.5+ methods for doing this.

+1  A: 

When you are specifying multiple instances, use Add() instead of Use(). Use() is a synonym for the old TheDefaultIs().

ObjectFactory.Configure(x => x.For<ITestClass>().Add(blueInstance.Object)
    .Named("Blue"));
Joshua Flanagan
A: 

Turns out I needed to use "With" to do what I was trying to do. This ultimately is a two step process, but accomplishes what I wanted.

var greenFromContainer = ObjectFactory.GetNamedInstance<ITestClass>("Green");
var actual = ObjectFactory.With(greenFromContainer).GetInstance<TestTarget>();

More complicated scenarios would seem to be best handled with separate containers/registries or leveraging the extended constructor rules.

Jim Leonardo