2010-09-29 8 views
13

J'essaie de trouver la bonne façon d'injecter une usine automatique qui prend des paramètres, ou même si cela est possible avec Unity.Unity auto-factory avec params

Par exemple, je sais que je peux le faire:

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

Maintenant ce que j'aimerai pouvoir faire est:

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"); 

Malheureusement, cela ne fonctionne pas. Je peux voir comment vous pouvez configurer des usines personnalisées pour créer des instances dans Unity, ne peut pas sembler financer des exemples clairs pour cet exemple.

Évidemment Je pourrais créer ma propre usine mais je cherche une manière élégante de faire ceci dans l'unité et avec le code minimum.

Répondre

28

Désolé d'être l'une de ces personnes agaçantes qui répondent à leurs propres questions mais je l'ai compris.

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

Est-il possible de faire quelque chose comme ça, mais en utilisant l'injection du constructeur? – dmigo

+0

@Chesheersky l'exemple ci-dessus utilise l'injection du constructeur. – TheCodeKing

+0

Droit, mon erreur :) – dmigo

1

Si vous êtes à la recherche d'une interface usine entièrement dactylographiée (permettant des noms de documentation XML et paramètres, par exemple), vous pouvez utiliser un NuGet package j'ai créé, que vous pouvez exploiter simplement en définissant une interface pour l'usine, puis en l'associant au type concret que vous souhaitez instancier.

vit à code GitHub: https://github.com/PombeirP/FactoryGenerator

+0

Exactement ce dont j'ai besoin Suggérer moi d'ajouter un exemple à votre réponse comme ici: http://blog.ploeh.dk/2012/03/15/ImplementinganAbstractFactory/ dans la section Dynamic Proxy. – Ghosthack

5

La réponse par @TheCodeKing fonctionne très bien, mais dans la plupart des cas pourrait être raccourci à ce qui suit (peut-être tout?):

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

(notez que je « utilise RegisterInstance() au lieu de RegisterType())

Depuis la mise en œuvre Func<> est déjà une sorte d'usine il n'y a généralement pas n eed pour l'envelopper dans un InjectionFactory. Il s'assure seulement que chaque résolution du Func<string, ILog> est une nouvelle instance, et je ne peux pas vraiment penser à un scénario qui l'exige.