C# RESTAPI服务合同模拟 序言部分

C# RESTAPI服务合同模拟 序言部分,c#,api,rest,asp.net-web-api2,servicecontract,C#,Api,Rest,Asp.net Web Api2,Servicecontract,我从事分布式计算机系统的工作,该系统是使用C#和作为进程间通信技术编写的,基本上部署到客户内部网环境中。系统负责执行预配置任务,其中可能涉及多台物理计算机(一台或多台)。系统是用描述的,并且在任务的代码中使用它们是透明的,因此它们中的一些是本地对象还是本地对象并不重要——代码库位于单个位置。此外,该接口的实现在代码中的单一位置。这种方法的优点是,当您以某种方式更改代码时,您能够在代码中反映这种更改 要点是: 在单个代码库1中拥有服务契约及其实现非常重要 问题 现在,我需要以REST方式公开我们的

我从事分布式计算机系统的工作,该系统是使用C#和作为进程间通信技术编写的,基本上部署到客户内部网环境中。系统负责执行预配置任务,其中可能涉及多台物理计算机(一台或多台)。系统是用描述的,并且在任务的代码中使用它们是透明的,因此它们中的一些是本地对象还是本地对象并不重要——代码库位于单个位置。此外,该接口的实现在代码中的单一位置。这种方法的优点是,当您以某种方式更改代码时,您能够在代码中反映这种更改

要点是:

在单个代码库1中拥有服务契约及其实现非常重要

问题 现在,我需要以REST方式公开我们的服务,并使用它执行进程间通信。根据调查结果(以及其他原因),选择使用。使用它,我们需要创建从ApicController继承的类。控制器将使用合同(接口),但不会执行合同

public class ContractsController : ApiController
{
    private IContracts contractsRepository;

    public ContractsController(IContracts contractsRepository)
    {
        this.contractsRepository= contractsRepository;
    }
}
之所以做出此决定,是因为我不希望合同包含特定于Http的内容,如
IHttpActionResult
HttpResponseMessage
,等等。同时,我的控制器必须与其使用的合同兼容,因此,对代理合约的调用必须正确路由到另一端控制器的正确操作,该控制器将调用合约的相同方法。这使得我编写代码(实际上是单元测试)来验证契约和控制器是否同步

我曾尝试使用一些API规范的代码生成器,如,但结果代码是。。。您知道,它适用于hello world示例,而不适用于复杂的应用程序。即使有了这种方法,生成高质量的代码也不简单

如果是WCF服务,一切都会很好,因为我们有
[ServiceContract]
,服务器和客户端也是如此

例子 这里的例子可以说明ApicController和它使用的契约(接口)的同步问题(为了简单起见,这里的if语句)

private void LongRunningAction()
{
i合同1 c1;
i合同2 c2;
如果(/*合同1属于本地计算机*/)
{
c1=container.Resolve();
}
else/*合同1属于远程计算机*/
{
c1=container.Resolve(“RemoteComputerName”).Resolve;
}
如果(/*contract2属于本地计算机*/)
{
c2=container.Resolve();
}
else/*contract2属于远程计算机*/
{
c2=container.Resolve(“RemoteComputerName2”).Resolve;
}
//代码的其余部分将是相同的,因为我们使用
//接口,可以是本地对象或
//代理到远程计算机。将生成代理对象
//Http请求,并将其传递给远程ApiController,
//因此,契约和apicontroller必须同步。
}
问题: 如何确保所使用的控制器和契约()同步

使用哪种方法来避免这种不确定性



1单个代码库并不意味着单个项目或单个程序集。

我弄错了吗,或者这看起来像是使用IoC unity、ninject等的简单依赖注入?我已经在使用IoC了。主要问题是ApiController-s的代码必须与它使用的接口同步,因为我在代码中使用接口进行长时间运行的操作,基本上我不知道接口的当前实例是本地对象还是远程对象的代理。说您正在寻找类似于WCF的行为是否正确,服务实现了一个接口,而客户端依赖于该接口,因此两端都必须遵守该接口?这是可能的。
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.
}