【问题标题】:Which is better practice, one client instance for the class or one in each method?哪个是更好的实践,类的一个客户端实例或每个方法中的一个?
【发布时间】:2013-07-21 19:35:30
【问题描述】:

假设我的客户端应用中有一个名为 DataService 的类。此类有许多调用 WCF 服务的方法。

我想知道哪个是更好的做法:

  1. 在类中创建WebServiceClient的实例,在创建类的实例时初始化,供方法使用,例如:

    public class DataService
    {
        MyWebServiceClient client = new MyWebServiceClient();
    
        public void Method1()
        {
            var v = client.Operation1();
    
            ...
        }
    
        public void Method2()
        {
            var v = client.Operation2();
    
            ...
        }
    }
    
  2. 或者,在类的每个方法中创建并初始化一个WebServiceClient的实例,例如:

    public class DataService
    {      
        public void Method1()
        {
            var client = new MyWebServiceClient();
            var v = client.Operation1();
    
            ...
        }
    
        public void Method2()
        {
            var client = new MyWebServiceClient();
            var v = client.Operation2();
    
            ...
        }
    }
    
  3. 还有第三种选择,就是在类中声明,在每个方法中初始化:

    public class DataService
    {
        MyWebServiceClient client;
    
        public void Method1()
        {
            client = new MyWebServiceClient();
            var v = client.Operation1();
    
            ...
        }
    
        public void Method2()
        {
            client = new MyWebServiceClient();
            var v = client.Operation2();
    
            ...
        }
    }
    

【问题讨论】:

  • 解决方案已经够了;您正在解决的业务问题是什么?解决方案的选择取决于它要解决的问题。
  • 因为第三个选项...,我的一部分想要对此投反对票
  • 我只使用构造函数 DI(Autofac 运行良好),其余的不用担心。使用像 Autofac 这样的容器可以让我简单地控制高级生命周期并处理依赖关系图而无需很多工作。现在,如果client 依赖于方法调用本身的某些东西,我可能会使用 Autofac“函数”(实际上是一个隐式工厂)方法..
  • 请记住,根据服务对象是按调用还是按会话创建的,方法 1 和 2 可能具有不同的语义。
  • 如果他们不这样做,因为服务是无状态的:掷硬币选择哪个。看到他们做同样的事情,这是自行车棚的论据材料。

标签: c# .net wcf oop


【解决方案1】:

当你像这样依赖另一个类时,通常最好将它的构造分离出来并传入(或者可能使用依赖注入)。这使您的 DataService 类更易于测试,您可以通过这种方式更轻松地模拟您的 WebServiceClient。

考虑类似...

public class DataService
{

    public DataService(MyWebServiceClient client)
    {
        .... //Assign it to a private var...
    }

}

【讨论】:

    【解决方案2】:

    我会使用构造函数注入和每个类一个实例,如下所示:

    public class DataService
        {
            IMyWebServiceClient _client;
    
             public  DataService(IMyWebServiceClient client)
              {
               _client=client
               }
    
              public  DataService():this(new MyWebServiceClient())
               {
    
               }
    
    
            public void Method1()
            {
    
                var v = _client.Operation1();
    
                ...
            }
    
            public void Method2()
            {
    
                var v = _client.Operation2();
    
                ...
            }
        }
    

    【讨论】:

    • 构造函数注入?
    • 构造函数注入意味着您将拥有一个带有外部依赖参数的构造函数,并且您将使用此构造函数在单元测试期间注入模拟,也将被 Iocs 使用
    • Contractor 注射是您向现场提供快乐药物的承包商注射的地方,以便他们降低费率 :)
    • @SimonWhitehead 你可以编辑它而不是开玩笑,但很有趣
    【解决方案3】:

    我在较旧的应用程序中最常使用方法 3。但是最近看到了一些代码,其中您有对象声明但实例化是由诸如 Spring 之类的框架完成的。实例保存在容器内。不过,仍在学习该过程。

    public class DataService
    {
        MyWebServiceClient client;
    
        public void Method1()
        {
            var v = client.Operation1();
    
            ...
        }
    
        public void Method2()
        {
            var v = client.Operation2();
    
            ...
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-27
      • 2013-12-28
      • 2018-03-03
      • 1970-01-01
      • 1970-01-01
      • 2012-11-07
      相关资源
      最近更新 更多