EnableReferences use case
See original GitHub issueI’m trying to understand the usage of the EnableReferences
. I’ve created this sample to wrap my head around the concept and I’m getting an unexpected result.
Basically, I have a BookStore with Books (with all the books) and Genres that have references to the books.
Expected
The resulting XML of the Genres section should hold references to each book.
Actual result
The resulting XML holds references to a list of Books instead.
How to reproduce
This is the offending code:
void Main()
{
string OutputXml = System.IO.Path.GetTempFileName() + ".xml";
var b1 = new Book();
var b2 = new Book();
var allBooks = new[] { b1, b2, };
var fs = new BookStore()
{
AllBooks = allBooks,
Genres = new[]
{
new Genre()
{
Books = allBooks,
},
new Genre()
{
Books = allBooks,
},
}
};
var serializer = new ConfigurationContainer()
.Type<Book>(b => b.EnableReferences())
.Create();
var serialized = serializer.Serialize(new XmlWriterSettings() { Indent = true }, fs);
System.IO.File.WriteAllText(OutputXml, serialized);
var psi = new ProcessStartInfo(OutputXml)
{
UseShellExecute = true,
};
Process.Start(psi);
}
class BookStore
{
public IEnumerable<Book> AllBooks { get; set; }
public IEnumerable<Genre> Genres { get; set; }
}
class Book
{
}
class Genre
{
public IEnumerable<Book> Books { get; set; }
}
As you see, both genres have a reference to allBooks
. The serializer identifies that I want to reflect this in the XML, but I would like to have the reference to the actual books inside allBook
.
NOTE
In order to get the desired results I would have to use the following code:
void Main()
{
string OutputXml = System.IO.Path.GetTempFileName() + ".xml";
var b1 = new Book();
var b2 = new Book();
var allBooks = new[] { b1, b2, };
var fs = new BookStore()
{
AllBooks = allBooks,
Genres = new[]
{
new Genre()
{
Books = new[] { b1, b2 },
},
new Genre()
{
Books = new[] { b1, b2 },
},
}
};
var serializer = new ConfigurationContainer()
.Type<Book>(b => b.EnableReferences())
.Create();
var serialized = serializer.Serialize(new XmlWriterSettings() { Indent = true }, fs);
System.IO.File.WriteAllText(OutputXml, serialized);
var psi = new ProcessStartInfo(OutputXml)
{
UseShellExecute = true,
};
Process.Start(psi);
}
Once the Books are assigned to different references (2 different arrays), the correct XML is produced.
I’ve configured the serialized calling the config.Type<Book>(b => b.EnableReferences())
because I’ve expected this would cause the Book to be reference from another places in the XML, but I think I’ve misunderstood its usage.
Is this a bug or I’m failing to tell the serializer what I want 😃
Issue Analytics
- State:
- Created 3 years ago
- Comments:13 (9 by maintainers)
Top GitHub Comments
DOH @SuperJMN I apologize for the confusion here. You are giving me quite the memory workout! 😅 It turns out there are two ways of enabling references:
EnableReferences()
: Enables references on the entire container.Type<T>().EnableReferences(x => x.Id)
: Enables references specifically for the type, with the provided member being the identity member.Unfortunately, despite my best wishes, there is no
Type<T>().EnableReferences()
. What you are actually doing is calling it on the Type’s parentConfigurationContainer
thereby enabling it for the entire container. This explains why bothBook
andBook[]
are being counted.The fluent api suffers from some design issues like the above. You think you’re applying it to the type, but you’re really accessing the parent container. It was my first attempt at a fluent API, what can I say. 😁
“Super” happy to report that this fixes #360, too! 🎉
😁