2010-09-21 6 views
2

J'ai une interface, par exemple ISomeService. ISomeService fournit un service commun, mais les implémentations peuvent varier. En tant que tels, ils auront des dépendances différentes.Implémentation d'une usine ou d'un fournisseur de service générique dans Autofac

Tenir compte:

interface ISomeService 
{ 
    void DoSomething(); 
} 

class SomeServiceA : ISomeService 
{ 
    public SomeServiceA(DependencyOne one, DependencyTwo two) 
    { 
    } 


    public void DoSomething() 
    { 
    } 
} 

class SomeServiceB : ISomeService 
{ 
    public SomeServiceB(DependencyThree three) 
    { 
    } 

    public void DoSomething() 
    { 
    } 
} 

Maintenant, la réalité est que je ne peux pas simplement ajouter une dépendance à ISomeService à mon contrôleur et fait avec elle. Je vais devoir choisir une implémentation de IService basée sur ce que l'utilisateur me dit, et je pourrais avoir à créer plusieurs copies du service sélectionné.

Peut-être que je l'aurais une classe qui me permet de résoudre une instance de la ISomeService j'ai besoin, par type:

class SomeServiceProvider 
{ 
    public T Get<T>() 
     where T : ISomeService 
    { 
      // uh oh, this is starting to have a bad smell... do I call the container? that's no good 
    } 

} 

Je pouvais

class SomeController 
{ 
    SomeServiceProvider ServiceProvider { get; set; } 

    public SomeController(ServiceProvider provider) 
    { ServiceProvider = provider; } 

    public void SomeAction(string serviceName) 
    { 
      ISomeService someService; 
      if (serviceName.Equals('SomeServiceA')) someService = ServiceProvider.Get<SomeServiceA>(); 
      else someService = ServiceProvider.Get<SomeServiceB>(); 
      someService.DoSomething(); 
    } 

} 

Il semble que l'usine de délégué Autofac ne serait pas approprié ici, et je ne sais pas quoi faire autrement (sauf utiliser un localisateur de service). Des recommandations?

Répondre

2

Est-ce ce que vous cherchez? Service types, names and keys

Les services peuvent être identifiés en utilisant un nom de service. En utilisant cette technique, la méthode d'enregistrement Named() remplace As().

builder.Register<OnlineState>().Named<IDeviceState>("online"); 

Pour récupérer un service nommé, la méthode ResolveNamed() est utilisée:

var r = container.ResolveNamed<IDeviceState>("online"); 
+0

Je pense que la section ** Résolution d'un index ** dans votre lien fera ce que je veux, même si c'est un peu gênant que je doive écrire un composant qui nécessite une référence à Autofac lui-même. Mais, je suppose que je peux faire face à cela. Merci! – HackedByChinese

+1

Je suggère de créer un SomethingFactory qui utilise IIndex et implémente ISomethingFactory, que vous pouvez ensuite utiliser dans vos contrôleurs - le meilleur des deux mondes! :) Il est préférable de conserver des types comme IIndex dans la partie infrastructure de votre application, où elle interagit avec le conteneur IoC, plutôt que dans les composants d'application standard. Bonne chance avec ça! Entaille –

Questions connexes