2010-09-29 9 views
13

Estoy tratando de encontrar la forma correcta de inyectar una auto fábrica que tome params, o incluso si esto es posible con Unity.Unity auto-factory con los parámetros

Por ejemplo Sé que puedo hacer esto:

public class TestLog 
{ 
    private Func<ILog> logFactory; 

    public TestLog(Func<ILog> logFactory) 
    { 
      this.logFactory = logFactory; 
    } 
    public ILog CreateLog() 
    { 
     return logFactory(); 
    } 
} 

Container.RegisterType<ILog, Log>(); 
TestLog test = Container.Resolve<TestLog>(); 
ILog log = test.CreateLog(); 

Ahora lo que voy a gustaría ser capaz de hacer es:

public class TestLog 
{ 
    private Func<string, ILog> logFactory; 

    public TestLog(Func<string, ILog> logFactory) 
    { 
      this.logFactory = logFactory; 
    } 
    public ILog CreateLog(string name) 
    { 
     return logFactory(name); 
    } 
} 

Container.RegisterType<ILog, Log>(); 
TestLog test = Container.Resolve<TestLog>(); 
ILog log = test.CreateLog("Test Name"); 

Desafortunadamente esto no funciona. Puedo ver cómo puede configurar fábricas personalizadas para crear instancias en Unity, simplemente no parece financiar ningún ejemplo claro para este ejemplo.

Obviamente Podría crear mi propia fábrica pero estoy buscando una forma elegante de hacerlo en Unity y con un código mínimo.

Respuesta

28

Lamento ser una de esas personas molestas que responden a sus propias preguntas, pero lo descubrí.

public class TestLog 
{ 
    private Func<string, ILog> logFactory; 

    public TestLog(Func<string, ILog> logFactory) 
    { 
     this.logFactory = logFactory; 
    } 
    public ILog CreateLog(string name) 
    { 
     return logFactory(name); 
    } 
} 

Container.RegisterType<Func<string, ILog>>(
    new InjectionFactory(c => 
     new Func<string, ILog>(name => new Log(name)) 
    )); 

TestLog test = Container.Resolve<TestLog>(); 
ILog log = test.CreateLog("Test Name"); 
+0

¿Es posible hacer algo así, pero usando la inyección de constructor? – dmigo

+0

@Chesheersky el ejemplo anterior usa inyección de constructor. – TheCodeKing

+0

Correcto, mi error :) – dmigo

1

En caso de que usted está buscando un interfaz de fábrica totalmente escrito (lo que permite nombres de documentación XML y los parámetros, por ejemplo), se puede utilizar un NuGet package he creado, lo que puede aprovechar simplemente mediante la definición de una interfaz para la fábrica, y luego asociándola con el tipo de concreto que desea instanciar.

Código vive en GitHub: https://github.com/PombeirP/FactoryGenerator

+0

Exactamente lo que necesito. Sugiero que agregue un ejemplo a su respuesta como aquí: http://blog.ploeh.dk/2012/03/15/ImplementinganAbstractFactory/ en la sección Dynamic Proxy. – Ghosthack

5

La respuesta por @TheCodeKing funciona bien, pero en la mayoría de los casos podría reducirse a lo siguiente (posiblemente todos?):

Container.RegisterInstance<Func<string, ILog>>(name => new Log(name)); 

(tenga en cuenta que yo 'm usando RegisterInstance() en lugar de RegisterType())

Desde la implementación Func<> ya es una clase de fábrica por lo general hay ninguna n para envolverlo en un InjectionFactory. Solo garantiza que cada resolución del Func<string, ILog> sea una nueva instancia, y realmente no puedo pensar en un escenario que lo requiera.