GithubHelp home page GithubHelp logo

Comments (17)

FaustoNascimento avatar FaustoNascimento commented on May 10, 2024 1

I see, that makes sense.

About the code, what I've got is something very simple for my specific use case, just needed something quick and dirty, but you can gladly have it:

        public static void ToFile(this XmlDocument doc, string path)
        {
            using (var xmlTextWriter = new XmlTextWriter(path, new UTF8Encoding(false)))
            {
                xmlTextWriter.Formatting = Formatting.Indented;
                xmlTextWriter.IndentChar = '\t';
                xmlTextWriter.Indentation = 1;

                doc.Save(xmlTextWriter);
            }
        }

        public static T DeserializeFromFile<T>(this ExtendedXmlSerializer xmlSerializer, string path)
        {
            var xml = File.ReadAllText(path);
            return xmlSerializer.Deserialize<T>(xml);
        }

        public static void SerializeToFile(this ExtendedXmlSerializer xmlSerializer, object o, string path)
        {
            var xml = xmlSerializer.Serialize(o);
            var xmlDocument = new XmlDocument();

            xmlDocument.LoadXml(xml);
            xmlDocument.ToFile(path);
        }

So you can see in my case I'm not doing anything specifically with either Xml/Text Reader/Writer

from home.

Mike-E-angelo avatar Mike-E-angelo commented on May 10, 2024

Definitely... for v2 we actually have the serializer methods accept a stream. Will that be sufficient? Or do you think you'll need an extension method for file as well? I think the best approach is to keep it open to stream, and allow consumers to fill in implementation details such as file. But definitely open to feedback around this. :)

from home.

FaustoNascimento avatar FaustoNascimento commented on May 10, 2024

For my purposes, that's plenty. Though I would suggest maybe keeping it inline with what XmlSerializer offers: Stream, TextReader/TextWriter and XmlReader/XmlWriter.

from home.

FaustoNascimento avatar FaustoNascimento commented on May 10, 2024

Getting an XmlWriter would make modifying the XML much easier for example. It's what I'm currently using to do the indentation.

from home.

Mike-E-angelo avatar Mike-E-angelo commented on May 10, 2024

Ah ok... TBH I am still confused between all the options in how XmlSerializer allows you to initialize. I tried to dig into it but it seems as if they really do use all 3 of those. If you know of any resources that explain why there are 3 (or know outright) I would be happy to check it them out.

We could create a Using(XmlWriter) method to the ConfigurationAPI. Or maybe Using(()=>XmlWriter) as a new XmlWriter is created for each serialization. The same could also be used for XmlReader, too.

from home.

Mike-E-angelo avatar Mike-E-angelo commented on May 10, 2024

OK with v2 mostly complete we can revisit this again. We currently use stream, but the ask here is for text/xml reader/writer. We do use a factory for creating xmlreader and xmlwriters. You can see that here.

It would be easy enough to create a new serializer extension that creates a new implementation via use of the stream or otherwise.

So something like:

class XmlFactoryExtension : ISerializerExtension
	{
		public IServiceRepository Get(IServiceRepository parameter) => parameter.Register<IXmlFactory, MyFactory>();

		void ICommand<IServices>.Execute(IServices parameter) {}
	}

	class MyFactory : IXmlFactory
	{
		public IXmlWriter Create(Stream stream, object instance)
		{
			...
		}

		public IXmlReader Create(Stream stream)
		{
			...
		}
	}

Then using it as such:

var serializer = new ExtendedConfiguration().Extend(new XmlFactoryExtension()).Create();

I am hesitant to add more API surface than is required, as I myself find the different ways of creating a document/instance very confusing, but I am open to feedback as always.

How does this suggested approach look/work for everyone?

from home.

FaustoNascimento avatar FaustoNascimento commented on May 10, 2024

The ask here was for Serialize and Deserialize methods to accept other parameter types (namely those that are already supported by the default XmlSerializer - TextReader/TextWriter and XmlReader/XmlWriter).

Maybe I misunderstood it, but I think that what you suggested goes in a different direction and is more complicated to use than creating simple overloads for Serialize/Deserialize which accept those parameter types?

from home.

WojciechNagorski avatar WojciechNagorski commented on May 10, 2024

What kind of function I can do with it? I don't know if it is useful for users. There is some real example?

from home.

Mike-E-angelo avatar Mike-E-angelo commented on May 10, 2024

OK so it seems that this all really hinges on my ignorance around the connections between Xml/Text* and Stream, so you'll have to forgive me here. Taking another peak, it appears you can create a System.Xml.XmlWriter by either a stream or TextWriter. I think what I got caught up in was trying to find the actual implementation to where the stream was used (different matter altogether).

In any case, our current design is suboptimal. It is currently as such:

public interface IExtendedXmlSerializer
{
	void Serialize(Stream stream, object instance);

	object Deserialize(Stream stream);
}

When it sounds like it should be this:

public interface IExtendedXmlSerializer
{
	void Serialize(System.Xml.XmlWriter stream, object instance);

	object Deserialize(System.Xml.XmlReader reader);
}

and a set of extension methods as such:

public static class Extensions
{
	public static void Serialize(this IExtendedXmlSerializer @this, Stream stream, object instance)
		=> @this.Serialize(System.Xml.XmlWriter.Create(stream), instance);

	public static void Serialize(this IExtendedXmlSerializer @this, TextWriter writer, object instance)
		=> @this.Serialize(System.Xml.XmlWriter.Create(writer), instance);

	public static object Deserialize(this IExtendedXmlSerializer @this, Stream stream)
		=> @this.Deserialize(XmlReader.Create(stream));

	public static object Deserialize(this IExtendedXmlSerializer @this, TextReader reader)
		=> @this.Deserialize(XmlReader.Create(reader));
}

How does that look, @FaustoNascimento? That actually would not be too much work and I appreciate your patience/persistence in helping me to see this. Especially since this could be a breaking change it's better to do it now before we actually release anything to Nuget. :)

from home.

Mike-E-angelo avatar Mike-E-angelo commented on May 10, 2024

@wojtpl2 this is actually a fundamental issue with the design as the lowest common denominator here is the System.Xml.XmlWriter/Reader. It is sort of complicated by the fact that I originally designed it with it being format-agnostic, but I think it's pretty clear at this point that is something that is probably better for v3.

So something like this (in v3):

public interface ISerializer<TReader, TWriter>
{
	void Serialize(TWriter writer, object instance);

	object Deserialize(TReader reader);
}

public interface IExtendedXmlSerializer : ISerializer<System.Xml.XmlReader, System.Xml.XmlWriter> {}

from home.

FaustoNascimento avatar FaustoNascimento commented on May 10, 2024

Careful with creating a XmlWriter from a TextWriter - if I'm not mistaken, you cannot easily change the encoding used by the TextWriter and it defaults to UTF16, so the header of the XML will state it's encoded using UTF16, as oppose to UTF8 (I found this out the hard way, when I was trying to create an extension method for EXS to Serialize directly to file).

Instead of having extension methods, would it not be easier to create overloads?

Edit
Sorry, just realized you're suggesting the extension methods as a temporary fix for v2, with v3 then being done differently. Still, with the overloads just be careful of how the XmlWriter is created.

from home.

Mike-E-angelo avatar Mike-E-angelo commented on May 10, 2024

Ah, it's definitely open to discussion, even for v3. I will share my perspective and I would like to hear your thoughts on it.

From my view, my concern is always about exposing surface for any component that I write. Not just for me, but for any consumers of that component. Here is a good thread about this very issue that was encountered during the development of v2 (see point 2).

In that case we're talking about ~30 methods that can boiled down to a great deal less. Here we're talking about the same thing, except in the opposite direction. It's still taking from 2 to 6, but that means every implementor of that interface will have to create an implementation for each and every one of those methods each and every time.

Now in the case of some specialized knowledge of ensuring correct instantiation of objects, then that might change things a bit, but I would probably err on encapsulating that in a factory which is then called by the extension method.

I so guess the point is that for every method on the interface, maximum effort should be made to ensure that it isn't overlapping with other methods on that interface. I am definitely open to discussion on this and would like to hear your thoughts about it.

Also, if you have any finalized code that you are using that you would suggest in instantiating an XmlWriter, I would be interested in that. In fact I believe I saw some bug reports on the new Roslyn CPS project system for Visual Studio that was talking about the UTF16 issue.

from home.

Mike-E-angelo avatar Mike-E-angelo commented on May 10, 2024

Great! I will look into it and let you know.

from home.

Mike-E-angelo avatar Mike-E-angelo commented on May 10, 2024

Alright, I have been checking this out. A few questions for you, @FaustoNascimento:

  1. Is there a reason for using new XmlTextWriter vs. System.Xml.XmlWriter.Create?
  2. Are you aware of File.Create? Using this, you could write to a file without the need of using XmlDocument. Additionally, this is supported by .NETStandard1.6 while XmlTextWriter oddly isn't.
  3. Looks like the code here is using a XmlTextWriter here and not a TextWriter, and wanted to verify. I am interested in knowing if there was anything you landed on with the utf8 vs utf16 as a solution. Or maybe you just ended up ditching TextWriter altogether?

After spending more time than I expected here, I'd also like to reiterate the drive/desire for simplicity. I basically took about an hour (again LOL) of my time to try to wrap my mind around all the ways you can create an XmlWriter, and the associations/connections between all the components. For instance, proper closing/disposing of each item (and wrapped item) and additionally with how XmlWriterSettings plays in with this (it doesn't when you use a new XmlTextWriter).

I think this was also another goal achieved by simply using Stream. Nonetheless, I see the value in exposing the root denominator here, especially if we have a strategy for keeping things simple via the proposed methods above.

from home.

FaustoNascimento avatar FaustoNascimento commented on May 10, 2024
  1. Yes, it's called dumbness. Or as prefer to label it for myself... "lack of sleep". Not sure anyone will buy that though...
  2. I think the reason why I used the XmlDocument here was simply because I was already using the XmlTextWriter so it sort of just fit in nicely.
  3. If I recall correctly, I started with a TextWriter, but that's when the encoding issues occurred, so I just ditched it altogether.

There's no doubt that the code above can be improved, as I said not quite sure just how much of that is usable.

from home.

Mike-E-angelo avatar Mike-E-angelo commented on May 10, 2024

Ha, sounds good, @FaustoNascimento. Thanks again for your contribution. 👍

So I went ahead and got in the extension methods. You can now use Stream/Xml/Text/Writer/Reader with ExtendedXmlSerializer. 🎉

Unfortunately (or fortunately depending on your perspective), it did cover some issues with performance. I will make a new issue for this. Hopefully we can release a new pre-release soon so that you can try this out. I will be closing this issue for now. Please feel free to re-open/open a new issue if you have trouble with the features as designed.

from home.

Mike-E-angelo avatar Mike-E-angelo commented on May 10, 2024

Ah @FaustoNascimento looks like the latest version is deployed for better or for worse here if you'd like to try it out:

https://www.myget.org/feed/wojtpl2/package/nuget/ExtendedXmlSerializer

from home.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.