序言
本人从事分布式计算机系统,使用C#和.Net Remoting作为进程间通信技术编写,基本部署到客户内网环境。系统负责执行可能涉及多台物理计算机(一台或多台)的预配置任务。该系统是用Interfaces描述的,并且在任务代码中使用它们是透明的,因此它们中的一些是代理对象还是本地对象都没有关系 - 代码库位于单一位置。此外,该接口的实现在代码中的单一位置。这种方法的优点是,当您以某种方式更改接口时- 您可以在代码中反映这种更改。
要点是:
在单一代码库1中拥有服务合同及其实施很重要。
问题
至于现在,我需要以 REST 方式公开我们的服务,并使用它进行进程间通信。根据WCF 和 ASP.NET Web API(以及可能的其他原因),选择使用ASP.NET Web API。使用它,我们需要创建从 ApiController 继承的类。控制器将使用合约(接口),但不会实现它。
public class ContractsController : ApiController
{
private IContracts contractsRepository;
public ContractsController(IContracts contractsRepository)
{
this.contractsRepository= contractsRepository;
}
}
做出这个决定是因为我不希望合约包含 Http 特定的,比如IHttpActionResult
,HttpResponseMessage
等。同时我的控制器必须与它使用的合约兼容,因此对代理合约的调用必须正确路由到正确的另一端控制器的操作,它将调用合同的相同方法。这让我编写代码(实际上是单元测试)来验证合约和控制器是否同步。
我曾尝试通过 API 规范使用一些代码生成器,如swagger、raml,但生成的代码是……你知道,它适用于 hello-world 示例,而不适用于复杂的应用程序。即使使用模板驱动——生成优质代码也并不简单。
如果它是 WCF 服务 - 一切都会很棒,因为我们有[ServiceContract]
,服务器和客户端都是一样的。
例子
这里的示例可以演示 ApiController 和它使用的合约(接口)的同步问题(为简单起见,此处使用 if 语句)
private void LongRunningAction()
{
IContract1 c1;
IContract2 c2;
if (/* contract1 belongs to local computer */)
{
c1 = container.Resolve<IContract1>();
}
else /* contract1 belongs to remote computer */
{
c1 = container.Resolve<IRemoteFactory>("RemoteComputerName").Resolve<IContract1>;
}
if (/* contract2 belongs to local computer */)
{
c2 = container.Resolve<IContract2>();
}
else /* contract2 belongs to remote computer */
{
c2 = container.Resolve<IRemoteFactory>("RemoteComputerName2").Resolve<IContract2>;
}
// Rest of the code will be the same because we operate with
// interfaces, which could be either local objects or
// proxy to the remote computer. Proxy objects will generate
// the Http request, and it will be passed to the remote ApiController,
// so the contracts and ApiControllers must be in sync.
}
问题
如何确保他们使用的控制器和合同(接口)是同步的?
使用哪种方法来避免这种不确定性?
1单一代码库并不意味着单一项目或单一程序集。