11

No estoy seguro si esto es posible o no.¿Puedo usar la instalación de fábrica tipada para devolver la implementación según el parámetro (enum)?

Necesito devolver la implementación correcta de un servicio basado en un valor enum. Por lo que la aplicación codificado a mano sería algo como:

public enum MyEnum 
{ 
    One, 
    Two 
}  

public class MyFactory 
{ 
    public ITypeIWantToCreate Create(MyEnum type) 
    { 
    switch (type) 
    { 
     case MyEnum.One 
      return new TypeIWantToCreate1(); 
      break; 
     case MyEnum.Two 
      return new TypeIWantToCreate2(); 
      break; 
     default: 
      return null;  
    }  
    } 
} 

Las implementaciones que se devuelven tienen dependencias adicionales que tendrán que ser inyectado a través del contenedor, por lo que una fábrica de enrollado a mano no funcionará.

¿Es esto posible y, de ser así, cómo sería el registro?

+0

¿Qué hay de malo en registrar esa fábrica en su contenedor, y en lugar de hacer 'new Type1', simplemente devolver la llamada al contenedor? – Steven

+0

No quiero resolver directamente desde el contenedor: no tendré acceso al contenedor en este punto del código. –

+0

Haga que la parte de fábrica de [Composition Root] (http://blog.ploeh.dk/2011/07/28/CompositionRoot.aspx) de su aplicación (y permita que dependa de una interfaz 'IMyFactroy' que es parte de la aplicación). En ese caso, está bien acceder al contenedor ([this is * not * the Service Locator anti-pattern] (http://blog.ploeh.dk/2011/08/25/ServiceLocatorRolesVsMechanics.aspx)). Simplemente inyecte el contenedor en el constructor de la fábrica y estará bien. – Steven

Respuesta

8

Si el registro de su componente en el contenedor que especifica el valor de enumeración como Identificación del componente es una opción, es posible que teniendo en cuenta este enfoque demasiado

public class ByIdTypedFactoryComponentSelector : DefaultTypedFactoryComponentSelector 
{ 
     protected override string GetComponentName(MethodInfo method, object[] arguments) 
     { 
      if (method.Name == "GetById" && arguments.Length > 0 && arguments[0] is YourEnum) 
      { 
       return (string)arguments[0].ToString(); 
      } 

      return base.GetComponentName(method, arguments); 
     } 
} 

que ByIdTypedFactoryComponentSe lector se usará como Selector para su fábrica Typed

public enum YourEnum 
{ 
    Option1 
} 

public IYourTypedFactory 
{ 
    IYourTyped GetById(YourEnum enumValue) 
} 


container.AddFacility<TypedFactoryFacility>(); 
container.Register 
(  
    Component.For<ByIdTypedFactoryComponentSelector>(), 

    Component.For<IYourTyped>().ImplementedBy<FooYourTyped>().Named(YourEnum.Option1.ToString()), 

    Component.For<IYourTypedFactory>() 
    .AsFactory(x => x.SelectedWith<ByIdTypedFactoryComponentSelector>()) 
    .LifeStyle.Singleton, 

    ... 
+0

¿Qué ocurre si los parámetros requeridos son TypeIWantToCreate1 o TypeIWantToCreate2? El primero estaba dedicado a encontrar el Componente y los otros serían inyectados a la instancia del Componente. –

1

Parece que esto es posible. Echar un vistazo a esto:.

Example

Usted tendrá que crear una aplicación ITypedFactoryComponentSelector para resolver la llamada, y registrarlo en el contenedor sólo para resolver las peticiones de las clases que le interesan

Cuestiones relacionadas