WCF调用不是interfaced方法?

时间:2013-09-25 08:25:19

标签: c# .net wcf

刚遇到一个问题。 我正在努力使wcf服务单元测试准备好或更好所有代码都必须使用unittest进行测试。

Atm它不可能的coze我已经连接到每次使用的crm 2011服务器 所以我用接口替换它。但我想像你使用它一样对WCF进行单元测试 现在我的想法是制作一个公共方法,并给出一个虚假的连接。

现在我的问题是是否可以调用此方法(例如:ConnectionHandler),即使它不在界面中?

这看起来像这样:

public interface IWCF
{
    [OperationContract]
    bool method1();

    [OperationContract]
    bool method2();
}

public class WCF:  IWCF
{

    public bool method1(){
    ...
    }

    public bool method2(){
    ...
    }

    private connection connectionHandler;
    public connection ConnectionHandler(Iconnection con){
        if(con != null){
            connectionHandler = con;
        } else {
            connectionHandler = takedefault;
        }
    }
}

修改
啊,我忘了告诉这个:我实际上有安全性,我不希望任何人都可以通过不同的连接到服务器它仅用于单元测试目的。

2 个答案:

答案 0 :(得分:1)

可以调用此方法,可以将接口强制转换为具体对象。但这会损害调用代码,调用代码不应该知道服务的实现细节。

我会建议您使用constrcutor注射,这样您的服务实现将如下所示:

 public interface IWCF
{
    [OperationContract]
    bool method1();

    [OperationContract]
    bool method2();
}

public class WCF:  IWCF
{
    private connection connectionHandler;

    public WCF(Iconnection con)
    {
         if(con != null){
            connectionHandler = con;
        } else {
            connectionHandler = takedefault;
        }
    }

    public bool method1(){
    ...
    }

    public bool method2(){
    ...
    }



}

在这种情况下,如果您在客户端上使用constrcutor注入,客户端代码将不知道服务实现的详细信息

答案 1 :(得分:0)

任何精心设计的代码片段的一个重要特性是您明确了解向客户公开的功能。这成为面向服务的应用程序的一个关键特性,因为您以标准化的方式公开您的功能以供外部客户使用。

调用不属于接口的方法原则上是不好的,因为您现在正在编程实现而不是接口。很高兴WCF知道这一点,并且不会让你使用不在界面上的方法,因为它没有用OperationContract属性修饰。

关于你的代码 - 我不确定你想要实现的是什么 - 设置一个客户端(我假设是这样的)像数据库连接这样的东西让我有点不安(一开始这意味着您的服务正处于违反Service statelessness principle的状态。这并不意味着你所做的事情一定是错的,但你应该发现你很少在一个设计良好的应用程序中违反这一点。

也就是说,如果您希望向不同的客户端公开不同的功能区域,正确的方法是在您的服务上公开代表不同合同的端点:

[ServiceContract]
public interface IWCF
{
    [OperationContract]
    bool method1();

    [OperationContract]
    bool method2();
}

 [ServiceContract]
public interface IConnectionWCF
 {
     [OperationContract]
     bool SetConnection(string connection);
 }

 public class WCF : IWCF, IConnectionWCF
{
     public bool method1()
     {
        ...
     }

     public bool method2()
     {
        ...
     }

     public bool SetConnection(string connection)
     {
         ...
     }
}

您还需要注意,WCF服务收到的所有内容必须首先由客户端序列化,通过网络发送,并在服务器上反序列化。你在这里处理具体的课程 - 而不是抽象。将一个接口(例如Iconnection)作为参数传递给服务调用在面向服务的环境中并没有任何意义。

关于单元测试 - 请记住,基本上类WCF只是一个普通的老类。您可以单独测试此类,而不是它是一个WCF服务。您不应该在单元测试中设置任何服务托管功能 - 您要检查您编写的代码是否正确 - WCF堆栈已经过Microsoft测试。

修改

响应您的评论,如建议here,您应该使用构造函数注入来在实例化类时设置连接对象。然后,这就提出了如何控制WCF服务实例化的问题。您需要实施IInstanceProvider,或者有关更详细的实施,请参阅here。这样,当您在WCF中托管服务时,使用IInstanceProvider,在测试时,只需将伪连接对象传递给构造函数。

修改

为了澄清,这个类的单元测试将类似于:

[TestClass]
public class UnitTests
{
    [TestMethod]
    public void Test()
    {
        Iconnection connection = new FakeConnection();
        WCF classUnderTest = new WCF(connection);

        //Run test logic
    }
}