You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Love your implementation. I was curious any thoughts to adding support for doing the mapping on the child instance instead of the parent? This would provide better support for a more flexible IoC pattern -
where the implementer of the interface controls the mapping rather than the author of the interface.
Example: The interface is defined in one assembly by a framework author
publicinterfaceIAnimal{stringBreed{get;set;}}
and then the concrete implementation would be in another file (or assembly)
this could be implemented using the DependencyInjection or by using Reflection for all known types loaded (supporting the DI pattern would be more ideal I think)
// the mapping setupTypeDescriptor.AddAttributes(typeof(IAnimal),newJsonSubtypes.KnownSubTypeAttribute(typeof(Cat),"cat"),newJsonSubtypes.KnownSubTypeAttribute(typeof(Dog),"dog"));varjson="{\"catLives\":6,\"@type\":\"cat\",\"age\":11}";varresult=JsonConvert.DeserializeObject<Animal>(json);Assert.AreEqual(typeof(Cat),result.GetType());Assert.AreEqual(11,result.Age);Assert.AreEqual(6,(resultasCat)?.Lives);
But TypeDescriptor.GetAttribute(...) is not available for at least netstandard1.3 and netstandard1.4
They both are great ideas. How close is the 1st option? If is good enough to test for the standard use cases (maybe just part it as experimental and release it?)
I think I found an issue with #28 - if the interface and the concrete class is in different assemblies there is an issue in creating the concrete instance. I think the issue is when the interface and class are in different name space. It looks like their is an assumption in the code that the namespace for the interface is used to build the namespace for the class.
So I tracked it down -- it looks like the code assumes that everything is in a single assembly (interface and classes). For my scenario I have the interface in one assembly and the concrete classes spread out over several other assemblies.
To repro create 3 assemblies
MainApp
Interface
Implementation
This will show the issue. Now the hard part is, I am not sure what the solution might be as you are supporting a lot of the legacy frameworks via PCL (I think) and up until the latest version AppDomain is not usable which makes getting a list of all loaded assemblies a bit tricky from what I can remember.
When dynamic registration is used (which has been introduced with #28) the sub type should be is taken from the registration and not from the parent type assembly.
With #28 the method GetSubTypeMapping is overrided and then should provides some values so it did not fall in the GetTypeByName (which build the subtype from the assemble of the parent, but not in this case).
Activity
manuc66 commentedon Jan 27, 2018
Hi, I agree that it might be better to do the mapping on the child instead of the parent.
In branch feature/base-without-useless-property I have support for the case you're exposing (having no possibility to add attributes on the parent)
But it have situations where I did not managed yet to fix some edge cases, so it's not released yet.
manuc66 commentedon Jan 27, 2018
If
JsonSubTypesusesTypeDescriptor.GetAttributesinstead ofType.GetCustomAttributessomething like this could have been implemented easily:The concrete type whitout attributes:
But
TypeDescriptor.GetAttribute(...)is not available for at least netstandard1.3 and netstandard1.4ravensorb commentedon Jan 27, 2018
They both are great ideas. How close is the 1st option? If is good enough to test for the standard use cases (maybe just part it as experimental and release it?)
[-]Option for attribute on child class instead of Parent?[/-][+]Option for avoiding mapping on the Parent[/+]manuc66 commentedon Jan 28, 2018
The 1st option is now released in v1.3.0 with #28
ravensorb commentedon Mar 8, 2018
I think I found an issue with #28 - if the interface and the concrete class is in different assemblies there is an issue in creating the concrete instance. I think the issue is when the interface and class are in different name space. It looks like their is an assumption in the code that the namespace for the interface is used to build the namespace for the class.
try to reproduce issue (see: #26 (comment))
manuc66 commentedon Mar 8, 2018
@ravensorb I tried to reproduce the issue you described but did not managed (see: https://github.com/manuc66/JsonSubTypes/tree/bugfix/try-to-reproduce-bug). Can you provide some sample code and open an new issue with it?
Thanks
ravensorb commentedon Mar 8, 2018
So I tracked it down -- it looks like the code assumes that everything is in a single assembly (interface and classes). For my scenario I have the interface in one assembly and the concrete classes spread out over several other assemblies.
To repro create 3 assemblies
This will show the issue. Now the hard part is, I am not sure what the solution might be as you are supporting a lot of the legacy frameworks via PCL (I think) and up until the latest version AppDomain is not usable which makes getting a list of all loaded assemblies a bit tricky from what I can remember.
manuc66 commentedon Mar 8, 2018
When dynamic registration is used (which has been introduced with #28) the sub type should be is taken from the registration and not from the parent type assembly.
With #28 the method GetSubTypeMapping is overrided and then should provides some values so it did not fall in the GetTypeByName (which build the subtype from the assemble of the parent, but not in this case).
ravensorb commentedon Mar 8, 2018
issue with that is, it assumes that everything is loaded immediately and that is not always the case when you have things handled via DI