XML
It may seem unrelated, but if you haven't read Fowler's article on DSLs (from Google cache if it's down like now), please do so now. It will help you understand why XAML goes far beyond WPF and presentation.
Configuration is typically nothing more than a DSL (external DSL in Fowler's terms) that serves to setup the variable parts of a certain runtime library or framework. For example, while a logging framework has many "static" or invariant components (i.e. logging "pipeline" execution, interaction between components, registration of variable components, etc.), there are variable parts which determine the runtime behavior, such as concrete trace listeners attached to given trace sources, the specific file a file listener will write to, and so on.
With careful API design, manipulating the actual runtime classes wouldn't be significantly different than manipulating its corresponding configuration classes or files. Your API is already a sort of DSL for your domain. For example, system.diagnostics can contain the definition of trace sources:
<source name="TraceTest" switchName="SourceSwitch" switchType="System.Diagnostics.SourceSwitch" >
 <listeners>
   <add name="console" />
   <remove name ="Default" />
 </listeners>
</source>
To achieve the same using the corresponding runtime classes, you would write:
TraceSource source = newTraceSource("TraceTest");
source.Switch = newSourceSwitch("SourceSwitch");
source.Listeners.Add(newConsoleTraceListener());
source.Listeners.Remove("Default");
Note how close the two are. All you need is a good object (de)serialization format and you can go straight from the external DSL ("config" file) to the runtime objects without any intermediate representation. This wasn't possible before with .NET 1.x and 2.0 due to the lack of extensibility of the XmlSerializer and its excesive (IMO wrong) focus as a generic XML Schema <-> object converter (pretty much an unattainable goal if you want full fidelity both ways) and a webservices-only feature.
XAML, on the other hand, was thought from the beginning as a fully extensible object serialization format. With it, it's quite easy to achieve what's shown above, straight from the domain/runtime classes. One possible XAML syntax for the TraceSource example could be:
<TraceSource Name="TraceTest">
 <TraceSource.Switch>
    <SourceSwitch Name="SourceSwitch"/>
  </TraceSource.Switch>
 <TraceSource.Listeners>
   <ConsoleTraceListener />
 </TraceSource.Listeners>
</TraceSource>
(this wouldn't work with current diagnostics classes)
You end up having executable models :)
The only requirement to enable XAML serialization on your classes is to provide a public parameterless constructor, and public read/write properties for the stuff you want to get serialized. Validation can be done after deserialization by implementing System.ComponentModel.ISupportInitialize.
So, why would you want to develop and maintain a DSL/configuration model for your domain classes ever again?
And XAMLÂ is a v1 release, so I can only expect it to get better, more flexible and powerful over time.Â
I think I'm not the first guy to end up in this situation: I created a lot of content (and loyal readers) on some blog hosting site (in my case http://weblogs.asp.net) and now I want to move on, maybe with a self-hosted solution, maybe with Blogger and its custom domain support, whatever.
There are two separate issues:
- You don't want to start on your new site with zero content. You have created a TON of it on the old site. This batch migration process can be painful and you may need to write code to do it. Typically you'll want to leave on the old site just a "teaser" of your entries, and a link to your new cool site. At the very least, you want to leave a link.
At this point I hope you realize that the "why not an HTTP 301 and that's it?" is not a valid answer for pretty much any blog hosting site I know of. They won't do that kind of redirect if you want to move off, and there's still the question of compatibility of URLs generated by your new blogging engine, etc. I'd keep it "simple" and add a link to the old entries automatically using some blogging API your engine must surely expose.
- You don't want to lose the traffic that the old (but surely much better established) community site used to generate. On my current blog at Clarius, more than half the traffic is still coming from http://weblogs.asp.net. I only started tracking this recently through Google Analytics (post for another day) so it may very well have been much higher percentage when I had just moved.
Also, once you have moved to the new site, in order to keep the old one bringing traffic, you may want to cross-post (either full entries or summaries/teasers) to the old one, so that people start coming to your new blog to read the entries and leave comments.
You might be thinking: in order to just post the same content in two different blogs, all I need to do is write my entry, Publish to one blog account in WLW, then switch to another blog account, and post again. True, but that way you have basically forked your traffic and your audience: now users will be posting comments on both entries, oblivious to the fact that there's one new location that you'd rather have them use. Also, because your old blog has been around for more time and in an established community, those are the entries that will more likely be linked by others and shown first on search engine results, etc. All that will go against your goal of moving people over to your new site.
So what I did to solve issue 2) is create a WLW plugin that allows me to cross-post blog entries (summaries or full posts, at my choice) that link back to my main/new blog, all with a single click:
And I provide some plugin options too:
The options deserve some more explanation besides being quite obvious:
- Target blog: this is a dropdown that shows all the blog accounts you have currently registered in WLW. The "source" blog will always be the one you're editing and publishing the current blog entry to.
- Post summary: if checked, the cross-post will only contain the first 500 (200 is the default) characters of your current entry.
- Preview post: this option (true by default) allows you to see in WLW the generated summary or full entry with back-link, and it will show up with the target blog selected in WLW, as well as a new Draft that you can save, publish, delete, etc. Once you get more confident with how the plugin works, you'll typically want to unckeck this option, as it's pretty annoying to end up with duplicate titles in your "Recently Posted" sidebar for every entry.
My plugin is leveraging all of WLW features for posting, so if you can post to a blog from WLW, you can cross-post to it with my plugin too.
With the options above, here's what I got for one of my recent entries on PowerShell:
The plugin will automatically add the "..." when the characters limit is reached, append a link with an icon pointint to the full article in your source blog, and also a full link at the bottom. It's interesting to note that I'm not doing just a string.Substring there. That would either break the HTML pretty bad, or I'd have to post only the text content value of the HTML, which would break code blocks, styles, etc. as it would not include any markup. Instead, what I'm doing is the "right thing" by having an internal custom XmlReader that counts the characters it reads from text nodes and starts reporting stops reading further (but does report end elements for all ones from the current location). In the case above, you can see that the character count was exceeded while in the middle of some code (typically a <pre> element), yet the image link is displayed correctly, as well as the full link.
Installation is trivial. From the project release page, you can either:
- Get the MSI installer. It will just copy the plugin dll to your plugins folder under the WLW install location (will look for %ProgramFiles%\Windows Live Writer\Plugins)
- Get the binaries. Copy the included files to the above location manually.
- Get the sources. Open the solution in VS2005. Build. An AfterBuild target will attempt to copy the output to the above location, so you should even be able to run/debug from there.
I submitted the plugin to the Windows Live Gallery, so it may show up there too :)
Enjoy!
A document fragment is an XML file that doesn't have a root element:
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
...
</System>
<ApplicationData>
...
</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
...
</System>
<ApplicationData>
...
</ApplicationData>
</E2ETraceEvent>
...
In order to read this with plain XmlReader code, you can do the following:
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlReader reader = XmlReader.Create("tracelog.xml", settings))
{
while (reader.Read())
{
// Process each node of the fragment,
// possibly using reader.ReadSubtree()
}
}
It may be the case that instead of the more performant (and definitely suggested approach if the file is big) XmlReader API, you may want to use XmlDocument or XPathDocument to be able to query the file using full XPath. In .NET 2.0, the XPathDocument class will successfully load an xml fragment, which was kind of surprising to me as I'm pretty sure it was not a supported feature in .NET 1.1. The surprising part is because technically, a fragment is NOT a document. The way the XPathDocument does its magic is by creating a "transparent" root node, and holding the fragments from it. I say it's transparent because your XPath queries can use the root node axis and still get properly resolved to the fragments:
private void LoadXPath(object sender, EventArgs e)
{
string xml = @"<item id='1' /><item id='2'/>";
XmlReaderSettings set = new XmlReaderSettings();
set.ConformanceLevel = ConformanceLevel.Fragment;
XPathDocument doc = new XPathDocument(
XmlReader.Create(new StringReader(xml), set));
XPathNavigator nav = doc.CreateNavigator();
Debug.Assert(nav.Select("/item").Count == 2);
}
Note how the query is "/item", which would return the single root element in a regular XML document, but here it returns the two items which are hanging from the "transparent" root (that's why I call it such, as there's no way to "see" it, not even by using the OuterXml on an XPathNavigator sitting on the root).
If you're more of an XmlDocument guy, or maybe you need to perform updates to the fragments using random access via XPath queries too, then you're pretty much out of luck, as the XmlDocument will fails with a "System.Xml.XmlException: There are multiple root elements. Line x, position y." exception if you try to load an xml fragment (via string or XmlReader, doesn't matter).
Here's where a new class we added to the Mvp.Xml library can help: XmlFragmentReader. This is an XmlReader-derived class which receives a root element name (and optionally a namespace) to fake a root node. Because it's an XmlReader class, it does so in a streaming fashion, and shouldn't have an impact in reading performance, as all its members just pass-through to the base reader (the one reading the fragments) except on the initial state and the ending one (where the fake root is reported). Usage is straighforward:
private void LoadXml(object sender, EventArgs e)
{
string xml = @"<item /><item/>";
XmlDocument doc = new XmlDocument();
XmlReaderSettings set = new XmlReaderSettings();
set.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlReader reader = new XmlFragmentReader("root",
XmlReader.Create(new StringReader(xml), set)))
{
doc.Load(reader);
}
Debug.Assert(doc.SelectNodes("/root/item").Count == 2);
}
Note that the root node is not transparent as is the case with the XPathDocument, so you have to include it in your XPath queries.
Get the Mvp.Xml library and enjoy!
Quite some time ago (around XML raise as a universal data format), the W3C seemed to be in doubt of the value of QNames (prefix + local name) in attribute values.
One very clean evidence of this inconsistency around the best practice on QNames on attribute values is the W3C XML Schema specification, which was pretty happy with QNames in attributes:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="my-schema"
xmlns="my-schema"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="element1" type="xs:string" />
</xs:schema>
At the same time and in the complete opposite direction, the RDF specification, developed around the same time as XML itself, clearly favors XML entities instead of allowing QNames on attributes:
<?xml version="1.0"?>
<!DOCTYPE rdf:RDF [<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#">]>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:exterms="http://www.example.org/terms/">
<rdf:Description rdf:about="http://www.example.org/index.html">
<exterms:creation-date rdf:datatype="&xsd;date">1999-08-16</exterms:creation-date>
</rdf:Description>
</rdf:RDF>
(from the RDF Primer)
RDF explicitly forces the rdfs:datatype and other attributes to be full URI References, which is why the only abbreviation mechanism is through XML entities. I find it hard to see why the above is any better than:
<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:exterms="http://www.example.org/terms/">
<rdf:Description rdf:about="http://www.example.org/index.html">
<exterms:creation-date rdf:datatype="xsd:date">1999-08-16</exterms:creation-date>
</rdf:Description>
</rdf:RDF>
Given that XML Schema, SOAP, even XAML heavly uses QNames in attributes, I believe RDF is now in an awkward position maitaining that annoying restriction. It would be as simple to solve as saying "when a QName is used, it will be expanded using the XML prefix mapping in scope, plus the fragment identifier '#' plus the local name", so that xsd:date becomes http://www.w3.org/2001/XMLSchema#date.
SSE is an XML micro-format and corresponding sync algorithm that can be embedded in RSS or Atom feeds to allow for two-way synchronization among peers. More important: the algorithm allows for mesh-style synchronization between nodes, with no concept of a "master" copy. This can be game-changing for data-exchange and app-level data interop. But only the future will tell.
SSE was initially announced by Ray Ozzie (Microsoft's CTO). Ed Jeziersky brought this technology to my attention (thanks Ed!), and I soon got pretty excited given its potential. It had been quite a success in Strong Angel III too.
You can learn more about SSE by watching the MSDN TV video and reading the latest SSE spec and links above.
So I started working on an open-source implementation I got very good synergy from Steven Lees, Paresh Suthar and the rest of Ray Ozzie's Concept Development Team. It's great to see Microsoft so supportive of open source projects :D (I guess most people don't realize there's a grassroots "revolution" going on in that aspect inside Microsoft... see what's happening with the DLR, ASP.NET, etc.).
I'm glad to announce that the first beta release of the open-source SimpleSharing.NET library is available for download now. Right now, it has 83% code coverage through unit tests so I'm quite confident on its quality :)
What can you do with the library right now?
- Create an adapter (repository) that talks to your underlying application data/business objects (your CRM system, data-entry app, whatever)
- Export RSS feeds with synchronization information embeeded for merging with other feeds
- Import RSS feeds from other peers
- Synchronize a local feed via HTTP with a server feed
- Do all this without changing any code in your app: this makes for a hassle-free way to add import/export/sync functionality to your application
The SSE spec takes care of defining a standard algorithm for detecting conflicts and updates in a merge operation, as well as the behavior for deleted and created items. This makes for a predictable behavior regardless of the actual implementation technology.
I created this library with the following goals in mind:
- Have a minimal library that can be easily extended with adapters to accomodate simple synchronization scenarios
- Provide a full .NET as well as .NET Compact Framework implementation
- Interop with other SSE implementations as they come along
- Allow in a future version to synchronize weblog feeds across multiple disparate engines (should be very helpful for people moving from a hosted service such as weblogs.asp.net to a self-hosted environment that want to avoid losing the traffic from the old site)
The following are non-goals:
- Provide a full-blown and highly optimized synchronization engine (i.e., you can hardly use it for full database merge/replication, complex data/binary payload sync, etc.)
- Provide a server-side story
- Provide a service to periodically perform sync with a server and manage jobs (this means you have to manually sync from your app using the exposed SyncEngine API)
Included in the download is a sample application that is a very simple Customer CRUD application that provides a custom adapter to import/export feeds using its internal data-access component (so show how the adapter component can indeed be implemented on top of existing application components), and which syncs with a simple ASMX webservice via HTTP. This sample application uses a SQL Compact Edition database, so you'll need to install it, as well as the SQL Compact Edition Tools for VS 2005. If you don't want to, just exclude the Samples solution folder from the solution.
Feedback welcomed! (either comments here, or in the user forum)
Today, I was working on some GAXsoftware factory stuff. I just couldn't remember if a particular element I had at hand in an instance document supported xs:anyAttribute or not in the corresponding schema. So I though "how handy it would be if I could press F12 (Go to Definition) and be taken to the schema for it". I tried it:
Imagine my surprise when I saw:
Quite unexpected for me, I was presented with the XSD for the document with the relevant element definition focused under the cursor! Now, the element happens to he a ref to the definition which is somewhere else. So I thought "how handy it would be if I could press F12 and be taken to the definition of that referenced element". I tried it:
And I was inmediately taken to:
Simply amazing. I didn't know about this feature. What's more, you can use Ctrl+[minus sign] to navigate back, just like you do when you F12 to definitions in any code window.
Impressive job, XML team. Thank again!!!!!!
A while back I've reported as a bug that VS XML editor breaks if you use XInclude elements in the document. You may ask: "who cares? .NET does not support XInclude anyway!". It just so happens that the recently released version of the Guidance Automation Extensions (GAX) include the Mvp.Xml library, which adds support for XInclude in your guidance package configuration file.
So, in order to benefit from the better manageability and modularity of you guidance package configuration, you have to pay the price of losing intellisense :(... As a workaround, you can keep a dummy XML file around in the solution that you use for authoring the recipe with full intellisense, before you split it in multiple files. However, once you need to start editing it, you're again stuck. I believe the added flexibility is worth the price anyway, but that's just me....(and I'm an XML MVP, so I may be biased ;))
Of course you already knew that the PDC 2005 sessions are available online, right? (although not for much longer, I heard). But you just don't have the time to browse the list to find the interesting ones and download them one by one... Well, now you can point your favorite site copier software to the starting point Full PDC05 Sessions (grouped by DVD ;)), and download the full set. Note that the links point to the zipped presentations only.
This is the magic of XML :)... you just need a list of sessions they expose, plus a rather simple XSLT transformation (except for the muenchian grouping ;)), and off you go!
Enjoy... I suspect when they get huge download numbers for all sessions, this will end pretty soon ;)
Altova announced a royaltee-free distribution of
AltovaXML engine complete with .NET interfaces. It supports XQuery 1.0 and XSLT 2.0 (with or without schema support). Excelent news for .NET developers!!!
Via TSS (thanks
Paul!)
Generating classes from XSDs, and being able to customize the process has been a
favorite topic of mine for a while. Now there's a Guidance Package that
Matias wrote for that very purpose, using the approach I proposed in
my MSDN article. Read about the tool in
his blog entry.
Every now and then, an
article revives that old
debate on whether to code web services starting from XSD/WSDL or starting from classes that generate the former. Answers from
one side or
the other fail to realize the truth:
there's no black and white in the real world. Amen
Craig!
Just for the record: I agree with Craig in that you cannot do one without the other. Which way you start, is a matter of timing, which won't save you from learning both technologies. And I would even argue that learning how to properly understand and use the host of XML serialization attributes to get what you want on the wire is almost on a pair with learning XSD (except for the esoteric features like substitution groups that you don't even need to learn as they are not even supported by XmlSerializer).
In a major achievement for
MVPs contributing to the
Mvp.Xml project, a couple weeks ago I signed a license agreement with Microsoft to confer ample rights to use and distribute our code base. This has several implications:
- You may see more and more XInclude support in XML configuration files coming out from patterns & practices, as they were the ones that helped navigating the licensing process at Microsoft.
- Our code may be used anywhere Microsoft feels they want to. This is way cool for us :)
- We can continue to deliver new features from the project, and Microsoft will automatically have rights to use that and distribute it. The cool thing about this is that they will no longer be tied to the huge release cycles of their regular products, and may instead choose to release through our channel. And we can also implement stuff that they are reluctant to (for whatever reason) and take away the risk of implementing a feature themselves.
- IMO, this is a very important indication that Microsoft is serious both about the MVP program and what it can deliver, as well as supporting open source communities that are willing to cooperate in ways that do not undermine Microsoft intellectual property rights.
This also imposses a responsiblity on us, mainly to keep up working the way we did so far, contributing high-quality code, looking for opportunities to continue improving the XML experience in .NET, and seek to become a channel to deliver cool stuff that may be left out of the product otherwise.
Next targets:
- Reach an agreement with Dare to contribute the EXSLT.NET codebase to our project so that Microsoft automatically gains the rights to use it at will (making the lives of those developing @ and 4 Microsoft WAY easier).
- Once and for all move the Schematron.NET project over to this one. I need to improve it significantly and adapt it to match the ISO draft.
- Seriously start thinking about implementing RelaxNG, as it's another area that could be of interest to Microsoft
- Talk with the XML team about the feasibility of taking code/ideas they would like to see released under our project.
BTW, this agreement came out of good will from both sides, and I didn't make any money in the process.
On a project I'm working on for
MS Patterns & Practices, we were excited about the
XInclude spec becoming a recomendation and anxious about using it in our project, which is quite heavy on XML usage for configuration. The modularization that could be introduced transparently by XInclude was very compelling. Even if it
will hardly be implemented in .NET v2, we could still take advantage of the
Mvp.Xml project
XInclude.NET implementation
Oleg did. But apparently it's almost impossible to use XInclude and XSD validation together :(
The problem stems from the fact that XInclude (as per the spec)
adds the xml:base attribute to included elements to signal their origin, and the same can potentially happen with xml:lang. Now, the W3C XML Schema spec says:
Validation Rule: Element Locally Valid (Complex Type)
...
3 For each attribute information item in the element information item's [attributes] excepting those whose [namespace name] is identical to http://www.w3.org/2001/XMLSchema-instance and whose [local name] is one of type, nil, schemaLocation or noNamespaceSchemaLocation, the appropriate case among the following must be true:
And then goes on to detailing that everything else needs to be declared explicitly in your schema, including xml:lang and xml:base, therefore :S:S:S.
So, either you modify all your schemas to that each and every element includes those attributes (either by inheriting from a base type or using an attribute group reference), or you validation is bound to fail if someone decides to include something. Note that even if you could modify all your schemas, sometimes it means you will also have to modify the semantics of it, as a simple-typed element which you may have (with the type inheriting from xs:string for example), now has to become a complex type with simple content model only to accomodate the attributes. Ouch!!! And what's worse, if you're generating your API from the schema using tools such as xsd.exe or the much better
XsdCodeGen custom tool, the new API will look very different, and you may have to make substancial changes to your application code.
This is an important issue that should be solved in .NET v2, or XInclude will be condemned to poor adoption in .NET. I don't know how other platforms will solve the W3C inconsistency, but
I've logged this as a bug and I'm proposing that a property is added to the
XmlReaderSettings class to specify that XML Core attributes should be ignored for validation, such as XmlReaderSettings.IgnoreXmlCoreAttributes = true. Note that
there are a lot of Ignore* properties already so it would be quite natural.
Please
vote the bug if you feel it's important, and better yet, think of a better solution to it!!! ;)
Have you ever wanted you could just save an XML file and have a custom tool tell you what's the output of its validation with a schema (or set of schemas) just as it would be at runtime using the XmlValidatingReader? Go ahead and download the
Mvp.Xml.Design installer, and you can have that. Just assign to a file the custom tool "Mvp.Xml.XmlValidate" and set in the Custom Tool Namespace property a semi-colon separated list of schema files (either relative to the file location or with absolute path) and you're done. Everytime you modify the XML file and save it, the associated .txt file will tell you what the outcome of the validation is.
You can investigate other tools offered by the
Mvp.Xml project ;)
Now that the
XInclude spec
is officially a Recomendation, is it too late to include it in System.Xml v2? Unfortunately I think so :(
Luckily, you can still use it in your apps by using the
Mvp.Xml project
XInclude.NET.
With the advent of XML, each and every piece of software is configurable with it, from
Virtual PC to
IIS to
log4net to
Shadowfax and all the Application Blocks released from
PAG ... you name it.
If you think about it, however, it's quite easy to realize that what those XML files are actually, is nothing more than a text-based representation of the concepts in the particular domain of the tool/app. So, log4net has the concepts of Appenders, Filters, Object Formatters, and so on, while Shadowfax (as most SOA frameworks) has the concepts of Pipeline, Handler, Service Action, and so on. Therefore, XML is just a means to express the particular layout/behavior you want these tools/frameworks to have at run-time. It's not about XML, stupid! It's about the
Domain Specific Language (DSL) expressed in (serialized into) those tags.
A very important step forward to make these languages first-class citizens in the developer's minds and programming experience has been made by Microsoft with
the release of the tools necessary to build your own DSL editors/designers. With these specialized editors, the need for a generic XML editor (when used to edit configuration) will dissapear. How many people do you think is using generic XML editors to create instance documents that are used as
input for an application (other than just for testing purposes)? My bet:
NONE (InfoPath doesn't count, as it's not an XML editor but a forms tool, which just happens to use XML as the underlying store). Generic XML editors, instead, have been primarily used to
configure the myriad of tools/blocks/frameworks that you need to use to get your application up and running fast and with minimal effort (other than the one needed to configure it in the first place, an increasingly complex one indeed!). It's time to move forward.
That's why I think any effort put in creating
generic/customizable XML editors is futile. I believe the future is a multitude of specialized designers for the different aspects of an application (their DSLs). I hope sooner than later we'll see
an editor like this for tools like
UIP, and we'll have nothing to envy the
Eclipse guys...
The conference has been great. We're approaching the end, and I have to say I'm very satisfied. Even if I was one of the speakers, preaching the benefits of
Schematron (which went pretty well I think), and therefore didn't have to pay to be here, I'd have gladly done so. The level of talks is high and you get to meet a lot of cool guys from the entire XML space (definitely not only MS guys). No marketing, no beginner's topics, just XML and fun.
If I don't have some really exciting topic to talk about next year that Chris is willing to have on the conference, I honestly expect to be able to come back as an attendant. It's really that good.
Well done Chris!
If you get
this face when you explain what you're using XML for, you will know you've not passed the test....
The XmlSerializer has a farily well-known problem: the first time you use it, it will generate a class to read instances of the received type, compile it, and then load it. Of course, this can take considerable time, directly related to the complexity of the type and all its members and member types.
Unlike common wisdom, this is something that can be avoided and I have explained (albeit rather confusingly) in a
previous post. The usage was not great, though, as it was a command-line tool: ouch!
So, the
Mvp.Xml project debuts with a new package:
Mvp.Xml.Design. Now, in order to get a design-time version of a custom XmlSerializer for a type, you just assign the Mvp.Xml.XGen (renamed from the old SGen name that could be confused with a Whidbey tool of the same name), and you'll get a class to perform serialization of the type. The custom tool will take the first type in the file if multiple classes exist in it. Here's how it will look like:
The package comes in two flavors: an MSI installer or the raw source. The former also installs the sources besides the custom tool.
Go download it!