如何在RavenDB中使用自定义JSON.NET转换器从动态DLL反序列化为类型?

时间:2013-09-19 16:32:19

标签: json.net deserialization ravendb

我的RavenDB对象是从动态加载的DLL中的类型创建的。我无法将DLL加载到当前AppDomain的执行上下文中,因此JSON反序列化程序无法找到类型。

如何使用Custom Converter在我的运行时加载程序集中使用这些类型?

NB I tried通过AppDomain从另一个域提供DLL但后来导致了冲突。虽然它解决了该问题中的问题,但我现在需要确保所有对象都是从动态加载的程序集中的类型创建的。

2 个答案:

答案 0 :(得分:2)

如果要指定生成类型的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

答案 1 :(得分:0)

Rob的回答很有效。但是,如果您需要在转换器中解析“$ ref”,则应添加:

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