MSDN Magazin > Home > Ausgaben > 2008 > February >  PIAB und WCF: Integrieren des Policy Injection ...
PIAB und WCF
Integrieren des Policy Injection Application Block in WCF-Dienste
Hugh Ang and David San Filippo
Codedownload verfügbar unter: WCFandPIAB2008_02.exe (196 KB)
Browse the Code Online

Themen in diesem Artikel:
  • Integrieren von PIAB und WCF
  • Erstellen benutzerdefinierter WCF-Verhaltensweisen
  • Anwenden von Verhaltensweisen durch .NET-Attribute oder Konfiguration
  • Integration ohne Ändern von Code
In diesem Artikel werden folgende Technologien verwendet:
WCF, PIAB
Einer der wichtigsten Grundsätze für den Softwareentwurf ist die Trennung verschiedener Aufgabenbereiche innerhalb von Anwendungen. Im dienstorientierten Entwurf werden Anwendungen in Dienste und Vorgänge aufgeteilt. In der Realität dagegen greifen Implementierungsbelange oft auf die Dienste über.
Dieses Problem tritt nicht nur beim dienstorientierten Entwurf auf, sondern auch beim objektorientierten Entwurf. Enterprise Library 3.0 hat den Anwendungsblock „Richtlinieninjektion“ (Policy Injection Application Block, PIAB) eingeführt, um dieses Problem im objektorientierten Entwurf zu lösen. Zum Zeitpunkt dieses Artikels unterstützt jedoch die aktuelle Version von Enterprise Library (3.1) die Integration von PIAB in WCF-Dienste (Windows® Communication Foundation) nicht direkt. Deshalb dürfte die Anwendung von PIAB auf einzelne Belange in dienstorientierten Anwendungen etwas gewagt erscheinen. Mit den richtigen Verfahren gibt dies allerdings kein größeres Problem auf. Fangen wir also an.
Um PIAB zu nutzen, müssen Sie Kontrolle darüber haben, wie Ihre Objekte instanziiert werden. Bei Dienstframeworks wie WCF, bei denen die Objektinstanziierung vom Entwickler entfernt und abstrahiert wird, tritt bei dem Versuch, PIAB zu integrieren, ein Problem auf. WCF bietet jedoch verschiedene Erweiterbarkeitspunkte anhand von Verhaltensweisen. Im Folgenden erfahren Sie, wie Sie benutzerdefinierte WCF-Verhaltensweisen nutzen, um PIAB am WCF-Dienstpunkt anzuwenden, ohne dass zusätzlicher Code erforderlich wird. Mit der erfolgreichen Integration des WCF-Diensts kann PIAB wirklich zu einem universellen Framework für das Trennen der Dienstlogik von übergreifenden Implementierungsinformationen werden.

Ein praktisches Beispiel
Stellen Sie sich für ein besseres Verständnis dieses Übergriffsproblems vor, dass Sie einen einfachen Dienst erstellen, um ein benutzerdefiniertes Kundenobjekt mithilfe einer Kunden-ID zu finden. Sie schreiben eine einfache Methode in Visual Studio® 2005, um ein Datenzugriffsobjekt aufzurufen und ein Kundenobjekt zurückzugeben:
public Customer GetCustomer(string customerID)
{
    return CustomerDAO.GetCustomer(customerID);
}
Dabei fällt Ihnen ein, dass das Kunden-ID-Feld nicht leer sein darf. Also fügen Sie einige Zeilen für die Prüfung hinzu. Außerdem fügen Sie ein paar Ablaufverfolgungsanweisungen hinzu, damit Sie sicherstellen können, dass die richtigen Werte übergeben und vom Datenzugriffsobjekt zurückgegeben werden. Abschließend fügen Sie die Ausnahmebehandlung hinzu, um jegliche Ausnahmen einzuschließen, die vom Datenzugriffsobjekt mit einer benutzerdefinierten Ausnahme ausgelöst werden. Schon haben Sie 15 Zeilen Code. Es hätte sogar noch schlimmer sein können. Eine Autorisierungslogik oder eine Logik für die Zwischenspeicherung oder die Aktualisierung der Leistungsindikatoren hätte den Code noch unhandlicher gemacht.
Bislang hat jedoch keine dieser Ergänzungen etwas mit dem Abrufen eines Kundenobjekts zu tun. Schließlich ist alles, was Sie am Ende dieser Arbeit erhalten, ein schwer verständlicher, schwer zu verwaltender und schwer wiederzuverwendender Code. Leider gibt es in der Praxis viele solcher Beispiele, besonders wenn die Geschäftslogik mehr als eine Zeile Code umfasst.
Mithilfe von PIAB benötigen Sie nur eine einzelne Codezeile in Ihrer Methode. Der Code für die Prüfung, Ausnahmebehandlung und so weiter wird dabei durch die Erstellung von Richtlinien eingeführt, von denen die Implementierungsinformationen zur Laufzeit definiert werden. Richtlinien können auf Objekte über die Konfiguration oder über ergänzende Klassen mit Attributen angewendet werden. Jede Richtlinie verfügt über einen Satz von Übereinstimmungsregeln, die festlegen, wo sie angewendet werden soll, und eine Sammlung von Handlern, die festlegen, welche Verhaltensweisen eingeführt werden sollen, wenn Methoden für das Objekt abgerufen werden. PIAB enthält eine Reihe nützlicher Handler für die Prüfung, das Protokollieren, die Ausnahmebehandlung, das Verwalten der Leistungsindikatoren, die Autorisierung und das Zwischenspeichern. Viele dieser Handler nutzen die anderen Anwendungsblöcke von Enterprise Library.
Um ein Objekt zu nutzen, das diese Richtlinien verwendet, müssen Sie mithilfe von PolicyInjectorFactory eine Instanz der Klasse erstellen. Statt die Klasse, die den „neuen“ Operator verwendet, zu instanziieren, übergeben Sie den Typ zur Create-Methode von Factory. Die Factory legt mithilfe der Übereinstimmungsregeln fest, welche Richtlinien für diesen Typ gelten. PIAB unterstützt Übereinstimmungsregeln, die auf Typen, Assemblys, Mitgliedsnamen, Methodensignaturen, Namespaces, Parametertypen, Eigenschaftstypen, Rückgabetypen, benutzerdefinierten Attributen, Tags (PIAB stellt Ihnen ein Tagattribut zur Verfügung, das zur Übereinstimmung auf einen Wert festgelegt werden kann) und Ihren eigenen benutzerdefinierten Übereinstimmungsregeln basieren.
Wenn keine Übereinstimmungsregeln zutreffen, instanziiert die Factory den Typ und gibt ihn zurück. Ansonsten erstellt sie einen Proxy für dieses Objekt. Der Proxy fängt Aufrufe an das Objekt ab und ruft die Handler in einer Pipeline auf (siehe Abbildung 1).
Abbildung 1 Handlerpipeline (Klicken Sie zum Vergrößern auf das Bild)
Mit PIAB kann die GetCustomer-Dienstmethode auf eine einzelne Codezeile beschränkt werden. Es muss nur noch eine Richtlinie definiert werden, um den Vorgang „GetCustomer“ anzupassen und Handler für das Protokollieren, die Prüfung und die Ausnahmebehandlung einzubinden.
Nachdem Sie nun die PIAB-Richtlinie, die Übereinstimmungsregeln und die Handler verstehen, müssen Sie das Problem angehen, diese Lösung in WCF zu integrieren. Im Folgenden wird untersucht, wie Sie weiterhin PIAB nutzen könnten, falls der GetCustomer-Vorgang in einem WCF-Dienst definiert ist.

Übersicht über die WCF-Architektur
WCF ist die Microsoft-Plattform für das Erstellen von Diensten, die verschiedene Übertragungen unterstützen, darunter TCP/IP, HTTP, MSMQ, Named Pipes und WS-*-Protokolle. Auf einer hohen Ebene besteht die WCF-Architektur aus einer Dienstmodellschicht und einer Kanalschicht sowohl beim Absender als auch beim Empfänger (siehe Abbildung 2). Die Dienstmodellschicht stellt die API bereit, um den Benutzercode mit WCF zu verbinden. Die Kanalschicht behandelt das Messaging und die Übertragungsdetails.
Abbildung 2 WCF-Architektur (Klicken Sie zum Vergrößern auf das Bild)
Zum Hosten eines WCF-Diensts müssen Sie die Adresse, die Bindung und den Vertrag definieren, die den Dienstendpunkt definieren. Diese können entweder im Code oder in der Konfigurationsdatei definiert werden, und sie steuern gewissermaßen die Kanalschicht. WCF sorgt für den Aufbau der Kanäle, die für die Bindung und das Protokoll erforderlich sind, fragt eingehende Nachrichten ab und sendet sie durch Aufruf seiner Methoden an die vorgesehenen Dienstinstanzen.
Wie bereits erläutert, muss für die Aktivierung von PIAB für einen Typ seine Instanz über die PIAB-Factory erstellt werden. Beim Hosten eines WCF-Diensts bieten Sie lediglich den Typ der Dienstklasse an. Dies impliziert, dass die WCF-Laufzeit für das Erstellen einer Dienstinstanz verantwortlich ist, sobald sie benötigt wird. Wie kann also dieses Verhalten geändert werden, sodass eine Dienstklasseninstanz von der PIAB-Factory innerhalb der WCF-Laufzeit erstellt wird? Dies erfordert einen tieferen Einblick in die WCF-Laufzeitarchitektur, um herauszufinden, wie WCF den Dienst instanziiert.

Verteiler
Betrachten Sie die empfangende Anwendung in Abbildung 2. Das Diagramm zeigt eine vereinfachte Ansicht des physischen WCF-Verteilermodells, denn es sind tatsächlich Kanalverteiler und Endpunktverteiler vorhanden. Dieses Detail außer Acht zu lassen, hat auf das Vorhaben hier keine Auswirkung und erleichtert die Untersuchung. Beachten Sie, dass der Verteiler sich innerhalb der Dienstmodellschicht von WCF befindet. Der Verteiler spielt eine wichtige Rolle für WCF, da er für das Deserialisieren der WCF-Nachricht verantwortlich ist, die Dienstinstanz erstellt und schließlich den Aufruf verteilt. Nach dem Erstellen des Verteilerobjekts initialisiert die WCF-Laufzeit ein Instanzverhaltensobjekt, das ein Instanzenanbieterobjekt enthält. Der Instanzenanbieter ist für das Instanziieren des Diensts zuständig. Dieser Prozess wird in Abbildung 3 dargestellt.
Abbildung 3 Dienstinstanziierung (Klicken Sie zum Vergrößern auf das Bild)
Der wesentliche Erweiterbarkeitspunkt für WCF besteht in Verhaltensweisen. Durch Erstellen benutzerdefinierter Verhaltensweisen kann die Weise, in der WCF die Zieldienstinstanz erstellt, verändert werden, wodurch die PIAB-Methode eingerichtet wird. In Abbildung 4 wird dargestellt, wie PIAB beim Erstellen von benutzerdefiniertem Verhalten und eines Instanzenanbieters eingeführt wird.
Abbildung 4 Einführung von PIAB (Klicken Sie zum Vergrößern auf das Bild)
Im Folgenden werden ein benutzerdefiniertes Verhalten und ein Instanzenanbieter erstellt, die an die WCF-Laufzeit angeschlossen werden. Dies wird sowohl mithilfe von Konfigurationsdaten als auch Microsoft® .NET Framework-Attributen illustriert. Sie werden sehen, dass kein Code erforderlich ist, damit WCF unter Verwendung von PIAB Dienste instanziiert. Beachten Sie, dass das hier verwendete benutzerdefinierte Verhalten und der Instanzenanbieter generisch entworfen wurden, damit sie nicht eng an Diensttypen gekoppelt sind. Sie können also den Code herunterladen und für Dienste verwenden, auf die Sie über PIAB eine übergreifende Logik anwenden möchten.

Erweitern von IEndpointBehavior und IContractBehavior
Bevor das benutzerdefinierte Verhalten erstellt wird, muss verstanden werden, wie WCF-Verhaltensweisen erkannt und angewendet werden, vor allem im Kontext der Dienstinstanziierung. Wenn die WCF-Laufzeit die Anweisung erhält, einen Dienst zu hosten, durchschreitet die Dienstmodellschicht den folgenden Prozess:
  1. Suchen von Verhaltensweisen in der Konfiguration.
  2. Suchen von Verhaltensweisen, die als Attribute für die Dienstklasse oder den Vorgang definiert sind.
  3. Erstellen von Kanallistenern für das Behandeln von Messaging und Übertragung.
  4. Anwenden verteilter Verhaltensweisen sowohl für die Konfiguration als auch die in Schritt 1 und 3 beschriebenen Attribute.
Für den vorliegenden Zweck müssen eine Konfiguration oder Attribute definiert werden, die auf den Dienstcode angewendet werden können, damit das benutzerdefinierte Verhalten von der WCF-Laufzeit gefunden werden kann. In Schritt 4 des Prozesses wendet die WCF-Laufzeit das Verteilungsverhalten so an, wie in benutzerdefinierten Verhaltensweisen definiert. Dies bietet die Möglichkeit, den Standardinstanzenanbieter durch den eigenen Instanzenanbieter zu ersetzen.
Was Verhaltensweisen angeht, macht WCF die folgenden Schnittstellen verfügbar: IServiceBehavior, IEndpointBehavior, IContractBehavior und IOperationBehavior. IServiceBehavior behandelt Verhaltensweisen auf Hostebene, und IOperationBehavior ist auf den Umfang des Vorgangs begrenzt. Daher sind sie nicht zum Erstellen einer Dienstinstanz geeignet. Sowohl IEndpointBehavior als auch IContractBehavior erfordern die Implementierung der ApplyDispatchBehavior-Methode, und die Umschaltung erfolgt von dieser Methode aus, wobei der Instanzenanbieter durch den eigenen benutzerdefinierten Instanzenanbieter ersetzt wird.
Wenn also sowohl IEndpointBehavior als auch IContractBehavior den Erweiterbarkeitspunkt für das Erstellen einer Dienstinstanz über PIAB-Factory anbieten, welche der beiden Schnittstellen sollte dann hier verwendet werden? In diesem Fall werden beide verwendet. IEndpointBehavior kann verwendet werden, um das Verteilungsverhalten in einer Konfigurationsdatei zu erweitern, und IContractBehavior kann verwendet werden, um das Verteilungsverhalten als ein .NET-Attribut zu erweitern.

Der Konfigurationsansatz
Die WCF-Konfiguration übernimmt einfach einen Teil der .NET Framework-Konfigurationseinstellungen. In den Dateien „app.config“ oder „web.config“ der .NET-Anwendung, die die WCF-Laufzeit hostet, gibt es einen <system.serviceModel>-Abschnitt, den Sie später sehen werden.
Er ist zwar scheinbar kompliziert, aber wirklich gut an der WCF-Architektur ausgerichtet, bei der Dienst und Client Endpunkte enthalten, die aus Adresse, Bindung und Vertragsdefinitionen bestehen.
Bei Elementen wie <Verhaltensweisen>, <Erweiterungen> und so weiter, handelt es sich einfach um Details, auf die durch <Dienst>- und <Endpunkt>-Elemente verwiesen wird. In der Konfiguration kann die Verhaltensanpassung für ein <Dienst>- oder ein <Endpunkt>-Element durchgeführt werden. Das <Verhaltensweisen>-Element enthält <serviceBehaviors> und <endpointBehaviors>. Da die Serviceebene nicht der geeignete Ort dafür ist, das Verhalten anzupassen, um einen Diensttyp zu instanziieren, wird ein benutzerdefiniertes Endpunktverhalten bereitgestellt.
Wie in Abbildung 5 dargestellt, implementiert das benutzerdefinierte Verhalten die IEndpointBehavior-Schnittstelle. Damit es durch Konfiguration angewendet wird, muss es darüber hinaus von System.ServiceModel.Configuration.BehaviorExtensionElement abgeleitet sein und die BehaviorType-Eigenschaft sowie die CreateBehavior-Methode außer Kraft setzen.
public class PolicyInjectionEndpointBehavior : BehaviorExtensionElement, 
    IEndpointBehavior
{

    public override Type BehaviorType
    {
        get { return typeof(PolicyInjectionEndpointBehavior); }
    }

    protected override object CreateBehavior()
    {
        return new PolicyInjectionEndpointBehavior();
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, 
        EndpointDispatcher endpointDispatcher)
    {
        Type contractType = endpoint.Contract.ContractType;
        endpointDispatcher.DispatchRuntime.InstanceProvider = new 
            PolicyInjectionInstanceProvider(contractType);
    }

    // ...
}

ApplyDispatchBehavior ist die Hauptmethode in IEndpointBehavior, da sie ermöglicht, dass das benutzerdefinierte Endpunktverhalten den WCF-Standardinstanzenanbieter durch den benutzerdefinierten Instanzenanbieter „PolicyInjectionInstanceProvider“ ersetzt. Wie in Abbildung 6 dargestellt, implementiert der benutzerdefinierte Anbieter die Schnittstelle „System.ServiceModel.Dispatcher.IInstanceProvider“. Die GetInstance-Methode wird dann von der WCF-Laufzeit aufgerufen, um die Instanz des Diensttyps abzurufen. Die Implementierung von GetInstance ist einfach. Dazu wird vom PIAB der Enterprise Library ein Richtlinieninjektionsproxy erstellt, der auf dem Diensttyp und dem Vertragstyp (Schnittstelle) der empfangenen Nachricht basiert. Da der Standard-PIAB-Abfangmechanismus den transparenten Proxy von .NET Remoting verwendet, ist ein von MarshalByRefObject abgeleiteter Typ erforderlich, wenn kein spezifischer Vertragstyp (Schnittstelle) angegeben ist. In der Regel stellt diese Anforderung keinen Grund zur Sorge dar, wenn Sie PIAB mit WCF-Diensten verwenden, da WCF-Verträge .NET-Schnittstellen sind.
public class PolicyInjectionInstanceProvider : IInstanceProvider
{
  private Type serviceContractType;
  private static PolicyInjectorFactory fac = new PolicyInjectorFactory();
  private static PolicyInjector injector;

  public PolicyInjectionInstanceProvider(Type t)
  {

    this.serviceContractType = t;
    if (injector == null)
        injector = fac.Create();
    }

  public object GetInstance(InstanceContext instanceContext, 
    System.ServiceModel.Channels.Message message)
  {
    Type type = instanceContext.Host.Description.ServiceType;

    if (serviceContractType != null)
      return injector.Create(type, serviceContractType);
    else
    {
      return injector.Create(type);
    }
  }

  public object GetInstance(InstanceContext instanceContext)
  {
    return GetInstance(instanceContext, null);
  }

public  void  ReleaseInstance(InstanceContextinstanceContext,  object  instance)
  {
    IDisposable disposable = instance as IDisposable;
    if (disposable != null)
    {
      disposable.Dispose();
    }
  }

Da nun diese beiden benutzerdefinierten Typen für IEndpointBehavior und IInstanceProvider bereitstehen, können sie in den Konfigurationscode eingearbeitet werden, wie in Abbildung 7 dargestellt. Beachten Sie, dass im <BehaviorExtensions>-Element die Typdefinition für PolicyInjectionBehavior hinzufügt wird und dass es für diesen Dienst auf den Endpunkt angewendet wird. Zusammen mit der PIAB-Konfiguration können jetzt Richtlinien in den CustomerService-Dienst eingefügt werden, ohne zusätzliche Codezeilen zu schreiben.
<system.serviceModel>
  <services>
    <service name="CustomerService.CustomerService">
      <endpoint 
        address="http://localhost:8000/CustomerService/
          CustomerService.svc"
        binding="wsHttpBinding" 
        bindingConfiguration=""
        contract="CustomerService.ICustomerService"
        behaviorConfiguration="PolicyInjectionEndpointBehavior" />
    </service>
  </services>
  <behaviors>
    <endpointBehaviors>
      <behavior name="PolicyInjectionEndpointBehavior" >
        <PolicyEndpointBehavior />
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <extensions>
    <behaviorExtensions>
      <add
        name="PolicyInjectionEndpointBehavior"
        type="PolicyInjectionBehaviors.PolicyInjectionEndpointBehavior,
          PIBehaviors, Version=1.0.0.0, Culture=neutral,
          PublicKeyToken=null" />
    </behaviorExtensions>
  </extensions>
</system.serviceModel>


Der Attributansatz
In .NET besteht (zusätzlich zur Verwendung einer Konfigurationsdatei) eine andere häufig angewendete Methode zur deklarativen Programmierung, und zwar die Verwendung von Attributen, die als Metadaten in die Assembly kompiliert werden und für die CLR zur Laufzeit sichtbar sind. In Abbildung 8 wird eine Klasse definiert, PolicyInjectionBehaviorAttribute, die die Schnittstellen „System.ServiceModel.Description.IContractBehavior“ und „System.ServiceModel.Description.IContractBehaviorAttribute“ implementiert. Sie muss von der Attributbasisklasse von .NET Framework abgeleitet sein, um als Attribut angewendet zu werden.
[AttributeUsage(AttributeTargets.Class)]
public class PolicyInjectionBehaviorAttribute : Attribute,
  IContractBehavior, IContractBehaviorAttribute {
  public PolicyInjectionBehaviorAttribute() { }

  public Type TargetContract {
    get {
      return null; //return null so we apply to all contracts
    }
  }

  public void AddBindingParameters(ContractDescription description,
    ServiceEndpoint endpoint, 
    BindingParameterCollection parameters) { }

  public void ApplyClientBehavior(ContractDescription description, 
    ServiceEndpoint endpoint, 
    ClientRuntime clientRuntime) { }

  public void ApplyDispatchBehavior(ContractDescription description, 
    ServiceEndpoint endpoint,  
    DispatchRuntime dispatch) {
    Type contractType = description.ContractType;
    dispatch.InstanceProvider = new 
      PolicyInjectionInstanceProvider(contractType);
  }

  public void Validate(ContractDescription description, 
    ServiceEndpoint endpoint) { }
}

Die Implementierung für IContractBehaviorAttribute ist sehr einfach: In der TargetContract-Eigenschaft wird null zurückgegeben, da hier auf alle Verträge abgezielt wird, denen PolicyInjectionBehaviorAttribute angefügt ist. Die Implementierung von ApplyDispatchBehavior ähnelt der von PolicyInjectionEndpointBehavior. Der Standardinstanzenanbieter wird durch den eigenen PolicyInjectionInstanceProvider ersetzt. Dies ist der gleiche Instanzenanbieter, der für das Endpunktverhalten im Konfigurationsansatz verwendet wird. Der Code unten illustriert, wie Richtlinien durch dieses Attribut eingefügt werden. Beachten Sie, dass der Entwickler nichts anderes zu tun hat, als dieses Attribut anzuwenden:
[PolicyInjectionBehavior]
public class DecoratedCustomerService : ICustomerService {
  public Customer GetCustomer(string customerID) {
    return CustomerDAO.GetCustomer(customerID);
  }
}

Der Beispielcode
Um die Verwendung von konfigurationsgesteuerten und attributbasierten Implementierungen benutzerdefinierter WCF-Verhaltensweisen vorzuführen, wurde ein Beispiel erstellt, das beides illustriert. Im Beispiel wurde der Dienstvertrag als eine Schnittstelle namens „ICustomerService“ definiert. Anschließend wurden zwei konkrete Implementierungen dieser Schnittstelle erstellt: CustomerService und DecoratedCustomerService. Der einzige Unterschied zwischen diesen beiden Klassen besteht darin, dass DecoratedCustomerService mit dem PolicyInjectionBehavior-Attribut versehen wurde.
Der Beispielcode umfasst eine Konsolenanwendung, die sowohl CustomerService als auch DecoratedCustomerService hostet. Die Konfiguration der CustomerService-Klasse wurde geändert, um PolicyInjectionEndPointBehavior einzuführen. Außerdem wurde eine Clientanwendung hinzugefügt, die jeden Dienst einmal aufruft, um GetCustomer-Funktionen durchzuführen. Im Folgenden wird callCustomerService angezeigt, doch callDecoratedCustomerService sieht gleich aus:
private static void callCustomerService() {
  CustomerService.CustomerServiceClient client = 
    new CustomerService.CustomerServiceClient();
  Console.WriteLine("Retreiving Customer 1");
  CustomerService.Customer cust = client.GetCustomer("1");
  Console.WriteLine("Retreived Customer, Name: [" + cust.Name + "]");
}
Für beide Ansätze – Konfiguration und Attribut – wird die PIAB-Konfiguration so eingerichtet (siehe Abbildung 9), dass sie einen Logging Handler für Aufrufe, die an die Dienste erfolgen, umfasst. Sie können nach Wunsch andere Handler, z. B. Ausnahmebehandlung und Zwischenspeicherung, hinzufügen. Der Logging Handler in diesem Beispiel schreibt in eine Flatfile namens „audit.log“ ein Überwachungsprotokoll. Nachdem die Aufrufe erfolgt sind, wird „audit.log“ im selben Verzeichnis wie der Ausführungscode erstellt, es sei denn, die Konfiguration wird geändert, damit die Datei an anderer Stelle erstellt wird.
Abbildung 9 „App.config“ in Visual Studio (Klicken Sie zum Vergrößern auf das Bild)
Wie Sie sehen, stellt PIAB eine gute Möglichkeit dar, um die übergreifende und die domänenspezifische Logik voneinander zu trennen, und es kann von WCF-Diensten verwendet werden. Probieren Sie es aus, und laden Sie den Beispielcode unter „msdn.microsoft.com/msdnmag/code08.aspx“ herunter. Sie wenden PIAB auf Ihre WCF-Dienste an, indem Sie der PIBehaviors-Assembly einen Verweis hinzufügen und dann entweder PolicyInjectionEndpointBehavior mittels der Konfiguration oder PolicyInjectionBehaviorAttribute direkt auf Ihre Dienste anwenden.

Hugh Ang ist leitender Lösungsarchitekt bei Avanade und betreut als VP für Anwendungsentwicklung die Unternehmensarchitektur und Anwendungsentwicklungsabteilung eines Kunden. Sie können seinen Blog unter tigerang.blogspot.com

David San Filippo ist Lösungsentwickler bei Avanade und außerdem MCPD Enterprise Application Developer, MCSD.Net und MCDBA. Sie können seinen Blog unter www.mtelligent.com

Page view tracker