WCF och Dependency Injection
Dependency Injection (Jag håller mig till engelska begrepp, Beroende Injektion låter inget vidare) är något som är på bred frammarsch och antalet ramverk för detta på .NET plattformen ökar kontinuerligt. i och med släppet av Enterprise Library 4.0 fick vi även tillgång till Unity. (Jag har hört historier om att det var gänget bakom Codeplex som initialt byggde Unity på de ursprungliga Object Builder biblioteken och detta sedan övertogs av patterns & practices för vidare utveckling och paketering.)
Unity gör det bland annat möjligt för dig att definiera implementationen av ett kontrakt med hjälp av konfiguration. Låter det bekant? I WCF är det egentligen åt andra hållet; dvs du definierar ett eller flera kontrakt för en tjänsteimplementation. Hur kan man då göra för att utöka detta så WCF tilldelas en tjänsteimplementation utifrån ett kontrakt samt också kunna definiera eventuella beroenden som skall tilldelas tjänsteimplementationen? Kortfattat; implementera en Instance Provider och ta i den del av Unitys förmågor.
Jag börjar med att skapa en Instance Provider genom att implementera interfacet IInstanceProvider. IInstanceProvider kräver att jag implementerar tre metoder, två varianter av GetInstance() och en ReleaseInstance().
Jag lade till ytterligare en, privat, variant på GetInstance() vilken konfigurerar Unity Containern samt returnerar min efterfrågade instans.
Nästa steg är att få WCF att nyttja min Instance Provider. Detta görs med med ett beteende, Behavior. Det finns flera typer av Behaviors som kan användas i detta fall. Jag valde mellan Endpoint Behavior och Contract Behavior. Valet för denna demonstrations skull föll på ett Endpoint Behavior av den anledningen att jag då i konfiguration ange vilka Endpoints som skall nyttja min UnityInstanceProvider. Ett Contract Behavior kan inte läggas till med hjälp av konfiguration utan kan endast läggas till i runtime med hjälp av kod. (Går att lösa lite tjusigt med ett attribut som sätts på tjänstekontraktet. Nästa gång kanske...)
Jag implementerar därav också interfacet IEndpointBehavior. Den metod som jag behöver för att tilldela Dispatchern min InstanceProvider är ApplyDispatchBehavior. De övriga metoderna har jag lämnat tomma. I denna metod tar jag även reda på kontraktet som Endpointen exponerar. (Se bilden ovan för att se hur detta används i _container.Resolve() för att returnera tjänsteimplementationen)
Den sista lilla saken att göra för att sy ihop allt är att ärva från den abstrakta basklassen BehaviorExtensionElement och implementera metoden CreateBehavior och egenskapen BehaviorType. Detta för att tillgängliggöra mitt EndpointBehavior i konfiguration.
Med detta nu på plats kan jag i min .config-fil ange per Endpoint om jag vill låta Unity hantera skapandet av min tjänsteinstans.
Avslutningsvis vill jag poängtera att detta är en förenklad implementation för att påvisa tillvägagångssättet med en Instance Provider. Det finns t ex ingen funktionalitet på plats i mitt exempel för att hantera varaktiga tjänster.
Skicka ett mail till mig så sänder jag gladerligen över hela exempelkoden till dig!
Det var allt för nu.
-c
Comments
- Anonymous
February 19, 2009
I min förra post skrev jag hur vi med Unity kan löskoppla tjänsteimplementationens beroenden på ett smidigt - Anonymous
March 09, 2010
Smart. Bra och tydlig introduktion till hur man kommer igång med WCF och DI.