当谈到 WCF 时,我缺乏经验,而且我真的无法找到一种无痛的方式来模拟 WCF 服务。
情况:客户端和服务器都可以访问定义服务的接口,如下所示:
public interface ICustomerService
{
[OperationContract]
Customer GetCustomer(int id);
}
现在,我的第一个问题是,您是否有理由不让客户端和服务器共享在共享库中定义服务的相同接口类型。当然,如果服务的使用者不是 .NET,或者如果您将其暴露给没有库的第三方,则根本不可能,但我在可能的情况下分享它并不会伤害那些其他场景,对吧?
其次,如果这不是一个坏主意,我实际上如何让 Visual Studio 重用服务接口?我设法通过检查来让它共享Customer
类型Re-use types
,这也是在共享程序集中定义的,但它仍然重新生成接口。
但是,不管这些问题如何,我如何让客户端变得可模拟?如果我通过 VS 生成的服务引用,我会得到一个可以使用的具体类型,但我不希望我的代码直接引用该类型,我想与一个接口交谈。如果我将生成的客户端公开为ICustomerService
有效的,我没有Close
方法,因为接口没有定义它。
我还想到了以下方法,完全放弃了自动生成客户端,自己编写客户端,因为它很简单:
public interface IServiceClient<T>
{
void Close();
T Services { get; }
}
public class CustomerServiceClient : ClientBase<ICustomerService>, ICustomerService, IServiceClient<ICustomerService>
{
public Customer GetCustomer(int id)
{
return base.Channel.GetCustomer(id);
}
public ICustomerService Services
{
get { return this; }
}
}
这行得通,我可以将它作为IServiceClient<ICustomerService>
我的 IoC 容器公开,但需要注意的是,现在是这样,并且当接口更改client.Services.GetCustomer(1)
时,我已经失去了轻松重新生成客户端的好处。ICustomerService
添加的代码很简单,但维护它可能仍然很烦人。
另一种可能性是利用生成的类是partial
. 当我这样做时它也有效:
interface ICloseable
{
void Close();
}
interface ClientInterface : ICustomerService, ICloseable
{
}
partial class CustomerServiceClient : IClientInterface
{
}
但这创建了一个虚假的类和接口,这不是灾难,但不是很漂亮。
在我走任何一条路线之前,有什么明显的我忽略的吗?