I'm working on a small (.Net 5 wpf) app, which loads and saves its state from/into json files (using Newtonsoft library). I save it with $type and $id fields.
Now I have added a plugin system, where I load assemblies from a folder and create objects from them into my app state (say, my model/viewmodel). When I'm saving my model, everything runs fine. I checked the $type, and it's the real name.
My issue is: how to load it back (without writing custom parsing code) ? My plugin types are stored in a List in my plugin service, and newtonsoft has no knowledge of them. So, I have 2 questions:
- how do I tell newtonsoft lib to take my types into account ?
- and/or how do I tell the environment running my app (framework ? app domain ?) to meet my types, and consider them as known for the rest of the time my app is launched ?
I have no useful code to show cause everything happens in a DeserializeObject() method.
Ok let's illustrate as asked in the comments.
// Loading of my types. I can call it for deserialization if needed
var asm = Assembly.LoadFile("plugin.dll");
var typeX = asm.GetTypes().First();
var instance = Activator.CreateInstance(typeX) as BaseClass;
//Items is a List<BaseClass>
myModel.Items.Add(instance);
JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
string serialized = JsonConvert.SerializeObject(myModel, Formatting.Indented, settings);
File.WriteAllText(path, serialized);
// HERE: JSonConvert does not know my type typeX !
var readObject = JsonConvert.DeserializeObject<TypeOfMyModel>(content, settings);
I'd like to be able to say to JsonConvert, "hey, you might need these types too when deserializing my model, depending on what you encounter". Cause JsonConvert knows how to deserialize a class embedded known at compile type, but not one from an assembly I dynamically loaded.
Thank you for any help.
[edit] @dbc gave me the solution in the comments: using a custom SerializationBinder gives the ability to solve the type. Thanks !