寻找设计模式以自动执行重复的任务,例如登录/注销

Sea*_*ell 2 c# design-patterns httpclient

我正在寻找一种设计模式来帮助简化我的代码。

我的代码使用HttpClient调用获取或发布信息的Web API,但是每个会话都需要先进行一次登录调用,然后返回一个cookie作为ID,并在最后进行注销调用以关闭连接。因此,我的Web API类如下所示:

public class APIHelper 
{
    public HttpClient myClient { get; set; }

    public async void Login()
    {
        using (HttpResponseMessage response = await myClient.PostAsync("loginAddress", "loginInput"))
        {
            if (response.IsSuccessStatusCode)
            {                    
                //save cookie
            }
        }
    }

    public async void Logout()
    {
        using (HttpResponseMessage response = await myClient.PostAsync("logoutAddress", ""))
        {
            if (response.IsSuccessStatusCode)
            {                    
                //session ends
            }
        }
    }

    public void GetOrder()  {...}

    public void NewOrder(object OrderData)  {...}

    public void GetCustomer()   {...}

    public void NewCustomer(object CustomerData)    {...}
}
Run Code Online (Sandbox Code Playgroud)

为了使用它们,我只需按顺序调用它们:

public Main()
{
    APIHelper.Login();
    APIHelper.GetOrder();   //or NewOrder, or GetCustomer, or any other actual API calls
    APIHelper.Logout();
}
Run Code Online (Sandbox Code Playgroud)

无论如何,我可以将Login / Logout调用放入每个实际的API调用中,这样我就不必为每个调用都键入它们了吗?理想情况下,我只需要设置一次结构,然后对于我创建的任何API调用,系统都会在开始/结束时自动调用Login / Logout。哪种设计模式可以解决此类问题?任何简单的示例都将非常有帮助!

谢谢。SC

====================================

编辑:尝试Dymanoid的建议

感谢您的快速回复!我认为它应该可以工作,但是我又遇到了麻烦:“非静态字段,方法或属性'APIHelper.GetOrder()'需要对象引用。

查看新代码,似乎我在整个会话中都需要myClient对象(这是一个HttpClient对象):

public void DoMyJob(Action job)
{            
    var myClient = new APIHelper();     //initiates a HttpClient object

    myClient.Login();
    try
    {       
        job();
    }
    finally
    {
        myClient.Logout();
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,当从外部调用job函数时:

DoMyJob(APIHelper.GetOrder);
Run Code Online (Sandbox Code Playgroud)

我还没有对象。这很容易解决吗?抱歉,我没有在OP中说清楚,实际的原始通话看起来像这样:

var myClient = new APIHelper();
myClient.Login();
myClient.GetOrder();
myClient.Logout();
Run Code Online (Sandbox Code Playgroud)

但是,由于您的建议,我认为最好将初始化放入DoMyJob方法中。

dym*_*oid 6

为此,请使用模板方法和策略。

void DoMyJob(Action job)
{
    APIHelper.Login();
    try
    {
        job();
    }
    finally
    {
        APIHelper.Logout();
    }
}
Run Code Online (Sandbox Code Playgroud)

用法如下所示:

DoMyJob(() => APIHelper.GetOrder()); 
Run Code Online (Sandbox Code Playgroud)

要么

DoMyJob(APIHelper.GetOrder); 
Run Code Online (Sandbox Code Playgroud)

要么

DoMyJob(() => { APIHelper.GetOrder(); APIHelper.NewOrder(); } ); 
Run Code Online (Sandbox Code Playgroud)