【发布时间】:2014-12-18 08:22:51
【问题描述】:
我目前正在编写一项服务,该服务应该轮询多个 API,尽可能统一数据,并将其存储在我的数据库中。我宁愿不必为我提出的每个请求以及我想从请求中保存的每个数据子集创建一个新类。所以我选择使用匿名和动态类型。这创造了以下怪物;可能是因为我很长时间没有使用匿名/动态类型了。我还应该注意到该功能不起作用,但应该很好地说明我想要实现的目标。
public string GetActivities(ApplicationUser user)
{
//TODO: get statistics of today. If exists, overwrite.
var date = DateTime.Today;
var apiCall = String.Format("/1/user/-/activities/date/{0}.json", date.ToString("yyyy-MM-dd"));
var request = new RestRequest(apiCall);
var response = restClient.Execute(request);
//If the response is not what we expected (and exception gets thrown in HandleResponse), rethrow the exception.
try
{
HandleResponse(response);
}
catch
{
throw;
}
//Create a dynamic object from the JSON response. This way we do not need to create a new class for each response.
dynamic data = JsonConvert.DeserializeObject(response.Content);
//Create a list to add anonymous objects to. We define the prototype in Select()
var activities = Enumerable.Empty<dynamic>()
.Select(r => new {
distance = 0,
duration = 0,
hasStartTime = false,
startTime = DateTime.Now,
calories = 0,
steps = 0
}).ToList();
//Grab the data we need from the API response
foreach(var a in data.activities)
{
var act = new
{
distance = a.distance,
duration = a.duration,
hasStartTime = a.hasStartTime,
startTime = a.startTime,
calories = a.calories,
steps = a.steps
};
activities.Add(act);
}
List<Statistic> statistics = new List<Statistic>();
foreach (var a in activities)
{
var parsedData = new { distance = "" };
//Add the data we received as a JSON object to the object we store in the database.
var statistic = new Statistic()
{
ID = Guid.NewGuid(),
Device = context.Device.Where(d => d.Name == "Fitbit").Single(),
Timestamp = DateTime.Today,
Type = context.StatisticType.Where(s => s.Type == "calories_eaten").Single(),
User = user,
Value = JsonConvert.SerializeObject(parsedData)
};
statistics.Add(statistic);
}
//Save the newly added data to the database.
context.Statistic.AddRange(statistics);
context.SaveChanges();
return null;
}
考虑到这个功能已经变成了怪物,还有其他选择吗?最好是我不需要创建大量类的地方。
【问题讨论】:
-
不创建类的替代方法是创建类。根据每个 API 中 JSON 的相似程度,您也许可以创建一些可重用的方法来处理它们,但是在不知道 JSON 是什么样子的情况下,真的没有任何办法可以说。我最好的建议是,让它发挥作用;然后让另一个工作,然后寻找相似之处并将这些部分分解为辅助方法。继续这样做,直到您将设计发展为适合您的东西。
-
@BrianRogers 我刚刚发现了 ExpandoObjects,它们似乎帮了很多忙。它帮助我将上述方法减少了 25 行。还有一些样板文件需要考虑。
标签: entity-framework parsing json.net