2013-03-14 1 views
15

J'essaie de comprendre le modèle d'usine délégué avec Autofac. Je sais comment implémenter l'usine à l'aide iIndex <> avec détrompeur() l'inscription, qui est expliqué bien ici: Configuring an Autofac delegate factory that's defined on an abstract classUsine de délégué Autofac en utilisant func <>

Je voudrais savoir si je peux créer une usine à l'aide Func <>, et comment pourrais-je faire la inscriptions pour l'exemple suivant:

public enum Service 
{ 
    Foo, 
    Bar 
} 

public interface FooService : IService 
{ 
    ServiceMethod(); 
} 

public interface BarService : IService 
{ 
    ServiceMethod(); 
} 

public class FooBarClient 
{ 
    private readonly IService service; 

    public FooBarClient(Func<Service, IService> service) 
    { 
     this.service = service(Service.Foo); 
    } 

    public void Process() 
    { 
     service.ServiceMethod(); // call the foo service. 
    } 
} 
+0

Pourquoi ne pas simplement utiliser 'IIndex <>' avec 'Keyed()'? Autofac ne peut pas créer ce 'Func ' pour vous. Vous devez l'enregistrer dans votre conteneur en utilisant 'Keyed()' ou 'Named()' quelque chose comme: 'builder.Register > (c => s => c.ResolveKeyed (s) Les usines déléguées peuvent seulement créer un type avec des paramètres et ne pas choisir un type basé sur un paramètre parce que c'est ce qui est 'IIndex <>' pour. – nemesv

+2

Pour IIndex <> je vais devoir référencer la bibliothèque Autofac que j'essaye d'éviter. Je veux que mon code DI soit en racine composite (bibliothèque séparée) seulement si possible. –

Répondre

16

Autofac ne peut pas construire ce Func<Service, IService> pour vous qui vous permet de retourner différents types en fonction d'un paramètre. C'est ce que IIndex<> est pour.

Toutefois, si vous ne voulez pas/ne peut pas utiliser IIndex<> vous pouvez créer cette fonction d'usine avec l'aide du Keyed ou Named et enregistrer votre usine dans le conteneur:

var builder = new ContainerBuilder(); 
builder.RegisterType<FooBarClient>().AsSelf(); 
builder.RegisterType<FooService>().Keyed<IService>(Service.Foo); 
builder.RegisterType<BarService>().Keyed<IService>(Service.Bar); 

builder.Register<Func<Service, IService>>(c => 
{ 
    var context = c.Resolve<IComponentContext>(); 
    return s => context.ResolveKeyed<IService>(s); 
}); 
+0

merci nemesv! son fonctionnement comme prévu !!! une seule question, y aura-t-il une différence de performance - IIndex vs Func? –

+0

Je ne sais pas comment IIndex est implémenté et quel type de chaching ou optimisation de performance il a. Vous pouvez vérifier l'implantation ou vous devez faire des tests de performance adaptés à votre scénario pour comparer les deux. – nemesv

+2

Je viens d'essayer ça avec la version raison, mais ça me donne un 'ObjectDisposedException' ... J'ai" résolu "cela en appelant' new Foo' dans le délégué (qui est un biog nogo!) –

Questions connexes