December 2003 - Posts

CommentAPI no longer working on .Text

Note: this entry has moved.

Adding a feature (namely, the new Url rewriting happening in weblogs.asp.net) and breaking another (much more important) is certainly not good for us. I can no longer post comments from RssBandit. I am frustrated.
If I had the source code for the current version (that is, if ScottW was so kind as to keep a CVS/GDN updated version I can hack into), I could at least tell what is broken and maybe find a workaround.
No luck, I guess...
XmlSchema for C# XML Comments

Note: this entry has moved.

Sometime ago, I created this schema to perform some extra validation on the comments, as well as use it as a starting point to adding my own required elements for all projects. This was mainly a "need" for the NMatrix project, for example, requiring an <author name="Daniel Cazzulino" mail="kazzupepe@hotmail.com" /> tag in all public classes I create.

I think it may be useful to someone, so here it is again. A valid cool XML comment that many ignore is <see langword="[c# language keyword]" /> that automatically gets italicized and shows the appropriate VB.NET equivalent. Look for <!-- undocumented element -->" in the schema for other interesting ones.
Thanks!

Note: this entry has moved.

It's cool to see one's blog in the screenshot of the upcomming version of RssBandit by its very creator, Dare Obasanjo.

Thanks Dare! :D

XmlSerializer and open content models

Note: this entry has moved.

Using the built-in code generation features (let's say xsd.exe or the approach I've outlined), the generated classes use the System.Xml.Serialization.XmlAnyElementAttribute and System.Xml.Serialization.XmlAnyAttributeAttribute to capture the foreign elements and attributes in an instance document. Unfortunately, this is not enough.

Let me explain: one cool thing about the XmlSerializer is that you can trap "unknown" (i.e. not belonging to the XSD schema for the document) nodes (either elements or attributes) by attaching to the UnknownNode, UnknownAttribute or UnknownElement events. This may be useful if you want to trap these elements and do something with them. For example, I could attach an my:postProcessor="My.PostProcessorClass, My" attribute to an element and provide custom post-deserialization processing for it. To allow that, you have to make the content model (at least for attributes) open, so that the XSD validation won't fail when it finds such an attribute. The usual way is to add the following to a complex type definition:

<xs:anyAttribute namespace="##other" processContents="skip" />
Do you dare?

Note: this entry has moved.

Every now and then I smash against Dare's opinions such as this one or that one or his final word on the matter . And everytime I do, the more he becomes an important independent, objective and qualitative voice for me, and the less I think of him as a MSftie (although he joined pretty recently).
I hope he has a long career inside MS. More minds like his inside there and the positive signs we see here and here may spread, and turn MS into a company we can love, instead of looking at it with distrust, with our back against a wall ;)
Evolving existing APIs in backwards-compatible way (i.e. SOM and DOM)

Note: this entry has moved.

A couple days ago I posted about the inconvenience of an API that is designed to expose augmented data depending on its state. This is the case for the XmlSchema Object Model (SOM) in .NET and its Post-compilation infoset (PCI), as well as the DOM and its Post-schema validation infoset (PSVI). Dare Obasanjo aknowledged this issue, but is resigned, saying it's too late to fix any of this.

I believe it's not. For classes that have grown too big, or became messy by mixing concepts like the two mentioned above, there's still room for improvement, without risk of breaking compatibility, which is a must in a serious framework such as .NET.
The "solution" involves creating new interfaces to hold the funcional subsets, and make the "legacy" class implement them as simple passthrough accessors to the cluttered "full" interface. In the case of the SOM, a new hierarchy of interfaces could be implemented, starting in a ICompiledXmlSchema. The XmlSchema.Compile method could return the new type:

public ICompiledXmlSchema Compile(System.Xml.Schema.ValidationEventHandler handler)
{
  // Perform compilation as usual
  return (ICompiledXmlSchema) this;
}

Code using the void old version would remain unaffected, as they would be using:

XmlSchema xsd; //Load it somehow
// Perform compilation as usual
xsd.Compile(null);

In order to take advantage of the pre-compilation version subset a cast would be needed, for example to an IXmlSchema:

IXmlSchema prexsd = (IXmlSchema) XmlSchema.Read(stream, null);

This interface would expose pre-compilation only members, such as XmlSchema.Items, whereas the ICompiledXmlSchema would replace it with XmlSchema.Elements and XmlSchema.Attributes and XmlSchema.SchemaTypes instead.

This offers a more consistent programming model to the newer code taking advantage of these interfaces, while the "legacy" code keeps working. The typical case for read&compile schemas would be, therefore:

XmlSchema prexsd = XmlSchema.Read(stream, null);
ICompiledXmlSchema pcixsd = prexsd.Compile(System.Xml.Schema.ValidationEventHandler handler);
// Now I don't need to worry about pre vs post compilation members!
Thoughts?
Do you need another reason to avoid "sp_" prefix?!

Note: this entry has moved.

Note: Do not preface your stored procedure names with sp_, because doing so reduces performance. When you call a stored procedure that starts with sp_, SQL Server always checks the master database first, even if the stored procedure is qualified with the database name.
from Designing Data Tier Components and Passing Data Through Tiers, section titled "Recommendations for Using Stored Procedures with Data Access Logic Components".
A more sound licensing scheme for CustomControls

Note: this entry has moved.

Some time ago I complained about a naive approach to the subject suggested in an MSDN article. It looks like I was not the only one thinking along the lines of signed licencing files :o)

Update: another product also exists, which is more powerful and mature, judging by its features description and blog comments...

VS.NET Xml Intellisense and Schemas

Note: this entry has moved.

As most people know, in order to get intellisense for an "xmlnamespaced" document inside the IDE, the schema defining that namespace either has to be in the same project/folder or in c:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\schemas\xml (default VS installation folder). Therefore, if you have multiple projects, where one of them provides the schemas and another uses them in a document, you have to duplicate the file into the VS folder, and then you can forget copying it back when you change it in the project, etc... a mess.

Well, if you use Windows XP and NTFS volumes, there's a cool workaround, which involves creating a "hard link" inside the VS folder to the real file location. This way the file is not duplicated, but VS still finds it and keeps in sync with the real file location. It's easy to achieve: go to the VS folder aforementioned, and use the following command:

fsutil hardlink create {new filename} {existing filename}
Enjoy!
XmlSchema Object Model, Post-compilation InfoSet (PCI) and API consistency

Note: this entry has moved.

The Schema Object Model (SOM), much like the DOM, holds pre- and post-compilation (validation for DOM) information items. However, the model is not consistent for both, in the case of the SOM. For example, for the pre-compilation phase, you iterate the top-level items through the XmlSchema.Items collection:

foreach (XmlSchemaObject item in xsd.Items)

On the other hand, after schema compilation, when all the items in that "cat bag" go to the corresponding XmlSchema.Attributes, XmlSchema.Elements and XmlSchema.SchemaTypes properties, you can't keep iterating like that because now the iterator returned by the XmlSchemaObjectTable.GetEnumerator (they are all of that type), returns an IDictionaryEnumerator, meaning you now have to use either:

foreach (DictionaryEntry entry in xsd.Elements)
{
    XmlSchemaElement el = (XmlSchemaElement) entry.Value;
    //...
}
or:
foreach (XmlSchemaElement el in xsd.Elements.Values)

Which isn't very consistent with the approach for pre-compilation equivalent property. Besides, it's always a bit cumbersome having to deal with two sets of available properties for the pre/post state.
I'm wondering whether it would be better to have a separate object model extending the pre- one and adding the new post- ones. I think a cool API design would be to turn all of the pre- SOM to interfaces, and make the concrete pre/post implement it. The later could implement them explicitly, so that by default you don't have to "see" the pre- when you're dealing with the post- SOM.
Any thoughts?

More Posts Next page »

Search

Go

This Blog

News

     

      Microsoft MVP Profile

Syndication