Archive

Archive for the ‘Software Development’ Category

Windows Communication Framework (WCF): Beware the fake IDisposable implementation !!

Yeesh. My fascination with WCF became red-faced shame overnight.

We’re using WCF client/server both on a server, so an ASP.NET web app can query a custom indexing service. Since this was a fresh project with no legacy constraints, I opted to use WCF rather than remoting to…, well, to drink the kool-aid I suppose, but I thought the argument made at the AZGroups presentation that “you shouldn’t have to worry about the plumbing” was compelling. (Now that the solution is almost fully baked, I am really annoyed I went down this path simply because of the hassle I went through in having to manually populate the original strong types in a shared codebase between client and server. IMO, DataContract-driven proxy code is only useful for third parties.)

An initial WCF implementation with a simple loop of create, invoke, and drop scope a WCF client that used named pipes to a WCF service was freezing up after 12 iterations. Executing manually, roughly one iteration per second, it froze up on the 50th or so iteration.

Turned out I wasn’t calling Close() and should have been. *blush* Of course. But I looked for Dispose() to see if I could use the using() statement, and it wasn’t there. Or, wasn’t explicit, one must cast to IDisposable first before calling its Dispose() method.

Fixing that, now I was getting exceptions on Close() / Dispose() if the server had returned a Fault message. Buried deep in the far back of the WCF book I’m reading–and actually I had to use Reflector to figure this out before I looked in the book to see if I was right–is a brief mention not to use the using() statement with WCF clients, and don’t call Dispose(), either, but to call Close() manually. Dispose() on WCF clients actually call Close() internally. But just don’t expect the CLR / compiler to pick that up, and you shouldn’t always call Close(), either, but rather Abort(). Confused yet?

As I posted in Microsoft.public.windows.developer.winfx.indigo,

IDisposable was always percieved to be the happy, safe haven for getting rid of objects that use unmanaged resources. If something implemented IDisposable, Dispose() was always callable. Not so anymore.

((IDisposable)client).Dispose() can only be called on a WCF client if Close() can be called, because internally it calls Close(). Close() cannot be called unless basically it’s in the Open state; otherwise, you have to execute Abort() instead, which is not a memeber of IDisposable. This means that, even though the object does indeed implement IDisposable, its *SUPPORT* for IDisposable is 100% dependent upon the caller evaluating the State of the object to determine whether or not it’s open. In other words, Microsoft has established a new precedent: IDisposable mandates extraneous state-checking code before its IDisposable implementation is usable, and the only thing you can do about it is wrap it.

I might’ve opted to create a new interface, IReallyDispose, but then I’d still have to implement it. I could create an abstract class, WcfDisposable, but C# doesn’t support multiple inheritance. The best I can do is put a sticky note on my computer monitor that reads: "WCF client objects don’t REALLY implement IDisposable unless they’re Open!" Then I can only hope that I’ll pay attention to my stickynote when I’m going about WCF coding.

Does anyone else besides me find this to be unacceptably stupid and messy? I really *WANT* to like WCF. I love greenfield projects that use promising new technology, but when new technology abandons key design patterns like this, it really gets under my skin.

Discussing the matter further, ..

This isn’t about the object not being able to Close(). I don’t mind Close() raising exceptions. The core problem is that IDisposable throws an exception just because the object is in a "Faulted" state, while the object retains unmanaged resources!! IDisposable is generic and agnostic to connections/sockets/pipes/channels/streams, so I disagree when most people say "Dispose() and Close() are one and the same", because they’re not. What Dispose() is supposed to do is safely unload unmanaged resources, whether that means to Close() or not. WCF shouldn’t implement IDisposable if IDisposable.Dispose() will ever throw exceptions. I don’t care if Dispose() calls Close(), it should wrap that call with …

void IDisposable.Dispose()
{
	if (this.State == CommunicationState.Closing ||
		this.State == CommunicationState.Closed ||
		this.State == CommunicationState.Faulted)
	{
		this.Abort();
	}
	else
	{
		this.Close();
	}
}

Instead, Reflector says it’s implemented as such:

void IDisposable.Dispose()
{
	this.Close();
}

Since IDisposable has compile-time support for managing resources with Dispose, including the using() statement, this implementation is garbage.

There should be a working IDisposable.Dispose() that clears out unmanaged resources if you are *NOT* working in a transaction and have nothing to "abort" except the open connection itself. IMO, outside of a transaction, disposal of any object is an "abortion".

The bug in the design isn’t just faulty Dispose(), but that IDisposable was implemented in the first place. The practice we are told to use is to ignore it, and to call Close() or Abort() ourselves. Therefore, it’s not disposable, it’s only Closable/Abortable, depending on state. Why, then, did they implement IDisposable?

Where does Microsoft stand on this? Well, according to this forum post [link], they couldn’t figure out what to do themselves, so they released it with it with no real solution. Literally, "for good or for ill we have landed where we have", which was to try{} to Close, catch{} to Abort. Oh, nice planning. My respect for Microsoft just went down about 50 points.

Advertisements
Categories: Software Development

XML-to-C# Code Generation

Altova probably hates me. Not their products, but the company. I’ve frequently wanted to give their product line a noble shot for utilization, but I never have time to give it a fair shot, so I am never able to afford to purchase it or give it a full recommendation to my employer. My old user ID shows up in their tutorial videos alongside generic examples of hackers and spammers. For years, I’d try reinstalling the product to get past the 30-day trial in hopes that I’d have time to really check their cool tools out. When they killed that ability, I tried doing it within a virtual machine. Now in VMs I cannot get a trial key anymore; perhaps my e-mail domain name is blocked.

But I often forget that there is no real need for an investment in some third party XML code generation tool like Altova’s XMLSpy or MapForce if you need a complete object model written in C# to introspect a deserialized XML file. After spending hours Googling for C# code generators from XML, I realized that the solution is right under my nose. And I don’t have to spend a dime for it.

Why Generate?

You might be asking, why are you trying to generate C# code? Doesn’t System.Xml.XmlDocument and its XPath support work well enough to do what you need to do with an XML document? The answer is, yes, sometimes. Sometimes Notepad.exe is sufficient to edit an .aspx file, too, but that doesn’t mean that having a good ASP.NET IDE w/ code generation, like Visual Studio, should be ignored for Notepad.

In fact, I was happy with using XmlDocument until I realized that some of the code I was tasked to maintain consisted of hundreds of lines of code that would read CDATA values into a business object’s own properties, like this:

XmlNode node = storyNode.SelectSingleNode("./title");
if (node != null && node.ChildNodes.Count > 0 && node.ChildNodes[0].value != null)
{
	this._title = node.ChildNodes[0].Value
}

node = storyNode.SelectSingleNode("./category");
if (node != null && node.ChildNodes.Count > 0 && node.ChildNodes[0].value != null)
{
	this._category = node.ChildNodes[0].Value
}

...

This just seemed silly to me. When I started working with a whole new XML schema that was even more complex, I decided that manually writing all that code is just ludicrous.

XML -> XSD

Visual Studio 2005 (of which there are freely downloadable Express versions, of course) has the ability to introspect an XML document to generate an XML Schema (.xsd). It’s really very simple: load the XML file into the IDE, then select "Create Schema" from the "XML" menu. Overwhelmed by the complexity of it all yet?

Bear in mind that the resulting Schema is not perfect. It must be validated–by you. If at first glance the schema looks fine, there’s a simple test to validate it: simply programmatically load your XML document while enforcing the schema. For my purposes, I found that most of the adjustments I needed to make were just to make "required" elements "optional", unless of course they were indeed required.

XSD -> C# Code

If the schema’s clean, all you need is the .NET Framwork SDK, which comes bundled with Visual Studio 2005. Tucked away therein is XSD.exe, which does the magic for you. All you have to do is pass it "/c" along with the name of the .xsd file and the new name of the .cs file you want it to auto-generate.

The generated C# code isn’t always perfect, either. To say nothing of the rough comment stubs, one or two textual content elements were completely ignored in my case–the attributes were exposed as C# properties but the content, which was CDATA, was not. Easy enough to fix. This was likely due to an imperfect XSD file, but since this was really a run-once-and-forget-about-it effort, I was not afraid of diving into the C# to add the missing properties.

        private string _value;
        [System.Xml.Serialization.XmlText()]
        public string value
        {
            get { return _value; }
            set { _value = value; }
        }

System.Xml.Serialization.XmlSerializer works flawlessly with the generated C# code. I created the following generic class for the generated classes to inherit, so that they automatically offer a Deserialize() method:

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace MyProject.XmlGen
{
    public class XmlDeserializer<T>
    {
        public static T Deserialize(string xmlFilePath)
        {
            using (FileStream stream = new FileStream(xmlFilePath, FileMode.Open))
            {
                return Deserialize(stream);
            }
        }
        public static T Deserialize(Stream xmlFileStream)
        {
            return (T)Serializer(typeof(T)).Deserialize(xmlFileStream);
        }

        public static T Deserialize(TextReader textReader)
        {
            return (T)Serializer(typeof(T)).Deserialize(textReader);
        }

        public static T Deserialize(XmlReader xmlReader)
        {
            return (T)Serializer(typeof(T)).Deserialize(xmlReader);
        }

        public static T Deserialize(XmlReader xmlReader, string encodingStyle)
        {
            return (T)Serializer(typeof(T)).Deserialize(xmlReader, encodingStyle);
        }

        public static T Deserialize(XmlReader xmlReader, XmlDeserializationEvents events)
        {
            return (T)Serializer(typeof(T)).Deserialize(xmlReader, events);
        }

        public static T Deserialize(XmlReader xmlReader, string encodingStyle, XmlDeserializationEvents events)
        {
            return (T)Serializer(typeof(T)).Deserialize(xmlReader, encodingStyle, events);
        }

        private static XmlSerializer _Serializer = null;
        private static XmlSerializer Serializer(Type t)
        {
            if (_Serializer == null) _Serializer = new XmlSerializer(t);
            return _Serializer;
        }

    }
}

So with this I just declare my generated C# as such:

public class MyGeneratedClass : XmlDeserializer<MyGeneratedClass>
{
 ...
}

Literally, now it takes a whopping ONE line of code to deserialize an XML file and access it as a complex object model.

MyGeneratedClass myObject = MyGeneratedClass.Deserialize(xmlFilePath);

Cheers.

Categories: Software Development

WPF/E CTP is here!!

It’s Christmas season and I’m feeling nostalgic, reminiscing of childhood days when I opened up Christmas presents and felt like life was just beginning.

Yesterday it seems Microsoft shared with us the first WPF/E preview. (That’s WPF = Windows Presentation Foundation, “/E” = / Everywhere.)

Get to know this acronym, because this is Microsoft’s real-world answer to Adobe/Macromedia Flash. They’re making XAML renderable on web pages as controls, and exposed to Jscript (so you can do true AJAX and call into its DOM, for instance) and supported on IE, Firefox, Safari, for Windows, for the Mac  …

This is like Windows Vista for the Web on every platform.

http://www.microsoft.com/downloads/details.aspx?FamilyId=A3E29817-F841-46FC-A1D2-CEDC1ED5C948&displaylang=en

http://msdn2.microsoft.com/en-us/asp.net/bb187358.aspx

http://www.microsoft.com/design/Voices/Detail.aspx?key=better_web_wpfe&voice=wpfe

Here’s a sample page using WPF/E (must be installed):

http://www.jondavis.net/WPFESamplePack/Sprawl/default.html

.. a-heh-hand ..

http://www.jondavis.net/WPFESamplePack/videolibrary/default.html

Oh yes, and Microsoft is giving us stocking gifts, too. The “Interactive Designer” tool (the Flash IDE equivalent) is now “Expression Blend” and is now Beta 1. The SDK also integrates with Visual Studio

http://www.microsoft.com/products/expression/en/Expression-Blend/default.mspx

http://www.microsoft.com/products/expression/en/default.mspx

http://www.microsoft.com/downloads/details.aspx?FamilyId=2B01EC7E-C3B8-47CC-B12A-67C30191C3AA&displaylang=en

Jon

Categories: Software Development

Visual Studio 2005 on Vista: Broken ASP.NET debugging

When I upgraded to Windows Vista RTM I was reminded of the fact I already knew that Visual Studio 2005 has compatibility issues that so far have not been documented. After a week of tweaking a bunch of other things, I finally got around to firing up Visual Studio 2005 to see what is so incompatible.

The first concern I had was whether it would fail to fire up. No problems there. Then I created a Windows Forms app and tested CLR debugging. No problems there.

Next, I loaded the solution I’d been working on at work. This is a mix of class library projects and ASP.NET webs. Although I manually set up the main ASP.NET web project of interest on IIS 7 using the classic .NET 2.0 application pool, Visual Studio could not "mount" itself to IIS. Makes sense–IIS 7 breaks compatibility with IIS 6 components. There are backwards compatibility components you can install but AFAIK (but have not yet confirmed) these components are limited to workstation components for accessing other IIS 6 based servers.

All is not lost, you can still "mount" to the local file system directory and use the ASP.NET mini web server built into Visual Studio to debug. In theory.

However, given that our project files are shared on subversion (svn) with other team members who have no intention to use Windows Vista, I will not be able to get comfortable doing ASP.NET contributions on my laptop with the team.

———

Update: Nevermind. I’m debugging ASP.NET projects now. I’m not sure what I did between before and now, but I do know that among the requirements are 1) install IIS 6 compatibility components (which I already had), 2) enable Windows authentication on IIS, and 3) run Visual Studio as an Administrator.

Categories: Software Development

Just Arrived: Applications = Code + Markup (Charles Petzold)

September 3, 2006 2 comments

Charles Petzold’s new book on Avalon (Windows Presentation Foundation) just arrived at my doorstep earlier today. I get to be one of the lucky ones who pre-ordered this big thing and be one of the first proud owners of the book.

Without having done a thorough reading and only cracking it open, here are my quick observations:

  • It’s a big, hardcover book. Not as big as Programming Windows, though, which is still on my shelf.
  • Looks pretty chock full of content, I don’t think anything is going to be missed for general introduction to all major facets of WPF.
  • A pretentious title. Microsoft is being "cute" but it hits a nerve in a bad way. To define the word "application" as "code + markup" is stupid, no matter how prevalent Windows Presentation Foundation intends to be in Windows Vista. The word "application" is a long-standing software term that Microsoft cannot just go and redefine–no, not even Petzold.
  • Much more approachable from what I can tell than O’Reilly’s book, which frankly is a very bumpy ride.
  • About 60-70% or so of the book consists of code samples, and about 75% of the code samples are written in XAML while the other 25% are in C#.
  • I can see this book as being the new "Bible" of Windows user interfaces.
  • Covers content, docking, events, elements, menus, treeviews, listviews, data binding, graphics, animation, and more.
  • One of my biggest concerns about WPF is that from what I’ve seen so far of WPF it is very much like DHTML for its menus in that a menu cannot be displayed beyond the borders of its window, and I will miss that greatly. I am curious about Ch. 14 (Menus) to see if my observation was incorrect. (Update: My observation has proven to be incorrect.)
  • Looks like "Orcas" is required to run the samples. Darn. "Orcas" won’t be released for .NET 3.0 RC1 for a few more days, so I had to roll back to the June CTP of .NET 3.0 to install the "Orcas" preview, then uninstall .NET 3.0 and install .NET 3.0 RC1.
    Update: Thanks to Rob Relyea’s blog (his comments therein), an easier way to install the June "Orcas" preview is: msiexec /i vsextwfx.msi WRC_INSTALLED_OVERRIDE=1
  • 3D stuff does not appear to be covered at all.
Categories: Software Development

Simple and Standardized ASP.NET Localization

Here’s an article to read. I was asked about this in a job interview and I gave a crappy answer. Then I stumbled across this article the next day.

http://msdn.microsoft.com/msdnmag/issues/06/08/BasicInstincts/default.aspx

I’m sure the basic principles can apply to Windows apps as well.

Categories: Software Development

[AZGroups-Announce] Scott Guthrie Eric Sink Sept 6th

From the AZGroups-Announce mailing list:

Most of you have heard through the grapevine that Scott Guthrie is
coming back to PHX, along with Eric Sink on Sept. 6th.

I decided to through it out to the Announce list, since it hasn’t
made it here, and some of you don’t monitor the other lists.

RSVP is required, and we only have 800 seats available. This event
is being held at the Orpheum theatre downtown.

RSVP and all meeting details can be seen here.

http://azgroups.com/forums/post/489.aspx

You should know there is a difference between AZGroups and
YahooGroups. In order to RSVP you need to create an AZGroups
account, which can easily be done here.

http://azgroups.com/user/CreateUser.aspx

Thanks for all your support. Please help us let the world know about
this event by forwarding email to your co-workers, and possible
including/printing our marketing PDF flyer for your common work
areas.

http://azgroups.com/downloads/guthrie_sink_printable.pdf

Thanks,
Scot Cate

Categories: Software Development