C
C#2y ago
Angius

❔ Properly including XML templates in a class library

I'm writing a library for generating .epub files. Since they're just glorified zips with XML files inside, I'll need to generate that XML somehow. The easiest way is to just have some templates with the XML and placeholders, and run a .Replace() on them or use some templating library. Question is, how do I store those templates properly? Using triple-quoted string constants would be the easiest, but some of the XML is quite large. I could just store loose files and load them with File.ReadAllTextAsync(), but not sure how well that'd work in the class lib context. Not to mention, I'd like those templates to be available at all times, I'd rather avoid reading them from the filesystem each time I want to generate an epub. Using DI somehow is an idea, I could read the templates once and inject them as a singleton or something, but how do I even make DI work in a class lib, not knowing if the user of the library even uses DI in the first place? I'd consider source generators and just reading files on compile time and adding them to some Template const in each class that needs it, but source generators can't read files... Any ideas would be welcome
13 Replies
reflectronic
reflectronic2y ago
i would store them as embedded resources. it is the simplest option assuming that you are the one creating all of the templates
Angius
AngiusOP2y ago
Ye, I'm making them all Any up to date docs on embedded resources? Do you still need resgen?
reflectronic
reflectronic2y ago
no, that's for using resx. that's much more complicated than what you want here i mean, if they need to be localized, then maybe that's what you want but adding an embedded resource is
<EmbeddedResource Include="Templates\**\*.xml" />
<EmbeddedResource Include="Templates\**\*.xml" />
and using them at runtime is
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("name-of-embeddedresource");
// you can use StreamReader to get the string out of this to do your replacement
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("name-of-embeddedresource");
// you can use StreamReader to get the string out of this to do your replacement
Angius
AngiusOP2y ago
Seems easy enough. Does accessing them still perform some IO?
reflectronic
reflectronic2y ago
no
Angius
AngiusOP2y ago
Just wondering if I should cache the read strings or not So no caching necessary, cool
reflectronic
reflectronic2y ago
well, you should probably do that because you need to transcode the text into the string the stream is probably UTF-8
Angius
AngiusOP2y ago
UTF-8 seems fine to me
reflectronic
reflectronic2y ago
yeah, but the string that you're going to do Replace on isn't
Angius
AngiusOP2y ago
So get the stream, transcode to UTF-8, cache in a singleton or some such?
reflectronic
reflectronic2y ago
yeah, cache new StreamReader(stream).ReadToEnd() in a dictionary or something
Angius
AngiusOP2y ago
Seems easy enough, thanks!
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server