How do I use a Custom JSON.NET Converter in RavenDB to deserialize into types from a dynamic DLL?

强颜欢笑 提交于 2019-12-01 05:35:55

问题


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 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.


回答1:


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;
    }
}

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.




回答2:


Rob's answer works great. However if you need to resolve "$ref" in your converter, you should add:

JToken reference = parser["$ref"];
if (reference != null)
{
    string id = reference.Value<string>();
    result = serializer.ReferenceResolver.ResolveReference(serializer, id);
}


来源:https://stackoverflow.com/questions/18900283/how-do-i-use-a-custom-json-net-converter-in-ravendb-to-deserialize-into-types-fr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!