StructureMap HowTo: Conditional Construction on Deep Object
I'm having difficulty conditionally creating a dependency. Googling, I have yet to find a good example of using the BuildStack and Conditional Predicates.
Here's what I'm doing in the Registry:
//snip
public SomeRegistry()
{
this.InstanceOf<IFoo>().Is.Conditional(
c =>
{
c.TheDefault.Is.ConstructedBy(() => new FooZ());
c.If(
p => p.ParentType.IsAssignableFrom(typeof(IBar)) &&
p.BuildStack.Current.RequestedType.IsAssignableFrom(typeof(IDoStuffWithFooA)))
.ThenIt.Is.ConstructedBy(() => new FooA());
c.If(
p => p.ParentType.IsAssignableFrom(typeof(IBar)) &&
p.BuildStack.Current.RequestedType.IsAssignableFrom(typeof(IDoStuffWithFooB)))
.ThenIt.Is.ConstructedBy(() => new FooB());
});
this.Scan(
s =>
{
s.TheCallingAssembly();
s.WithDefaultConventions();
});
}
//snip
Here's unit tests showing what I'm expecting
//snip
[TestFixture]
public class ConditionalCreationTest
{
[Test]
public void GiveUsFooAWhenDoingStuffWithA()
{
var dependA = ObjectFactory.GetInstance<IDoStuffWithFooA>();
Assert.IsInstanceOfType<FooA>(dependA.Foo);
}
[Test]
public void GiveUsFooBWhenDoingStuffWithB()
{
var dependB = ObjectFactory.GetInstance<IDoStuffWithFooB>();
Assert.IsInstanceOfType<FooB>(dependB.Foo);
}
[Test]
public void GiveUsFooZByDefault()
{
var foo = ObjectFactory.GetInstance<IFoo>();
Assert.IsInstanceOfType<FooZ>(foo);
}
[Test]
public void GiveUsProperFoosWhenWeDontAskDirectly()
{
var bar = ObjectFactory.GetInstance<IBar>();
Assert.IsInstanceOfType<FooA>(bar.DoStuffA.Foo);
Assert.IsInstanceOfType<FooB>(bar.DoStuffB.Foo);
}
[SetUp]
public void SetUp()
{
ObjectFactory.Initialize(a => a.AddRegistry<SomeRegistry>());
}
}
//snip
This is what I want StructureMap to AutoWire with the correct dependency of IFoo:
//snip
public class Bar : IBar
{
private IDoStuffWithFooA doStuffA;
private IDoStuffWithFooB doStuffB;
public Bar(IDoStuffWithFooA doStuffA, IDoStuffWithFooB doStuffB)
{
this.doStuffA = doStuffA;
this.doStuffB = doStuffB;
}
public IDoStuffWithFooA DoStuffA
{
get
{
return this.doStuffA;
}
}
public IDoStuffWithFooB DoStuffB
{
get
{
return this.doStuffB;
}
}
}
//snip
I cannot figure out how to get GiveUsP开发者_如何转开发roperFoosWhenWeDontAskDirectly
test to pass.
I want to get FooA
to get initialized when I need IDoStuffWithFooA
, FooB
when IDoStuffWithFooB
, regardless of when it's needed in the graph. What is the proper syntax for the conditional predicate?
It's often best to try to avoid conditional construction with that syntax, it is much harder to interpret than the For - Use. Your scenario can be solved using:
For<IDoStuffWithFooA>().Use<DoStuffWithFooA>().Ctor<IFoo>().Is<FooA>();
For<IDoStuffWithFooB>().Use<DoStuffWithFooB>().Ctor<IFoo>().Is<FooB>();
For<IFoo>().Use<FooZ>();
Scan(
s =>
{
s.TheCallingAssembly();
s.WithDefaultConventions();
});
精彩评论