簡體   English   中英

在以編程方式構造的端點上聲明性地配置 WCF 行為擴展

[英]Declaratively configure WCF behavior extension on programmatically constructed endpoint

我有一個 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 工具。

為此,您需要為端點創建行為配置擴展。 有關如何執行此操作的更多信息,請查看https://docs.microsoft.com/en-us/archive/blogs/carlosfigueira/wcf-extensibility-behavior-configuration-extensions

更新:我現在看到您的問題。 沒有直接的方法可以將在配置中聲明的行為添加到通過代碼創建的端點。 不過,您仍然可以這樣做,但是您需要使用一些反射來訪問行為配置擴展的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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM