Is anybody able to explain the following behavior?
Especially why TestInitializeAndConfigure_Fails failes when TestUseAndAdd does not ... and why TestUse_Fails failes when TestUseOrderChanged does not.
Thanks
code
interface IResource {}
class TheFirstResource : IResource {}
class TheSecondResource : IResource {}
[TestFixture]
class Test
{
[Test]
public void TestUse_Fails()
{
ObjectFactory.Initialize(init =>
{
init.For<IResource>().Singleton().Use<TheFirstResource>();
init.For<IResource>().Singleton().Use<TheSecondResource>().Named("test");
});
IResource r1 = ObjectFactory.GetInstance<IResource>();
IResource r2 = ObjectFactory.GetNamedInstance<IResource>("test");
Console.WriteLine(string.Format("TestUse_Fails \n{0}\n{1}", r1, r2));
}
[Test]
public void TestUseOrderChanged()
{
ObjectFactory.Initialize(init =>
{
init.For<IResource>().Singleton().Use<TheSecondResource>().Named("test");
init.For<IResource>().Singleton().Use<TheFirstResource>();
});
IResource r1 = ObjectFactory.GetInstance<IResource>();
IResource r2 = ObjectFactory.GetNamedInstance<IResource>("test");
Console.WriteLine(string.Format("TestUseOrderChanged \n{0}\n{1}", r1, r2));
}
[Test]
public void TestUseAndAdd()
{
ObjectFactory.Initialize(init =>
{
init.For<IResource>().Singleton().Use<TheFirstResource>();
init.For<IResource>().Singleton().Add<TheSecondResource>().Named("test");
});
IResource r1 = ObjectFactory.GetInstance<IResource>();
IResource r2 = ObjectFactory.GetNamedInstance<IResource>("test");
Console.Writ开发者_开发百科eLine(string.Format("TestUseAndAdd \n{0}\n{1}", r1, r2));
}
[Test]
public void TestInitializeAndConfigure_Fails()
{
ObjectFactory.Initialize(init =>
{
init.For<IResource>().Singleton().Use<TheFirstResource>();
});
ObjectFactory.Configure(init =>
{
init.For<IResource>().Singleton().Add<TheSecondResource>().Named("test");
});
IResource r1 = ObjectFactory.GetInstance<IResource>();
IResource r2 = ObjectFactory.GetNamedInstance<IResource>("test");
Console.WriteLine(string.Format("TestInitializeAndConfigure_Fails \n{0}\n{1}", r1, r2));
}
}
output
TestUse_Fails
Smtesting.TheSecondResource
Smtesting.TheSecondResource
TestUseOrderChanged
Smtesting.TheFirstResource
Smtesting.TheSecondResource
TestInitializeAndConfigure_Fails
Smtesting.TheSecondResource
Smtesting.TheSecondResource
TestUseAndAdd
Smtesting.TheFirstResource
Smtesting.TheSecondResource
Just to help the people who will stumble upon this, here is an answer from the man Jermey himself. He answered the question on his blog here.
For().Use() is destructive. Do For().Use() once to get the default, and a second call to For().Add() to get the 2nd registration. Look at the Xml comments for those 2 API calls.
TestUse_Fails makes sense to me, because calling Use<>() essentially means you are specifying the default instance for the type (and adding it). Last one in generally wins--I can't find explicit docs on this, but that's the way most containers work. The r1 call gets TheSecondResource (the last one set to be default), and the r2 call gets the named resource.
TestUseOrderChanged works because the default after init/config is the TheFirstResource, but TheSecondResource has still been added to the container with a name. So r1 gets TheFirstResource (as it was last in and thus the default), and r2 correctly gets TheSecondResource as the named instance.
TestInitializeAndConfigure_Fails is the odd one. From where I sit, r1 should get TheFirstResource, since the default has not been overwritten--Use<>() has not been called again. Calling Configure after calling Initialize should not reset the container according to the docs. I would try calling ObjectFactory.WhatDoIHave() and see if TheFirstResource is even registered after the Initialize() and Configure() calls.
To me, this looks like a bug, and I would consider submitting it to the structuremap users group (http://groups.google.com/group/structuremap-users).
精彩评论