【问题标题】:WCF Client - Best PractiseWCF 客户端 - 最佳实践
【发布时间】:2012-09-17 15:35:51
【问题描述】:

我只是想听听您对 WCF 客户端实施的意见。

我有一个提供多种服务的服务器,例如 SecurityManager。 该服务在接口 ISecurityManager 中定义,并在 Class SecurityManager 中实现。

到目前为止一切都很好。 在客户端,我想通过一个单独的类来实现服务调用。我的问题是我是否也在实现相同 ISecurityManager 接口的 SecurityManager 类中执行此操作?

这里最好的做法是什么?

【问题讨论】:

    标签: c# wcf


    【解决方案1】:

    Visual Studio 生成器

    您可以要求 Visual Studio 为您构建客户端,右键单击您的客户端项目并添加 Service Reference。有一个对话框,您可以在其中键入您的服务 url 或从解决方案中发现它。

    创建客户端

    您可以构建继承自ClientBase<ISecurityManager>, ISecurityManager 的客户端类。作为此客户端类的操作示例:

    public void ExampleMethod(int id)
    {
       Channel.ExampleMethod(id);
    }
    

    像一个真正的男人一样

    或者没有任何客户端类,直接调用它:

    ServiceInvokerinvoker invoker = new ServiceInvoker(); 
    var result = invoker.InvokeService<ISecurityManager, ReturnType>(     proxy => proxy.ExampleMethod(1) ); 
    

    最后两个选项假设您已经配置了ISecurityManager 客户端:

    <client>     
    <endpoint name="ServiceName" 
    address="http://ServiceName.test/Service" 
    binding="basicHttpBinding"   
    contract="ISecurityManager" /> 
    </client> 
    

    【讨论】:

      【解决方案2】:

      我建议使用通用 Wrapper 进行 WCF 调用。 因此,每次您需要进行 WCF 调用时,您都可以这样做:

      var invoker = new ServiceInvoker();
              var result = invoker.InvokeService<ISecurityManager, MyObjectReturnType>(
                  proxy => proxy.DoSomething(myParameters));
              return result;
      

      我使用 ServiceInvoker 创建通道并管理内部可能发生的任何异常。它使用 ISecurityManager 合约创建一个通道,返回类型为 MyObjectReturnType 和操作 DoSomething(来自 ISecurityManager 合约的方法)。 您可以将此解决方案与您的所有接口一起使用,而无需任何额外的类实现!

      InvokeService 应该是这样的:

      public TResult InvokeService<TServiceContract, TResult>(Func<TServiceContract, TResult> invokeHandler) where TServiceContract : class
          {
              ICommunicationObject communicationObject;
              var arg = CreateCommunicationObject<TServiceContract>(out communicationObject);
              var result = default(TResult);
              try
              {
                  result = invokeHandler(arg);
              }
              catch (Exception ex)
              {
                  Logger.Log(ex);
                  throw;
              }
      
              finally
              {
                  try
                  {
                      if (communicationObject.State != CommunicationState.Faulted)
                          communicationObject.Close();
                  }
                  catch
                  {
                      communicationObject.Abort();
                  }
              }
              return result;
          }
      
      private TServiceContract CreateCommunicationObject<TServiceContract>(out ICommunicationObject communicationObject)
              where TServiceContract : class
          {
              //Create the Channel
              // ICommunicationObject is an out parameter for disposing purposes 
              return channel;
          }
      

      【讨论】:

      【解决方案3】:

      要“通过单独的类”实现服务调用,您只需使用 svcutil.exe 或 Visual Studio 从正在运行的服务实例生成服务引用。

      这将从您的服务合同中生成一组类型,这些类型将与包含您的服务合同和实施的程序集完全“分离”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-25
        • 1970-01-01
        • 2012-09-18
        • 1970-01-01
        • 2021-03-15
        • 2020-08-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多