ChannelFactory <t>和ClientBase <t>之间的区别是什么

时间:2017-06-17 14:11:07

标签: wcf

请您解释一下,ChannelFactory和ClientBase之间的区别是什么,以及哪个更适合用于SelfHost客户端 - 服务器应用程序。

using(ChannelFactory<MyInterface> cf = new ChannelFactory<MyInterface>("Endpoint From Web.Config")){} 

public class MyClient : ClientBase<MyInterface>, MyInterface {}

由于

1 个答案:

答案 0 :(得分:1)

让我们有一个界定合同的界面:

[ServiceContract]
public interface TheInterface
{
    [OperationContract]
    string DoWork( string Work );
}

ChannelFactory自动创建仅实现接口的代理。

 var factory = new ChannelFactory<TheInterface>( new BasicHttpBinding() );
 var address = new EndpointAddress( "http://..." );
 var client = factory.CreateChannel( address );

 // there are no other methods on the "client" reference
 // than the interface's DoWork method
 client.DoWork( "foo" );

另一方面,继承自ClientBase的类不仅实现了接口,还暴露了可用于改变客户端行为的多个附加属性。

public class TheInterfaceProxy : ClientBase<TheInterface>, TheInterface
{
    public TheInterfaceProxy( Binding binding, EndpointAddress address ) : base( binding, address ) { }

    public string DoWork( string Work )
    {
        return this.Channel.DoWork( Work );
    }
}

然后

var address = new EndpointAddress( "http://..." );

using ( var client = new TheInterfaceProxy( new BasicHttpBinding(), address ) )
{
     // DoWork is here
     // but multiple other members are there too
     // for example - applying a custom endpoint behavior:
     client.Endpoint.EndpointBehaviors.Add( new InspectorBehavior() );

     client.DoWork( "bar" );
}

其中使用示例简单行为来检查客户端的传入/传出消息

class InspectorBehavior : IEndpointBehavior
{
    #region IEndpointBehavior Members

    public void AddBindingParameters( ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters )
    {
    }

    public void ApplyClientBehavior( ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime )
    {
        clientRuntime.ClientMessageInspectors.Add( new DispatchInspector() );
    }

    public void ApplyDispatchBehavior( ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher )
    {
    }

    public void Validate( ServiceEndpoint endpoint )
    {
    }

    #endregion
}

class DispatchInspector : IClientMessageInspector
{
    #region IClientMessageInspector Members

    public void AfterReceiveReply( ref Message reply, object correlationState )
    {
        MessageBuffer buffer = reply.CreateBufferedCopy( Int32.MaxValue );
        reply = buffer.CreateMessage();
        Console.WriteLine( "Receiving:\n{0}", buffer.CreateMessage().ToString() );
    }

    public object BeforeSendRequest( ref Message request, IClientChannel channel )
    {
        MessageBuffer buffer = request.CreateBufferedCopy( Int32.MaxValue );
        request = buffer.CreateMessage();
        Console.WriteLine( "Sending:\n{0}", buffer.CreateMessage().ToString() );

        return null;
    }

    #endregion
}

没有答案哪个更好,但是:

  • 如果除了默认行为之外你不需要任何东西 - 你可以坚持ChannelFactory,这是两个中最简单的
  • 除了任何额外的内容,请使用ClientBase,它需要额外的课程,但