私は基本的に REST API のドキュメントを自動生成するメタデータ ジェネレーターに取り組んでいます。
これには、もちろん DTO である可能性がある要求/応答タイプの表示が含まれます。私が望むのは、オブジェクトのシリアル化された JSON (または XML) バージョンで、構造とプレースホルダー データを示しています。(シリアル化の部分は簡単ですが、最初にオブジェクトを作成するのは難しいです)。たとえば、次のオブジェクトがあるとします。
public class MyObject {
public string Name { get; set; }
public int Age { get; set; }
public bool Active { get; set; }
}
私はいくつかの関数を呼び出すことができるようにしたい:
var obj = GetDefaultValue(typeof(MyObject));
と同等のものを取得します。
new MyObject { Name = string.Empty, Age = 0, Active = false };
// or in other words: new MyObject { Name = default(string), Age = default(int), Active = default(bool) };
これを開始する基本的なコードがいくつかあります。
/// <summary>
/// Class to create a default value for a specified type.
/// </summary>
public abstract class DefaultValueGenerator
{
private DefaultValueGenerator() { }
/// <summary>
/// Creates a new default instance of type T.
/// Requires that T has a parameter-less constructor, or can be created using <code>default(T)</code>
/// </summary>
/// <param name="T"></param>
/// <returns></returns>
public static object GetDefaultValue(Type T)
{
try
{
return System.Activator.CreateInstance(T, true);
//TODO: if array type, also create a single item of that type
}
catch (Exception activatorException)
{
try
{
// from http://stackoverflow.com/a/2490267/7913
var defaultGeneratorType = typeof(DefaultGenerator<>).MakeGenericType(T);
return defaultGeneratorType.InvokeMember(
"GetDefault",
BindingFlags.Static |
BindingFlags.Public |
BindingFlags.InvokeMethod,
null, null, new object[0]);
}
catch //(Exception defaultGeneratorException)
{
throw new MissingMethodException(string.Format("No parameterless constructor defined for model {0}", T.Name), activatorException);
}
}
}
// from http://stackoverflow.com/a/2490267/7913
private class DefaultGenerator<T>
{
public static T GetDefault()
{
return default(T);
}
}
}
したがって、これを使用して次のように呼び出すことができます。
var obj = DefaultValueGenerator.GetDefaultValue(typeof(MyObject));
この実装の問題点の 1 つは、それを呼び出すDefaultValueGenerator.GetDefaultValue(typeof(string))
と、キャッチした例外がスローされ、キーワードactivatorException
が使用されることです。default
私は例外に頼っているので、ただ醜い..もっと良い方法はありますか?
2 番目の問題は配列/コレクションです。例:DefaultValueGenerator.GetDefaultValue(typeof(List<MyObject>))
要素が 0 のリストを作成し、それを JSON にシリアル化します[]
-- ドキュメントに関してはあまり役に立ちません。これで1つの要素を生成したいと思います。
3 番目の問題は、ネストされた型です。たとえば、私が持っている場合:
public class MyContainerObject {
public MyObject OtherObject { get; set; }
public int SomeValue { get; set; }
}
これに相当するものを生成したいと思います:
var obj = new MyContainerObject {
OtherObject = new MyObject { Name = string.Empty, Age = 0, Active = false },
SomeValue = 0,
}
しかし実際には、OtherObject を null 値として生成します。
すでにこれを行っているコード/ライブラリを知っている人はいますか? それ以外の場合、これを達成する方法と、私が指摘したいくつかの落とし穴を避けるためのヒントはありますか? これをより簡単に解決する別の方法はありますか?
組み込みの基本型 (string、int、guid など) だけでなく、より複雑なオブジェクトでも、パラメーターのないコンストラクターがある限り、これが機能することを望みます (私はその制限で問題ありません。いずれにせよ、使用される型は POCO/DTO でなければなりません)。