2013-08-07 14 views
10

Mam usług WCF, który implementuje dwa kontrakty usługowe ...Jak zarejestrować dwa kontrakty serwisowe WCF z autofac

public class MyService : IService1, IService2 

i jestem self-hosting usługi ...

host = new ServiceHost(typeof(MyService)); 

Wszystko działało poprawnie, gdy usługa zaimplementowała tylko jedną umowę o świadczenie usług, ale kiedy próbuję skonfigurować autofac, aby zarejestrować oba w ten sposób:

host.AddDependencyInjectionBehavior<IService1>(_container); 
host.AddDependencyInjectionBehavior<IService2>(_container); 

... zgłasza wyjątek w drugim, zgłaszając:

Wartości nie można było dodać do kolekcji, ponieważ kolekcja zawiera już element tego samego typu: "Autofac.Integration.Wcf. AutofacDependencyInjectionServiceBehavior ". Ta kolekcja obsługuje tylko jedną instancję każdego typu.

Na pierwszy rzut oka myślałem, że to mówił moje dwie umowy zostały w jakiś sposób są postrzegane jako tego samego rodzaju, ale w drugim czytaniu wierzę, że mówi, że AutofacDependencyInjectionServiceBehavior jest typem o którym mowa, to znaczy, że nie można go używać dwa razy!

A jednak znalazłem this post wyraźnie pokazał, że używając go kilka razy w nieco innej formie:

foreach (var endpoint in host.Description.Endpoints) 
{ 
    var contract = endpoint.Contract; 
    Type t = contract.ContractType; 
    host.AddDependencyInjectionBehavior(t, container); 
} 

niestety, że dał bardzo sam komunikat o błędzie.

Czy można zarejestrować więcej niż jedną umowę o świadczenie usług w jednej usłudze, a jeśli tak, to w jaki sposób?

Odpowiedz

7

W rzeczywistości można zarejestrować wiele końcowy dla jednego hosta z Autofac.

To prawda, że ​​nie można dodać kilka AutofacDependencyInjectionServiceBehavior ale to zachowanie iteracji wszystkich punktów końcowych i rejestruje je w metodzie ApplyDispatchBehavior: source

W celu dokonania tej pracy trzeba zarejestrować usługa AsSelf()

builder.RegisterType<MyService>(); 

Następnie można skonfigurować punkt końcowy zwykle:

host = new ServiceHost(typeof(MyService)); 
host.AddServiceEndpoint(typeof(IService1), binding, string.Empty); 
host.AddServiceEndpoint(typeof(IService2), binding, string.Empty); 

I wreszcie trzeba wezwać AddDependencyInjectionBehavior z typem sevicehost samego:

host.AddDependencyInjectionBehavior<MyService>(container); 

Oto mały sample project (na podstawie documentation), co dowodzi tego zachowania.

+0

Dziękuję - powinienem był spróbować tego! Cieszę się, że mnie udowodniłeś źle :-) –

0

Update (pogrubiony tekst) na podstawie użytkownika @ nemesv odpowiedź:

Dalsze badania wykazały, że z autofac jeden nie może zarejestrować wiele punktów końcowych na jednym ServiceHost jeśli ktoś rejestruje umów o świadczenie usług WCF . (Patrz odpowiedź @ nemesv za właściwy sposób to zrobić.)

Oto dlaczego:

Każda forma tej metody wydłużania ...

host.AddDependencyInjectionBehavior<IService1>(_container); 
host.AddDependencyInjectionBehavior(t, container); 

... postanawia dół do dodawania ServiceBehavior (wg Alex Meyer-Gleaves initial announcement of WCF integration w autofac) ...

host.Description.Behaviors.Add(behavior); 

Nie w tej właściwości Behaviors jest instancją KeyedByTypeCollection<TItem>, która może pomieścić tylko jeden obiekt danego typu. Ponieważ dodawane zachowanie zawsze będzie instancją AutofacDependencyInjectionServiceBehavior, można w związku z tym dodać tylko jeden punkt końcowy.

QED

Rozwiązaniem jest użycie wielu ServiceHosts, każdy z jednego punktu końcowego.

(Jako punkt zainteresowania, byłbym ciekaw wpływ na wydajność i skalowalność między tymi dwoma podejściami.)

+0

Czy dziedziczenie z usługi AutofacDependencyInjectionServiceBehavior i instancja odczytu tej pomocy nie będzie dziedziczone? –

Powiązane problemy