Syndication

News

     

Archives

Miscelaneous

Programming

May 2005 - Posts

Note: this entry has moved.

In a previous post, I discussed the way coarse-grained web service interfaces can be used in a strongly typed way by resorting to the xsd.exe or a cool custom tool. The only problem with that approach is that in order to communicate with the service, you need to pass an XmlNode, when you actually have an instance of an object. People will usually write code like the following to call the service:

 // Customer is an XmlSerializer-friendly class
Customer cust = new Customer("Daniel", "Cazzulino", new DateTime(1974, 4, 9));

// "Convert" the object to an XmlNode
XmlSerializer ser = new XmlSerializer(typeof(Customer));
XmlNode customerNode;

using (MemoryStream mem = new MemoryStream())
{
    ser.Serialize(mem, cust);
    mem.Position = 0;
    XmlDocument doc = new XmlDocument();
    doc.Load(mem);

    customerNode = doc.DocumentElement;
}

service.Execute(customerNode);

All the code to perform the XML serialization is so standard and repetitive that most developers will already have some sort of helper class with a single method that receives an objects and gives them back an XmlNode "view" of it.

There are several problems with this approach, though, all of them affecting the performance of your application:

  • Even if the information of the object is already in memory in the typed class, a new "copy" is generated through the XmlSerializer, consuming more memory as a consequence (the MemoryStream).
  • XML must be parsed from the stream, now consuming CPU processing
  • An XmlDocument with its entire object graph is built from the parsing process (that happens automatically when you call Load on it), which is now a different "view" of your object, but in terms of the DOM, which you will not use at all in your application

Interestingly, none of that is necessary, if you know the internal workings of the web service infrastructure used on the client-side proxy, which doesn't differ much from the one used on the server (asmx) side.

The XmlNode you pass to the service method call must be serialized and embedded as the body of the SOAP message to send to the server. Just like I explained a while back that it happens on the server side, the infrastructure will call XmlNode.WriteTo(XmlWriter w) passing a writer to emit content to the body of the SOAP message. So all we need to do is hold a "faked" XmlNode until that method is called, and serialize the object graph directly to that writer instead:

public class ObjectNode : XmlElement
{
    private object serializableObject;

    // All arguments for the base class are irrelevant.
    public ObjectNode(object serializableObject)
        : base("mvp", "xml", string.Empty, new XmlDocument())
    {
        this.serializableObject = serializableObject;
    }

    public override void WriteTo(XmlWriter w)
    {
        XmlSerializer ser = new XmlSerializer(serializableObject.GetType());
        ser.Serialize(w, serializableObject);
    }
}

Now your client code will look like the following:

// Customer is an XmlSerializer-friendly class
Customer cust = new Customer("Daniel", "Cazzulino", new DateTime(1974, 4, 9));

service.Execute(new XmlObjectNode(cust));

Now your client application will never consume resources for copying the object to a stream, parsing and loading an XmlDocument just to make a web service call. This will result in a significant performance increment, which will depend on the kind of object graphs you usually serialize.

For consistency with the approach I explained before for increasing the performance in this kind of scenario on the server side, the Mvp.Xml project implements this as another overload on the XmlNodeFactory class, so that your code is completely isolated from the implementation (which could even be based on the inefficient one explained before). Consuming code is equally simple, though:

service.Execute(XmlNodeFactory.Create(cust));

The internal implementation is just another overload returning a custom SerializableNode type:


public class XmlNodeFactory
{
    public static XmlNode Create(object serializableObject)
    {
        return new ObjectNode(serializableObject);
    }
    ….
    private class ObjectNode : SerializableNode
    {
        private object serializableObject;

        public ObjectNode() {}

        public ObjectNode(object serializableObject)
        {
            this.serializableObject = serializableObject;
        }

        public override void WriteTo(XmlWriter w)
        {
            XmlSerializer ser = new XmlSerializer(serializableObject.GetType());
            ser.Serialize(w, serializableObject);
        }
}

You can download the Mvp.Xml project (binary and sources) from SourceForge.

This post is part of the XML Performance series.

Note: this entry has moved.

Quite some time ago I started warning people about an important feature that was removed from ASP.NET Whidbey: non-visual components (IComponent-based classes). I logged the bug in Product Feedback, which resulted in a major number of votes that eventually draw some attention internally and resulted in the last update status which is Fixed.

Now that Whidbey Beta2 has finally hit the streets, it's time to regress the bug and see if it's really fixed. What follows is what I found (hint: another deception point).

I focus the discussion of the features that are missing on the article I published on CodeProject that showcases the full power of non-visual components and the extender provider model in v1.x.

First of all, instead of restoring the "Components Tray", they force you to right-click on the .aspx file and select View Component Designer:

That wouldn't be terribly bad, except for the consequences:

  • Extender Providers no longer work: the component is no longer officially part of the web form, but something that lives "behind" and that you have to see through a different designer. This means that the forms designer has no knowledge whatesoever about extender providers as it used to have. The following extension of built-in controls is no longer possible:


  • Designers/editors no longer work: if a designer relied on showing information from the current page, that won't work either. That's basically because the new designer surface you get is not the one for the form at all, but a new one created for non-visual components. That means that all controls on the form, which used to live in the same container (IContainer, specifically) as your own components, no longer do. Effectively, you have no way of retrieving the controls that exist on the design surface of the forms editor. This is even if the IDesignerHost service (that you can still ask for) Container property contains a Page object, and that's because it's empty of controls :S:S. The following kind of editor is no longer possible:


  • Components don't show up in the Toolbox: there's no way to make components appear in the toolbox. Even if they do show up in the Customize Toolbox dialog, and you can select them, they will never show up in the toolbox. As a consequence, there's no way to drop new components on a form. How are you supposed to use them therefore? The only way is through the components designer surface, with the problems mentioned above.

Therefore, one of the most important uses of a component, which was to extend and interact with the form's UI elements, in nicely decoupled way (you didn't need to inherit any of the built-in controls to add functionality to them), is no longer possible.

Interestingly, WinForms developers continue to enjoy this feature, and the code generation part was made more robust and clean with the introduction of partial classes. I see this as a sign of commiting with an existing feature and working to improve it where it was lacking, as opposed to starting from scratch again and leaving the customers guessing what the hell happened to their investment.

Maybe I'm just too pesimist. But this doesn't look like a fix at all for my bug, and it certainly cuts so many of the features of non-visual components that it renders them pretty much useless. Hence, it only makes sense for me to reactivate the bug and ask once more for your cooperation in voting for this feature to come back once more. Go and vote the bug if you feel this is an important feature being lost.

Note: this entry has moved.

Introduction

This post is a summary of a much longer article (~60 pages) that for space reasons does not fit well here in its entirety.

The full article can be viewed at CodeProject. http://clariusconsulting.net/articles/components/components.html.

The article discuses:

  • .NET and VS .NET vision of components: the building blocks and how they fit together.
  • The design-time architecture.
  • The MVC pattern: separating concerns and components responsibilities. Brief overview and our proposed architecture.
  • Aspect Oriented Programming (AOP) in the UI: extending existing components with new features. How to do it without inheritance or containment through VS .NET architecture.
  • Integration of components with the IDE: through the property browser. Converters, editors and designers.
  • Taking advantage of services provided by the host (IDE).
  • How to control code generation.
  • Design patterns to increase component reuse: making components cross-technology (web and windows-aware)
  • How to provide custom services through the VS .NET architecture.
  • Extending design-time infrastructure at run-time.

Article Overview

  • A component-oriented architecture: an overview of the ComponentModel, how it works in Visual Studio, its implications at design and run time.
  • Hosted components: .NET components and how they interact with the ComponentModel architecture, how they access services and publish new ones.
  • Design-time architecture: how the Visual Studio designers work, overview of designers, type converters and editors.
  • Root Components and Designers: how you can extend the architecture for your own components, to the point of completely replacing the root designer if you wanted to.
  • MVC: the Model-View-Controller design pattern. Brief overview of how we plan to apply this pattern to showcase the ComponentModel features.
  • AOP in the .NET era: how .NET implements a novel way of doing AOP with UI elements through the IExtenderProvider interface, and how to use it to implement the MVC model in a RAD way.
    • Custom Code Serialization: the CodeDom power. How to customize the code that gets injected in the InitializeComponent method.
    • CodeDom syntax: brief walkthrough of the CodeDom syntax.
    • Emitting CodeDom: how to emit the code from your component designers.
    • Back to simplicity: components built-in support for CodeDom generation is enough in some cases.
  • Completing the MVC Component Model: integrating the component-based model with the toolbox and drag & drop.
    • .NET Component Model: a closer look and inheritance problems. What happens when you drop components on the design surface.
  • Deep IDE Integration: improving integration of custom components with the IDE, and playing nice with the built-in services when changing values through the Property Browser.
    • Extending the Serviced Architecture: exposing new services through the IDesignerHost for consumption at design-time. Side-note on how CodeDom serialization of properties happens.
    • Custom Editors: creating complex UIs for setting component property values, how to integrate them with the Property Browser and be compatible with Visual Studio monitoring of component changes.
    • Custom and Global Commands: exposing commands or designer verbs on a component, but also how to publish commands that apply on the entire components tray area.
  • Dealing with different view technologies: implementing the adapter pattern to abstract Windows and Web UIs without losing *any* RAD features in the IDE.
    • Model Behavior, the MVC way: how the UI communicates with controllers to perform operations on the model.
    • Connecting the Views: how to connect controllers’ code with the views, so that updating and synchronization with the model happens automatically.
  • Beyond your own components: how to modify the CodeDom injected when serializing components you don’t own (i.e. controls), and add your own stuff on top of them, without needing inheritance or containment (AOP-style)
  • The final message: what did we learn from this journey on the ComponentModel and the IDE features, useful tips for developing IDe integration code, etc.

Article Summary

During the article I explore the most advanced features available in .NET and VS .NET for component-based development. I offer deep integration with the IDE, and even expand the model to the run-time.

I discuss the MVC design pattern, and create a concrete implementation that can make application development substantially faster. Not only that, but I create an implementation that can work with the same code base for both Windows and Web Forms.

Posted by Daniel Cazzulino | 2 comment(s)
Filed under: ,

Note: this entry has moved.

A while back, Peter blogged about pair programming with Virtual Server. The two of us have been pairing quite a bit lately, and it went really great. I'm starting to love it :D (not Peter, pair programming, of course...). CAB (Composite UI Application Block) is turning into a very very cool project. I'm definitely looking forward implementing all my future smart clients on top of it. There're SO many things that become way easier... But I'll be talking more about that in the future.

Now, back to pair-programming with Virtual Server, it works great except that  you cannot see your peer's mouse while he's moving it. This seems like a small issue, but the mouse shows you the intention of the other person as he goes across menus, the solution explorer, the scrollbar, everything. But today, edjez showed his amazing background on the dark depths of Windows GDI crap and came up with the idea of turning on the pointer trails and guess what: it works!!! Now we can both see each other's mouse pointer.

BTW, pairing with virtual server is *real* pair programming: you can switch the driver instantly, and the whole process is much more smooth. It's great. You really need to try it if you haven't done it yet.

Note: this entry has moved.

Finally, after various announcements and blog posts, the Guidance Automation Toolkit has a home at MSDN. Don't miss this opportunity to download the technology preview from MSDN, and play around with it.

Don't forget to send us your feedback!

Note: this entry has moved.

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).
Posted by Daniel Cazzulino | 4 comment(s)
Filed under: , ,

Note: this entry has moved.

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:
  1. 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.
  2. Our code may be used anywhere Microsoft feels they want to. This is way cool for us :)
  3. 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.
  4. 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.

Note: this entry has moved.

Finally, Wojtek got a blog, and after a short intro, he delves into the history that underlies PAG's latest addition: the Guidance Automation Extensions and Toolkit, already announced at the MSDN Architecture Center by Harry Pierson.
More Posts