2009-02-19 9 views
7

important; Estoy realmente buscando una respuesta StructureMap aquí. Por favor, no digas cómo hacerlo con Windsor, Spring, Unity o cualquiera de the others.Configuración de perfiles con StructureMap

Estoy jugando con StructureMap para IoC - y, básicamente, mi objetivo es tener un perfil "predeterminado" que defina los tipos de núcleo, y una serie de perfiles con nombre que anular/ampliar esto. I piensa que los perfiles pueden hacer esto, pero simplemente no puedo hacer que funcione a través de las API xml o del código. En particular, si intento cargar un contenedor para un perfil:

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

en cuando me siento "solicitada Perfil {nombre} no se puede encontrar", a pesar de que claramente llamé CreateProfile en el initialize (con ese nombre)

¿Estoy ladrando el árbol equivocado?

(también publicado a user-group)


Lo que idealmente quiero es ser capaz de definir las estándar (/ por defecto) tipos, y luego para una gama de diferentes configuraciones con nombre, anulación algunas de las configuraciones - es decir, si tuviera

  • mundial: IFoo =>Foo, IBar =>Bar
  • configA: (sin cambios)
  • configB: IFoo =>SpecialFoo

Creo que esto podría asignar a 2 contenedores, cargados utilizando perfiles con nombre. El propósito es que si te pido, ya sea un contenedor para IBar, consigo un Bar - pero configA devuelve un Foo (por IFoo), donde -como configB devuelve un SpecialFoo.

¿Alguien puede darme una pista de cómo puedo configurar esto? El código xml o está bien ... Solo quiero que funcione. Todo lo que necesito es interfaz-to- asignaciones de tipo concreto (sin ajustes especiales de configuración/propiedad).

Respuesta

9

El truco es asegurarse de que cada perfil como mínimo esté definido en él. Si no especifica una regla (configA), no creará/verá el perfil.

Dadas estas clases:

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{ } 

Se puede definir este registro:

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>(); 
    } 
} 

y funcionará con estas pruebas:

[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()); 
} 

si reemplaza CreateProfileNotEmpty con sencillo CreateProfile , fallará en la línea que establece el valor predeterminado para configA.

+1

interesante. Lo intentaré mañana. Considérelo como un +1 (y posiblemente como "el ganador"): en este momento estoy sin votos; –

Cuestiones relacionadas