【问题标题】:Asana API C# Project DesignAsana API C# 项目设计
【发布时间】:2013-03-03 09:20:13
【问题描述】:

我正在用 C# 为 Asana 设计一个 API 包装器,这是一个项目管理解决方案。在设计过程中,我遇到了一些障碍。我想知道设计 API 包装器的好方法是什么。

我正在集成的 Asana API 与 REST 配合使用。请求返回 JSON。

将有 6 个数据类(用户、任务、项目等),每个类都包含一堆字符串来保存从 REST 请求返回的数据。我对这些类的第一个想法是给它们每个工厂 Parse() 构造函数,这样我就可以轻松地传入 json 并获得一个数据对象作为回报。我意识到我无法将静态工厂方法提取到接口中。

我将有一个 REST 请求类来管理从 REST 服务器发送和接收数据。它总是会返回一个 JSON 字符串。

最后,我想要一个 AsanaAPI 类,该类将包含封装那些暴露在 REST 服务器上的方法(即 GetUser、GetAllUsers、GetTask)。每个方法要么返回一个特定的数据类,要么返回一个数据类数组。以下是两种情况:

    public User GetSingleUser(string userID = "me")
    {
        if(userID == "") throw new ArgumentException("UserID cannot be blank");

        string url = string.Format("{0}/{1}{2}", userUrl, userID, "?opt_fields=id,name,email,workspaces,workspaces.id,workspaces.name");
        JSONNode root = JSON.Parse(GetResponse(url))["data"];
        return User.Parse(root);
    }

    public List<User> GetAllUsers()
    {
        List<User> users = new List<User>();

        string url = string.Format("{0}{1}", userUrl, "?opt_fields=id,name,email,workspaces,workspaces.id,workspaces.name");
        JSONArray root = JSON.Parse(GetResponse(url))["data"].AsArray;
        foreach(JSONNode userRoot in root)
        {
            users.Add(User.Parse(userRoot));
        }

        return users;
    }

每个方法都有相同的格式,但是用户类型将被替换为项目、任务等。我想提取这两个方法中的逻辑,因为会有更多的方法具有几乎完全相同的格式。

总之,我遇到的障碍是

  1. 我无法从数据类中提取工厂构造方法。
  2. 我无法从请求方法中提取解析逻辑

我可以用泛型做点什么,还是有更好的方法来设计这个项目?

【问题讨论】:

    标签: c# api


    【解决方案1】:

    所以我创建了一个 Parsable 接口,其中只包含一个 Parse 方法。每种数据类型都实现 Parsable。我能够使用泛型类型提取解析逻辑。这不是最漂亮的解决方案,但确实有效。

        public User GetSingleUser(string userID = "me")
        {
            if(userID == "") throw new ArgumentException("UserID cannot be blank");
    
            string url = "{baseUrl}/users/{userID}?{opt_fields}".FormatWith(
                new { baseUrl = BASE_URL, userID = userID, opt_fields = "opt_fields=id,name,email,workspaces,workspaces.id,workspaces.name" });
    
            return (User)ParseJson<User>(AsanaRequest.GetResponse(url));
        }
    
        public User[] GetAllUsers()
        {
            string url = "{baseUrl}/users?{opt_fields}".FormatWith(
                new { baseUrl = BASE_URL, opt_fields = "opt_fields=id,name,email,workspaces,workspaces.id,workspaces.name" });
    
            return (User[])ParseJsonArray<User>(AsanaRequest.GetResponse(url));
        }
    
        public T ParseJson<T>(string json) where T : Parsable, new()
        {
            JSONNode root = JSON.Parse(json)["data"];
            T ret = new T();
            ret.Parse(root);
            return ret;
        }
    
        public T[] ParseJsonArray<T>(string json) where T : Parsable, new()
        {
            JSONArray root = JSON.Parse(json)["data"].AsArray;
            T[] nodes = new T[root.Count];
            for(int i = 0; i < root.Count; i++)
            {
                T newParsable = new T();
                newParsable.Parse(root[i]);
                nodes[i] = newParsable;
            }
    
            return nodes;
        }
    

    【讨论】:

      猜你喜欢
      • 2018-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多