2012-04-19 3 views
7

WCF 클라이언트에 추가 할 WCF 동작 확장이 있습니다. 그러나 클라이언트는 프로그래밍 방식으로 구성됩니다. 엔드 포인트 주소는 다를 수 있지만 유형을 알고 있습니다. 프로그래밍 방식으로나 설정 파일 (기본 설정)에서 동작을 추가 할 수는 있지만 구성 파일에서만 일부 구성을 전달해야합니다.프로그래밍 방식으로 생성 된 끝점에서 WCF 동작 확장을 선언적으로 구성하십시오.

공용 동작 (machine.config)에서이 작업을 원하지 않습니다.

나는 동작을 프로그래밍

endpoint.Behaviors.Add(new MyCustomBehavior()) 

을 추가 할 수 있습니다하지만 오히려 설정에서 그것을 할 거라고, 그래서 나는 거기뿐만 아니라 확장을 구성 할 수 있습니다.

프로그래밍 방식으로 작성된 끝점에 끝점 동작 확장을 추가하고 구성하여 클라이언트 끝점을 프로그래밍 방식으로 구성하는 동안 형식이나 인터페이스 만 알면됩니까?

<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> 

은 물론 나는 다른 섹션의 설정을 놓고, 거기에 읽어 내 행동을 가지고 있지만, 가능하면 차라리 WCF 시설을 사용할 줄 수 있습니다.

답변

10

이렇게하려면 끝점에 동작 구성 확장을 만들어야합니다. 이를 수행하는 방법에 대한 자세한 내용은 http://blogs.msdn.com/b/carlosfigueira/archive/2011/06/28/wcf-extensibility-behavior-configuration-extensions.aspx을 확인하십시오.

업데이트 : 지금 귀하의 문제를 확인합니다. 구성에서 선언 된 동작을 코드를 통해 생성 된 끝점에 추가하는 직접적인 방법은 없습니다. 그래도 여전히 할 수는 있지만 실제로 코드를 통해 생성 된 끝점에 끝점 동작을 추가하기 위해 동작 구성 확장 (메서드가 보호 됨)의 CreateBehavior 메서드에 액세스하려면 약간의 리플렉션을 사용해야합니다. 아래 코드는이 작업을 수행하는 방법을 보여줍니다.

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(); 
    } 
} 

그리고이 코드의 구성 :

<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

내 행동은 이미 행동 확장,의 매개 변수에주의를 구현 ... 미안 내 질문은 분명하지만, 모든 아니었다 경우 예제에서 찾을 수있는 behaviorConfiguration은 선언적으로 구성된 엔드 포인트 (서비스 또는 클라이언트)에 추가됩니다. 프로그래밍 방식으로 생성 된 특정 계약을 사용하여 엔드 포인트에 추가하는 방법을 알아야합니다. – DanO

+0

알았어. 전에는 이해 못 했어. 이에 대한 답변을 업데이트했으며 https://github.com/carlosfigueira/WCFQuickSamples/tree/master/WCFForums/QuickCode1에서 전체 코드를 찾을 수 있습니다. – carlosfigueira

+0

해결 방법을 제공하기 위해 노력해 주셔서 감사합니다! 이미 더 쉽게 할 수있는 것을 원하는대로 포기했지만, 프로젝트를 다시 방문하면 코드가 매우 도움이 될 것입니다! – DanO