使用一个客户端实例作为类的方法,还是每个方法中都使用一个客户端实例,哪种做法更好?

4

假设我在我的客户端应用程序中有一个名为 DataService 的类。这个类有许多方法,这些方法调用了一个 WCF 服务。

我想知道哪种做法更好:

  1. To create an instance of WebServiceClient in the class, which is initialized when an instance of the class is created, and is used by the methods, e.g:

    public class DataService
    {
        MyWebServiceClient client = new MyWebServiceClient();
    
        public void Method1()
        {
            var v = client.Operation1();
    
            ...
        }
    
        public void Method2()
        {
            var v = client.Operation2();
    
            ...
        }
    }
    
  2. Or, to create and initialize an instance of WebServiceClient in each method of the class, e.g:

    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. There is also a third option, which is to declare in class and initialize in each method:

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

6
别再谈解决方案了,你正在解决哪个商业问题?选择解决方案取决于它所解决的问题。 - Pieter Geerkens
4
有一部分我想要因为“第三个选项”而给这个帖子点踩... - Austin Salonen
1
我只使用构造函数依赖注入(Autofac 运行良好),并不用担心其他方面。使用像 Autofac 这样的容器可以让我简单地控制高级生命周期并处理依赖关系图,而无需进行大量工作。现在,如果 client 在方法调用本身中有依赖项,我可能会使用 Autofac 的“Function”(有效地是隐式工厂)方法。 - user2246674
2
请记住,根据服务对象是每次调用还是每个会话创建,方法1和2的语义可能不同。 - millimoose
1
如果它们不这样做是因为服务是无状态的:抛硬币选择任何一个。既然它们都一样,这只是无关紧要的争论材料。 - millimoose
显示剩余2条评论
3个回答

8
当您有一个像这样依赖于另一个类的情况时,通常最好将其构造分离并传递进去(或者可能使用依赖注入)。这样可以使您的DataService类更容易进行测试,您可以更轻松地模拟您的WebServiceClient。
考虑一些类似于以下的内容...
public class DataService
{

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

}

1

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

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

            ...
        }
    }

构造函数注入? - Austin Salonen
构造函数注入意味着您将具有带有外部依赖项参数的构造函数,并使用此构造函数在单元测试期间注入模拟,并且将被Iocs使用。 - Dan Hunex
2
承包商注射是指您注射承包商,让他们在现场使用快乐药物,以便降低他们的费用 :) - Simon Whitehead
@SimonWhitehead 你本可以编辑它而不是开玩笑,不过还是挺有趣的。 - Dan Hunex

0

在旧应用程序中,我经常使用方法3。但最近看到一些代码,其中对象声明是由Spring等框架完成实例化的。该实例被保留在容器内。虽然仍在学习该过程。

public class DataService
{
    MyWebServiceClient client;

    public void Method1()
    {
        var v = client.Operation1();

        ...
    }

    public void Method2()
    {
        var v = client.Operation2();

        ...
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接