我的 RavenDB 对象是从动态加载的 DLL 中的类型创建的。我无法将 DLL 加载到 current 的执行上下文中AppDomain
,因此 JSON 反序列化器找不到类型。
我将如何使用自定义转换器来使用运行时加载程序集中的类型?
注意 ,我尝试通过 AppDomain 从另一个域提供 DLL,但后来导致了冲突。尽管它解决了该问题中的问题,但我现在需要确保我的所有对象都是从动态加载的程序集中的类型创建的。
在您要指定Assembly
生成类型的地方,这就是您创建自定义转换器的方式。我所有的自定义类型都派生自IEntity
. 您需要这样做,以便反序列化器知道何时挂钩到您的自定义类。
public class DynamicAssemblyJsonConverter : JsonConverter
{
private Assembly dynamicAssembly = null;
public DynamicAssemblyJsonConverter(Assembly dynamicAssembly)
{
this.dynamicAssembly = dynamicAssembly;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jObject = JObject.Load(reader);
var typeName = jObject["$type"].Value<string>().Split(',')[0];
var target = dynamicAssembly.CreateInstance(typeName);
serializer.Populate(jObject.CreateReader(), target);
return target;
}
public override bool CanConvert(Type objectType)
{
return objectType is IEntity;
}
}
如果您正在使用 RavenDB(就像我一样),请创建它CustomConverter
,然后在查询或加载之前将其应用到 Raven,方法是将其分配给:Conventions.CustomizeJsonSerializer
.
Rob 的回答效果很好。但是,如果您需要在转换器中解析“$ref”,则应添加:
JToken reference = parser["$ref"];
if (reference != null)
{
string id = reference.Value<string>();
result = serializer.ReferenceResolver.ResolveReference(serializer, id);
}