Polymorphic table array
queil opened this issue · 3 comments
Hi @paiden,
I was trying to do something like the following:
[[item]]
type="A"
[[item]]
type = "B"
And then:
cfg.ConfigureType<IMyCommonInterface>(t =>
t.CreateInstance(() => /* here I'd resolve an instance from a container based on the "type" property of my table */ )
The problem is that the factory method lacks a TOML context (compare to WithConversionFor<>. FromToml). It this scenario supported at all?
Thanks!
Definitely not a use case I had in mind when creating the lib....
But you can get something to work with the WithConversionFor<> method, see my example below. Why do you try to use the CreateInstance method? Probably because of the bug - oh man always another one - I describe after my example 😆 ...
CreateInstance is only meant to tell 'Nett' how to create a instance of a class without default constructor, nothing else.
This example shows what will work in the near future:
public sealed class Polymorphism
{
public abstract class B
{
public string Type { get; set; }
public B(string t)
{
this.Type = t;
}
}
public class C : B
{
public C()
: base(nameof(C))
{
}
}
public class D : B
{
public D()
: base(nameof(D))
{
}
}
public class Root
{
public List<B> Items { get; set; } = new List<B>();
}
[Fact]
public void FooPol()
{
var write = new Root()
{
Items = new List<B>()
{
new C(),
new D(),
}
};
var t = Toml.WriteString(write);
var config = TomlSettings.Create(cfg => cfg
.ConfigureType<B>(tc => tc
.WithConversionFor<TomlTable>(c => c
.FromToml(tbl => PolyCreate(tbl)))));
var read = Toml.ReadString<Root>(t, config);
B PolyCreate(TomlTable table)
{
if (table.Get<string>(nameof(B.Type)) == nameof(C))
{
return new C();
}
else if (table.Get<string>(nameof(B.Type)) == nameof(D))
{
return new D();
}
else
{
throw new InvalidOperationException();
}
}
}
Unfortunately this example currently does not work out of the box because in TomlTable.Get (~line 170)
the order of get converter and get activated instance seems to be reversed. So the converter will
not be used and a InvalidOperationException will be thrown.
Will have to investigate a little more and create a fix.
But the following workaround should make the example work without the fix in place
var config = TomlSettings.Create(cfg => cfg
.ConfigureType<B>(tc => tc
.CreateInstance(() => new C()) // Workaround for bug, should have no effect
.WithConversionFor<TomlTable>(c => c
.FromToml(tbl => PolyCreate(tbl)))));
Released with 0.11.0