2012-04-19 12 views
7

Mam rozszerzenie zachowania WCF, które chciałbym dodać do klienta WCF. Jednak klient jest konstruowany programowo. Adres punktu końcowego może się różnić, ale znam typ. Mogę dodać zachowanie programowo lub w pliku konfiguracyjnym (zalecane), ale muszę przekazać trochę konfiguracji tylko w pliku konfiguracyjnym.Deklaracyjnie skonfiguruj rozszerzenie zachowania WCF na programowo skonstruowanym punkcie końcowym

Nie chcę tego we wspólnych zachowaniach (machine.config).

mogę dodać zachowanie programowo

endpoint.Behaviors.Add(new MyCustomBehavior()) 

Ale wolałbym zrobić to w config, więc mogę skonfigurować rozszerzenie również tam.

Czy można deklaratywnie dodawać i konfigurować rozszerzenie zachowania punktu końcowego do skonstruowanego programowo punktu końcowego, znając tylko typ lub interfejs, pozostawiając programowy punkt końcowy klienta do skonstruowania?

<system.serviceModel> 
    <client> 
    <!-- Created programmatically --> 
    </client> 
<extensions> 
    <behaviorExtensions> 
    <add name="MyCustomBehavior" type="namespace.CustomBehaviors", MyAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
    </behaviorExtensions> 
</extensions> 
    <behaviors> 
    <endpointBehaviors> 
     <behavior name="MyCustomBehavior"> 
     <MyCustomBehavior MyImportantBehaviorParam1="foo" /> 
     </behavior> 
    </endpointBehaviors> 
    </behaviors> 
</system.serviceModel> 

Oczywiście mógłbym umieścić config w innym dziale, i moje zachowanie czytać to tam, ale raczej bym w miarę możliwości korzystać z usług WCF.

Odpowiedz

10

Aby to zrobić, musisz utworzyć rozszerzenie konfiguracji zachowania dla swojego punktu końcowego. Aby uzyskać więcej informacji o tym, jak to zrobić, sprawdź http://blogs.msdn.com/b/carlosfigueira/archive/2011/06/28/wcf-extensibility-behavior-configuration-extensions.aspx.

Aktualizacja: Widzę teraz Twój problem. Nie ma bezpośredniego sposobu dodawania do punktu końcowego utworzonego za pomocą kodu zachowania zadeklarowanego w konfiguracji. Nadal możesz to zrobić, ale musisz skorzystać z refleksji, aby uzyskać dostęp do metody CreateBehavior metody rozszerzenia konfiguracji zachowania (metoda jest chroniona), aby faktycznie utworzyć zachowanie punktu końcowego, aby dodać go do punktu końcowego utworzonego za pomocą kodu. Poniższy kod pokazuje, jak można to zrobić.

public class StackOverflow_10232385 
{ 
    public class MyCustomBehavior : IEndpointBehavior 
    { 
     public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) 
     { 
      Console.WriteLine("In {0}.{1}", this.GetType().Name, MethodBase.GetCurrentMethod().Name); 
     } 

     public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) 
     { 
      Console.WriteLine("In {0}.{1}", this.GetType().Name, MethodBase.GetCurrentMethod().Name); 
     } 

     public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) 
     { 
      Console.WriteLine("In {0}.{1}", this.GetType().Name, MethodBase.GetCurrentMethod().Name); 
     } 

     public void Validate(ServiceEndpoint endpoint) 
     { 
      Console.WriteLine("In {0}.{1}", this.GetType().Name, MethodBase.GetCurrentMethod().Name); 
     } 
    } 

    public class MyCustomBehaviorExtension : BehaviorExtensionElement 
    { 
     public override Type BehaviorType 
     { 
      get { return typeof(MyCustomBehavior); } 
     } 

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

    [ServiceContract] 
    public interface ITest 
    { 
     [OperationContract] 
     string Echo(string text); 
    } 
    public class Service : ITest 
    { 
     public string Echo(string text) 
     { 
      return text; 
     } 
    } 

    public static void Test() 
    { 
     string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; 
     ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); 
     ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), ""); 

     var configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
     ServiceModelSectionGroup smsg = configuration.GetSectionGroup("system.serviceModel") as ServiceModelSectionGroup; 
     EndpointBehaviorElement endpointBehaviorElement = smsg.Behaviors.EndpointBehaviors["MyCustomBehavior_10232385"]; 
     foreach (BehaviorExtensionElement behaviorElement in endpointBehaviorElement) 
     { 
      MethodInfo createBehaviorMethod = behaviorElement.GetType().GetMethod("CreateBehavior", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Type.EmptyTypes, null); 
      IEndpointBehavior behavior = createBehaviorMethod.Invoke(behaviorElement, new object[0]) as IEndpointBehavior; 
      endpoint.Behaviors.Add(behavior); 
     } 

     host.Open(); 
     Console.WriteLine("Host opened"); 

     ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress)); 
     ITest proxy = factory.CreateChannel(); 
     Console.WriteLine(proxy.Echo("Hello")); 

     ((IClientChannel)proxy).Close(); 
     factory.Close(); 

     Console.Write("Press ENTER to close the host"); 
     Console.ReadLine(); 
     host.Close(); 
    } 
} 

i konfiguracji dla tego kodu:

<system.serviceModel> 
    <extensions> 
     <behaviorExtensions> 
      <add name="myCustomBehavior_10232385" type="QuickCode1.StackOverflow_10232385+MyCustomBehaviorExtension, QuickCode1"/> 
     </behaviorExtensions> 
    </extensions> 
    <behaviors> 
     <endpointBehaviors> 
      <behavior name="MyCustomBehavior_10232385"> 
       <myCustomBehavior_10232385/> 
      </behavior> 
     </endpointBehaviors> 
    </behaviors> 
</system.serviceModel> 
+0

Moje zachowanie już Realizuje Behavior Extension, zwróć uwagę na parametr w ... Przepraszam, jeśli moje pytanie nie było jasne, ale we wszystkich przykłady, które mogę znaleźć, konfiguracja behawioralna jest dodawana do konstruktywnie skonstruowanego punktu końcowego (usługa lub klient). Muszę wiedzieć, jak dodać go do punktów końcowych z daną umową, która jest tworzona programowo. – DanO

+0

Rozumiem, nie rozumiałem tego wcześniej. Zaktualizowałem odpowiedź tym, i możesz znaleźć pełny kod na https://github.com/carlosfigueira/WCFQuickSamples/tree/master/WCFForums/QuickCode1. – carlosfigueira

+0

Dziękujemy za podjęcie wysiłku w celu zapewnienia tego rozwiązania! Zrezygnowałem już z robienia tego, co chciałem, na rzecz tego, co było łatwiejsze, ale jeśli wrócę do tego projektu, twój kod będzie bardzo pomocny! – DanO

Powiązane problemy