我正在开发一个元数据生成器,它基本上为 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));
这个实现的一个问题是,如果你调用DefaultValueGenerator.GetDefaultValue(typeof(string))
它会抛出我捕获的异常activatorException
,然后使用default
关键字。只是丑陋,因为我依赖一个例外..有更好的方法吗?
第二个问题是数组/集合。例如:DefaultValueGenerator.GetDefaultValue(typeof(List<MyObject>))
创建一个 0 元素列表,然后将其序列化为 JSON 为[]
-- 在文档方面不是很有帮助。我想生成一个元素。
第三个问题是嵌套类型。例如,如果我有:
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 生成为空值。
任何人都知道一些已经这样做的代码/库吗?否则,关于如何实现这一点的任何提示,并避免我指出的一些陷阱?有没有更容易解决这个问题的不同方法?
我希望它适用于内置的基本类型(字符串、int、guid 等)以及任何更复杂的对象——只要它们有一个无参数的构造函数(我可以接受这个限制,因为无论如何,使用的类型应该是 POCO/DTO)。