如何在RavenDB中使用自定义JSON.NET转换器从动态DLL反序列化为类型?
我的RavenDB对象是根据动态加载的DLL中的类型创建的.我无法将DLL加载到当前AppDomain
的执行上下文中,因此JSON反序列化器无法找到类型.
My RavenDB objects are created from types in a DLL that is loaded dynamically. I cannot load the DLL into the execution context of the current AppDomain
, so the JSON deserializer can't find the types.
我将如何使用自定义转换器来使用已加载的运行时汇编?
How would I use a Custom Converter to use the types in my loaded-at-runtime Assembly?
NB 我尝试服务通过AppDomain从另一个域下载DLL,但稍后导致冲突.尽管它解决了该问题中的问题,但现在我需要确保所有对象都是根据动态加载的Assembly中的类型创建的.
NB I tried serving the DLL from another domain via the AppDomain but that caused conflicts later. Although it solved the problem in that question, I now need to make sure that all of my objects are created from types in the dynamically loaded Assembly.
在要指定Assembly
生成类型的位置,这是创建自定义转换器的方式.我所有的自定义类型均源自IEntity
.您需要执行此操作,以便解串器知道何时将钩子插入自定义类.
Where you want to specify the Assembly
to generate the types, this is how you create a custom converter. All of my custom types derive from IEntity
. You need to do this so that the deserializer knows when hook into your custom class.
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
,然后将其分配给Conventions.CustomizeJsonSerializer
,然后在查询或加载之前将其应用于Raven.
If you are using RavenDB (like I am), create this CustomConverter
and then apply it to Raven before you query or load by assigning it to: Conventions.CustomizeJsonSerializer
.