私はまだかなりプログラミングが新しく、未処理のJSON文字列を取り込み、JSONをオブジェクトに解析して処理用のハンドラに渡すWebHookコンシューマを作成する任務があります。 JSONは次のようで来ている:タイプを知らなくても汎用オブジェクトを返す?
public class WebHookModel<T> where T : class, new()
{
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
[JsonProperty(PropertyName = "created_at")]
public DateTime CreatedAt { get; set; }
[JsonProperty(PropertyName = "type")]
public string Type { get; set; }
[JsonProperty(PropertyName = "object")]
public T Object { get; set; }
[JsonIgnore]
public string WebHookAction
{
get
{
return string.IsNullOrEmpty(Type) ? string.Empty : Type.Split('.').Last();
}
}
}
次に作成:
{
"id":"1",
"created_at":"2017-09-19T20:41:23.093Z",
"type":"person.created",
"object":{
"id":"person1",
"created_at":"2017-09-19T20:41:23.076Z",
"updated_at":"2017-09-19T20:41:23.076Z",
"firstname":"First",
...
}
}
私はこれがジェネリックを使用する絶好の機会だと思ったし、次のように私のクラスを構築しましたので、内部オブジェクトは、任意のオブジェクトにすることができます次のインターフェイス:
public interface IWebHookModelFactory<T> where T : class, new()
{
WebHookModel<T> GetWebHookModel(string type, string jsonPayload);
}
は、私が理解するために失敗していますが、どのように私はタイプがコンパイル時に何であるか知らなくてもファクトリクラスを実装することが出来るのですか?
モデルをちょっと見て、抽象的なTオブジェクトを持つ抽象クラスに変更し、派生クラスで定義できるようにしました。
public abstract class WebHookModel<T> where T : class, new()
{
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
[JsonProperty(PropertyName = "created_at")]
public DateTime CreatedAt { get; set; }
[JsonProperty(PropertyName = "type")]
public string Type { get; set; }
[JsonProperty(PropertyName = "object")]
public abstract T Object { get; set; }
[JsonIgnore]
public string WebHookAction
{
get
{
return string.IsNullOrEmpty(Type) ? string.Empty : Type.Split('.').Last();
}
}
}
public PersonWebHookModel : WebHookModel<Person>
{
public override Person Object { get; set; }
}
しかし、実行時に型がわからないインターフェイスを実装しようとするのと同じ問題が発生します。私がオンラインで見つけたことから、これは共分散の例ですが、この問題を解決する方法を説明する記事は見つかりませんでした。ジェネリックスをスキップして大文字の case文を作成するのが最善でしょうか?
public interface IWebHookFactory<TModel, TJsonObject>
where TJsonObject : class, new()
where TModel : WebHookModel<TJsonObject>
{
TModel GetWebHookModel(string type, string jsonPayload);
}
それは私が私が私のサービスに渡しているどのモデルに基づいて個々のハンドラを定義することができますので、私は抽象クラスのアプローチを使用するビットの部分です。解決のための
public interface IWebHookService<TModel, TJsonObject>
where TJsonObject : class, new()
where TModel : WebHookModel<TJsonObject>
{
void CompleteAction(TModel webHookModel);
}
public abstract class BaseWebhookService<TModel, TJsonObject> : IWebHookService<TModel, TJsonObject>
where TJsonObject : class, new()
where TModel : WebHookModel<TJsonObject>
{
public void CompleteAction(TModel webHookModel)
{
var self = this.GetType();
var bitWise = System.Reflection.BindingFlags.IgnoreCase
| System.Reflection.BindingFlags.Instance
| System.Reflection.BindingFlags.NonPublic;
var methodToCall = self.GetMethod(jsonObject.WebHookAction, bitWise);
methodToCall.Invoke(this, new[] { jsonObject });
}
protected abstract void Created(TModel webHookObject);
protected abstract void Updated(TModel webHookObject);
protected abstract void Destroyed(TModel webHookObject);
}
public class PersonWebHookService : BaseWebHookService<PersonWebHookModel, Person>
{
protected override void Created(PersonWebHookModel webHookModel)
{
throw new NotImplementedException();
}
protected override void Updated(PersonWebHookModel webHookModel)
{
throw new NotImplementedException();
}
protected override void Destroyed(PersonWebHookModel webHookModel)
{
throw new NotImplementedException();
}
}
た場合インフォーマットのみあなたが 'T'を持っているイオンは実行時の型情報(' Type'、名前、またはあなたが持っているもの)であり、ジェネリックを使わないなら、それは仕事のための正しいツールではありません。あなたは無意味な 'WebHookModel
これらのオブジェクトで正確に何が行われていますか?下流でどのように処理されるのですか?それらのすべてに対応するハンドラが1つありますか、またはそれぞれのハンドラがありますか? –
WebHookオブジェクトが入ってくるごとに、これまでに10個見つかりました。別の方法で処理する必要があります。 BaseWebHookServiceとPersonWebHookServiceは、各オブジェクトの処理方法の例です。 APIドキュメントの規約には、object.action(作成、更新、または破棄されるアクション)があります。 BaseWebHookServiceは、渡されるWebHookModelに基づいて、使用する派生サービスを認識します。 – bschreck