2010-11-01 4 views
2

J'ai un service WCF qui sera appelé à partir de divers clients.Service WCF avec plusieurs implémentations de dépendances

En interne, le service WCF utilise un élément ISomething. Il existe plusieurs implémentations de cette interface et j'ai besoin que certains clients utilisent une implémentation et d'autres clients pour utiliser une implémentation différente.

En outre, j'utilise Unity et un conteneur IoC. Je configurerais généralement une fabrique personnalisée pour permettre au service wcf de se résoudre avec son graphe de dépendance, mais si j'ai plusieurs implémentations d'une dépendance, je ne pense pas que je puisse aller avec cette approche et je devrais recourir à la résolution l'ISomething dans le service (utilisant effectivement Unity comme un localisateur de service) qui n'est pas idéal.

donc je dois travailler

(1) comment spécifier que la mise en œuvre de ISomething a besoin du client (par exemple. Utiliser un en-tête, passer la chaîne de mise en œuvre dans chaque méthode, héberger plusieurs points d'extrémité, etc.)

(2) comment Unity s'intègre-t-il?

Répondre

2

Une option consiste à écrire un décorateur qui effectue la sélection pour vous:

public class RoutingSomething : ISomething 
{ 
    private readonly ISomeContext ctx; 
    private readonly ISomething s1; 
    private readonly ISomething s2; 
    private readonly ISomething s3; 

    public RoutingSomething(ISomeContext ctx) 
    { 
     this.ctx = ctx; 

     // An even better design would be to inject these too 
     this.s1 = new BarSomething(); 
     this.s2 = new BazSomething(); 
     this.s3 = new QuxSomething(); 
    } 

    // Assuming ISomething has a Foo method: 
    public void Foo() 
    { 
     if(this.ctx.Bar()) 
     { 
      this.s1.Foo(); 
      return; 
     } 
     if(this.ctx.Baz()) 
     { 
      this.s2.Foo(); 
      return; 
     } 
     if(this.ctx.Qux()) 
     { 
      this.s3.Foo(); 
      return; 
     } 
    } 
} 

Vous pouvez généraliser cela pour que ISomeContext est tout simplement un résumé de l'usine ISomething. Cela commence alors à se transformer en general solution to varying dependencies based on run-time context.

Vous pouvez désormais enregistrer RoutingSomething dans Unity en plus de vos autres composants. Lorsque le conteneur résout le service, il va y injecter une instance de RoutingSomething.

+0

C'est assez chouette mais j'ai encore besoin du service pour savoir quelle implémentation le CLIENT veut utiliser. Comment puis-je transmettre cette information afin qu'elle soit accessible assez tôt pour être disponible lorsque je résous le service? –

+0

Le service est-il protégé par une sorte d'authentification? Si c'est le cas, vous pouvez utiliser le principal authentifié comme clé pour sélectionner le service correct. Sinon, un en-tête personnalisé semble être une option raisonnable. –

Questions connexes