Configure profiles using StructureMap

important ; I am really looking for StructureMap here. Please do not say how to do this with Windsor, Spring, Unity or any of the others .

I play with StructureMap for IoC - and basically my goal is to have a default profile that defines the basic types, and several named profiles that override / extend it. I think profiles can do this, but I just can't get it to work either through xml or with the API code. In particular, if I try to load the container for the profile:

 container = new Container(); container.SetDefaultsToProfile(profile); 

Then I get "Requested Profile {name} cannot be found", despite the fact that I explicitly called CreateProfile in the initialization (with this name).

Am I barking the wrong tree?

(also posted to user group )


What I ideally want is to define the standard (/ default) types, and then for a number of different named configurations, override some settings - i.e. if i had

  • global: IFoo => Foo , IBar => Bar
  • configA: (no change)
  • configB: IFoo => SpecialFoo

I believe that this can appear in 2 containers loaded using named profiles. The goal is that if I ask for a container for IBar , I get Bar - but configA returns a Foo (for IFoo ), where - when configB returns SpecialFoo .

Can someone let me know how I can tweak this? Either xml or the code is fine ... I just want it to work. All I need is an interface - concrete mappings (there are no special configuration settings / properties).

+7
structuremap configuration
source share
2 answers

The trick is to make sure that each individual profile has at least the rule defined in it. If you do not specify a rule (configA), it will not create / see a profile.

Given these classes:

 public interface IFoo { string SayHello(); } public class Foo : IFoo { public string SayHello() { return "Hello"; } } public class SpecialFoo : IFoo { public string SayHello() { return "Hello Special"; } } public interface IBar { } public class Bar : IBar { } public interface IDummy { } public class Dummy : IDummy{ } 

This registry can be defined:

 public class MyRegistry : Registry { protected override void configure() { ForRequestedType<IBar>().TheDefault.Is.OfConcreteType<Bar>(); ForRequestedType<IFoo>().TheDefault.Is.OfConcreteType<Foo>(); CreateProfileNotEmpty("configA"); CreateProfileNotEmpty("configB") .For<IFoo>().UseConcreteType<SpecialFoo>(); } StructureMap.Configuration.DSL.Expressions.ProfileExpression CreateProfileNotEmpty(string profile) { return CreateProfile(profile) .For<IDummy>().UseConcreteType<Dummy>(); } } 

And he will work with these tests:

 [TestMethod] public void TestMethod1() { var container = new Container(new MyRegistry()); Assert.IsNotNull(container.GetInstance<IBar>()); Assert.AreEqual("Hello", container.GetInstance<IFoo>().SayHello()); container.SetDefaultsToProfile("configB"); Assert.IsNotNull(container.GetInstance<IBar>()); Assert.AreEqual("Hello Special", container.GetInstance<IFoo>().SayHello()); container.SetDefaultsToProfile("configA"); Assert.IsNotNull(container.GetInstance<IBar>()); Assert.AreEqual("Hello", container.GetInstance<IFoo>().SayHello()); } 

if you replace CreateProfileNotEmpty with a simple CreateProfile, it will not work on the line that sets the default value for configA.

+9
source share

Watch this video, it shows another way to create a "default" profile and the presence of other named profiles that will act as options.

http://www.dimecasts.net/Casts/CastDetails/135

+1
source share

All Articles