Support Private Constructors in ServiceStack.Text
When creating immutable objects, it's common to not have a default constructor. ServiceStack.Text supports this presently with the use of FormatterServices.GetUnitializedObject. However, GetUnitializedObject does not do any field initialization. The DataContractSerializer works around this with support of the OnDeserialized attribute; but why would we want to write the initialization code twice? Instead, We should change ServiceStack.Text to fall back to private constructors. Here is some proposed code.
public static ConstructorInfo GetEmptyConstructor(this Type type)
{
if NETFX_CORE
return type.GetTypeInfo().DeclaredConstructors.FirstOrDefault(c => c.GetParameters().Count() == 0);
else
var ret = type.GetConstructor(Type.EmptyTypes);
if (ret != null) return ret;
// attempt to use constructors with all default values
var ctors = from ctor in type.GetConstructors()
let prms = ctor.GetParameters()
where prms.All(p => p.IsOptional)
orderby prms.Length
select ctor;
ret = ctors.FirstOrDefault();
if (ret != null) return ret;
if (JsConfig.UsePrivateConstructor)
{
ret = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
}
return ret;
endif
}
4
votes