C#,按顺序使用多个外部API&Services

时间:2017-10-12 16:50:58

标签: c# web-services design-patterns soap

我正在寻找有关如何为我想要创建的网站实施某些内容的建议。

我想要使用一些内部托管的SOAP服务,但我想知道最好的方法是什么,起因是在下一个请求中需要响应中的某些元素。我可以(以前做过)管理过这个,但它不是很干净或者很清楚。

我已经和一些同事交谈,并且我已经提到了责任链(CoR)设计模式,但我不能100%确定这是否正是我所需要的,如果它鉴于我目前对此有一定的了解,我似乎无法想象这会如何发挥作用。

流程将是这样的:

  

用户填写一个表单,其中发布数据项 FirstName LastName DOB 邮政编码

Service1 is then called with the above details in the request body
  

Service1响应其他一些数据,EG

<CustomerId>99999</CustomerId>
  

然后需要使用一个本身需要CustomerId节点和其他节点的主体构建Service2。

我对CoR的理解是,它会将请求传递给它,直到它能找到处理它的东西为止,我试图了解这是否是正确使用的模式,如果我需要使用其他东西?

我还假设最佳做法是将我在服务电话中收到的项目映射到对象中?

1 个答案:

答案 0 :(得分:0)

是的,我认为CoR适合你。

这可能是一种实施方式:

public class Request
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Postcode { get; set; }
}

public class Response : Request
{
}

public class EntryPointService
{
    private readonly IService1 _service1;

    public EntryPointService(IService1 service1, IService2 service2, IService3 service3)
    {
        _service1 = service1;

        // Create your chain
        service1.RegisterNext(service2);
        service2.RegisterNext(service3);
        service3.RegisterNext(EndServiceHandler.Instance);
    }

    public Response Post(Request request)
    {
        // start your workflow
        var response =  _service1.TryToProcess(request);

        return response;
    }
}

public interface IChainProcessor
{
    void RegisterNext(IChainProcessor next);
    Response TryToProcess(Request request);
}

public interface IService1: IChainProcessor
{
}

public interface IService2: IChainProcessor
{
}

public interface IService3 : IChainProcessor
{
}


public class Service1: IService1
{
    private IChainProcessor _next = EndServiceHandler.Instance;

    public void RegisterNext(IChainProcessor next)
    {
        _next = next;
    }

    public Response TryToProcess(Request request)
    {
        var canProcess = true; // Add your validation logic here.

        if (!canProcess) return _next.TryToProcess(request);

        try
        {
            // Do your service1 workflow.

            // DoSomething1(request);
            // DoSomething2(request);         
        }
        catch (ChainProcessException e)
        {
            // If something is wrong, Log and stop your workflow.
            return new Response(); // <= add your return info here.
        }

        return _next.TryToProcess(request);
    }
}

// Null object pattern: End chain element
public class EndServiceHandler : IChainProcessor
{
    public static EndServiceHandler Instance { get; } = new EndServiceHandler();

    public void RegisterNext(IChainProcessor next)
    {
        throw new InvalidOperationException(
            "Could not assign the next chain processor to the End of Workflow");
    }

    public Response TryToProcess(Request loanRequest)
    {
        // add here you invalid state.
        return new Response();
    }
}

注意:

  1. 所有服务实现与Service1
  2. 类似
  3. 您应该将请求的状态管理到请求对象中,在每个步骤中对其进行所有必要的更改,最后将其映射到响应对象。
  4. 如果要停止流程,可以通过两种方式完成:
    • 在调用_next.TryToProcess(request)
    • 之前返回Response对象
    • 将一个ChainProcessException抛入try-catch
  5. 关于停止流程的想法是当您需要返回验证消息,显示意外错误或返回用户的一些额外信息时。
  6. 你永远不应该到达EndServiceHandler,流程应该在此之前中断。