This repository has been archived by the owner on Oct 19, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 27
How to convert a dictionary whose value is an interface type? #90
Labels
Comments
Unfortunately this use case is not natively supported at the moment as a quick short investigations brings up. At the moment you can only do the following workaround: var result = Toml.WriteString(entity);
var settings = TomlSettings.Create(cfg => cfg
.ConfigureType<IDictionary<string, ISomeInterface>>(tc => tc
.CreateInstance(() => new Dictionary<string, ISomeInterface>()))
.ConfigurePropertyMapping(pm => pm
.OnTargetPropertyNotFound(FailedToMapToTarget)));
void FailedToMapToTarget(string[] keyChain, object target, TomlObject source)
{
var tgtDict = (Dictionary<string, ISomeInterface>)target;
TomlTable srcTable = (TomlTable)source;
var key = keyChain.Last();
if (key == "ClassA")
{
tgtDict.Add(key, srcTable.Get<ClassA>());
}
else if (key == "ClassB")
{
tgtDict.Add(key, srcTable.Get<ClassB>());
}
}
Console.Write(result);
var read = Toml.ReadString<TomlEntity>(result, settings); But I think I will add this functionality in the near future. This will be a breaking change and the configuration will have to be changed to something like this, that is conceptually better var settings = TomlSettings.Create(cfg => cfg
.ConfigureType<IDictionary<string, ISomeInterface>>(tc => tc
.CreateInstance(() => new Dictionary<string, ISomeInterface>()))
.ConfigureType<ISomeInterface>(tc => tc
.WithConversionFor<TomlTable>(conv => conv
.FromToml(SomeInterfaceFromTomlTable)))
var read = Toml.ReadString<TomlEntity>(result, settings);
ISomeInterface SomeInterfaceFromTomlTable(string key, TomlTable tbl)
{
if (key == "ClassA") { return tbl.Get<ClassA>(); }
else if (key == "ClassB") { return tbl.Get<ClassB>(); }
else { return null; } // probably throw EXC
} |
@paiden Thanks, it works. |
paiden
added a commit
that referenced
this issue
Apr 21, 2020
User can now map TOML objects into specific base types via specifying a concrete activator. A consequence is that the ambiguous API MapTableKey is not needed anymore. This is a good thing but will introduce a breaking change with the next release. While this commit makes it work and all test are green, I have the feeling not all scenarios will work as e.g. the ToDictionary test are not good enough to catch all issues here. In general the conversion from TOML object graph to a CLR object graph has a lot of technical debt. E.g. conversion is partially handled by converter and partially handled by the TOML objects themselves. The visitor pattern there is a pain. Future work will be needed to improve the code base in this space. Another consequence of this inconsistencies is, that the CreateInstanceContext KeyChain property most of the time is not filled with correct data. Related #90
paiden
added a commit
that referenced
this issue
Apr 22, 2020
User can now map TOML objects into specific base types via specifying a concrete activator. A consequence is that the ambiguous API MapTableKey is not needed anymore. This is a good thing but will introduce a breaking change with the next release. While this commit makes it work and all test are green, I have the feeling not all scenarios will work as e.g. the ToDictionary test are not good enough to catch all issues here. In general the conversion from TOML object graph to a CLR object graph has a lot of technical debt. E.g. conversion is partially handled by converter and partially handled by the TOML objects themselves. The visitor pattern there is a pain. Future work will be needed to improve the code base in this space. Another consequence of this inconsistencies is, that the CreateInstanceContext KeyChain property most of the time is not filled with correct data. Related #90
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Hello, I have a interface and some derived classes, like:
And I have a entity class with a IDictionary property with the interface above as value type:
Now I can write the entity to string but cannot read into it:
In fact I will have more derived classes and I have their own reflection types, how can I specify their type and instantiate them into the dictionary?
The text was updated successfully, but these errors were encountered: