July 2006 - Posts
One of WCF's goals is interoperability with standard protocol stacks, like WSE or other WS-* implementations. This led, I am told, to the design of WCF's default object serializer - the DataContractFormatSerializer. This handy little engine serializes primitive types, common objects, enums, Collections and anything that implements IXmlSerializable or ISerializable, giving us a much nicer out-of-the-box-and-over-the-wire experience for our objects.
Because of the aforementioned design goal, however, it has one little problem - the serialized data it generates does not contain information about the .NET CLR type from which this data was serialized. This makes sense when you have interoperability in mind - the datatypes you pass should be described in your service metadata, such as WSDL, and not rely on an implementation detail like the CLR type itself.
When we're writing closed systems, however, where we control both ends of the pipe and use WCF code, it can get limiting. Conside this scenario:
[ServiceContract]
interface MyService
{
[OperationContract]
void SendMessage (IMessage message);
}
This is a pretty realistic simplification of my current system, and we often have interfaces or abstract base classes defined in our service contracts.
What happens now? Let's I try to send a concrete IMessage implementations to this contract. When the service receives the messages and tries to deserialize the message parameter, it's stuck - there's no way to create an abstract IMessage from the serialized data, and the data carries no information on how to deserialize it.
If my contract defined this:
[OperationContract]
void SendMessage (MessageBase message);
I would be in the same jam - it would try to deserialize a DerivedMessage object into a MessageBase - at best, there would be loss of data. At worst (and as it happens) it simply fails to work.
The first solution that WCF's object model offered is to explicitly mark the service with the concrete types it can receive. This is a stop-gap measure that works, but takes the whole point out of using interfaces and inheritance trees:
[OperationContract]
[ServiceKnownType(typeof(DerivedMessage)]
void SendMessage (MessageBase message);
This would require me to add a ServiceKnownType attribute for every single concrete type, past, present and future. Obviously, not a good solution.
An alternate method involved a daring bit of magic:
[OperationContract]
[ServiceKnownType("MyKnownTypeMethod")]
void SendMessage (MessageBase message);
In this case, some backstage voodoo looks for a static method of that given name, calls it during the type's static constructor and asks it to return a list of Known Types. Not only is this totally unintuitive, it also simply doesn't work, at least for me. Maybe it's the beta, maybe it's me.
The third solution came to me from the future. I was shaking my fist at the heavens and asking why couldn't WCF simply serialize the typenames inside, like is done with Remoting. Interop isn't my concern, and it's silly to lose such a powerful feature. My answer came from Aaron Skonnard's blog, and from his August 2006 MSDN Magazine article, not quite yet published:
It seems the standard DataContractFormatSerializer has a shy little brother called the NetDataContractFormatSerializer. The 'Net' here, like in other parts of WCF, means ".NET". This is a formatter than can be used when both ends of the stream are running .NET, and it can thus embed the type information in the serialized blob. This makes all the fudging around with knowntypes completely unneccesary, and gives us the flexibility we had with earlier methods.
Using it, unfortunately, is a closely held secret. Skonnard's blog is the only mention of the name outside of the sketchy SDK documentation. It seems that we have to write our own OperationBehavior attribute (which Skonnard graciously supplies) and put it on our OperationContracts. The code can be found in his page, and usage is as follows:
[ServiceContract]
interface MyService
{
[OperationContract]
[NetDataContractFormat]
void SendMessage (IMessage message);
}
And that's it. The new attribute will add code that will replace the Formatter used during serialization, and from now on we're on easy street.
Notice that we have to set this attribute on every operation we need it. I was originally frustrated with not getting it to work because I instinctively put the attribute not on the SendMessage operation but rather on the IMessage definition - it stood to reason that we put it on the serializee, not the serializer. Once I got my head wrapped around that, it turned out you can't put it on the ServiceContract but have to do it for each operation seperately.
It seems a lot of work, but it really is much simpler than the alternatives above. Thank you, Aaron, for revealing this hidden gem!
I've been using WCF for the past few months and on the whole, I think the programming model works. I'm getting to really like the extensibility model and the whole deal seems to click rather well. One place where I feel it's a bit broken, though, is around the object model for Bindings.
The concept is simple - one of WCF's main selling point is having my communication channel be interchangeable, so I can replace a TCP/IP connection with HTTP or MSMQ almost seamlessly. This is translated into code by having each service have a Binding element which specifies the connection properties, and all these specific Binding objects - NetTcpBinding, NetMsmqBinding, etc - all derive from a shared Binding class.
It seems WCF sees seven layers to each binding, according to the SDK docs:
Layer | Options | Required |
Transport Flow | TransportFlowBindingElement | No |
Reliability | ReliableSessionBindingElement | No |
Security | Symmetric, Asymmetric, Transport-Level | No |
Shape Change | CompositeDuplexBindingElement | No |
Transport Upgrades | SSL stream, Windows stream, Peer Resolver | No |
Encoding | Text, Binary, MTOM, Custom | Yes |
Transport | TCP, Named Pipes, HTTP, HTTPS, flavors of MSMQ, Custom | Yes |
You would expect to have these as properties of the base Binding object - after all, if every binding has a required Encoding property, it makes sense, right?
Apparently this is not the case. The base Binding object contains only the most basic information - the naming information of the binding and the Timeout values, as well as shared functionality for opening and closing connections. Encoding? Security? All these are implemented individually in each binding class individually.
Not only that, but these settings are entirely incompatible - not only do I need to explicitly cast my Binding instance to a NetTcpBinding, the Security property of that object is of type NetTcpSecurity - a type that has nothing in common with, say, NetNamedPipeBinding's NetNamedPipeSecurity object. No inheritance, no shared interfaces, nothing.
Another example is the ReaderQuotas property, an XmlDictionaryReaderQuotas object that is defined seperately but identically in every Binding implementation. This means that I can't write code that sets the ReaderQuotas in a generic fashion, since there's no common interface or baseclass.
I find this very annoying. I'm trying to write a ConfigurationService component that supplies a client with the required binding information at runtime, but I find myself forced to hardcode several assumptions or else have very ugly try/catch code to explicitly see what type my Binding is and set the appropriate methods.
Seeing as we're in RC1, it's probably too late for this API to change. I wonder why it was developed this way. I hope the next version of WCF sees this revised.
Doing work on our WinForm application, we find ourselves having to make choices - too many choices - about the UI. We don't have access to professional UI engineers, unfortunately, and we make uneducated guesses on too many issues - should we use a treeview or a filtered list? Should we use opacity in our floating toolbox windows?
Lots of people have very strong opinions about these issues, but very few of us have anything to back them up except "In my experience...". What I'd love to have is some sort of good web-site that has white-papers, recommendations or analysis of different common UI widgets or patterns and how they translate to end-user usability.
Does anyone know of any such resource available on the 'net?
When we step back for a moment from our SOAs and Factories and Polymorphism, we have to admit that at the root of much of our code lie a hell of a lot of simple if/else statements. Like it or not, they're what makes our program logic tick.
All too often, though, our if logic is reversed - rather than checking for a true condition, we check for false:
if (!myDictionary.Contains(key))
{ }
This syntax, while very common, isn't really easy to parse. While I can express my required logic in words as "if my dictionary does not contain key", my syntax reads like the unintuitive "if not my dictionary does contains key" - I tend to think of my C# code in terms of natural languages. Usually English, even though it's not my native tongue.
So in order to bring C# more in line with my way of thought, I thought of having C# accept this sort of syntax:
if (myDictionary.!Contains(key))
{ }
The .! operator is valid only before a boolean member, and inverts the return value, making it equivalent to the code above. Now the code reads the way it should and is just as easy to understand.
How does this sound? Any other supporters for this? Should I file a feature request on Connect?
A client asked me the other day what happened to File->Properties in Word 2007. They simply couldn't find it.
In the Beta1 TR, I remember it was confusingly located on the Status Bar (!) – right-click, pick View and View Properties. Very annoying.
In Beta 2 it took me a minute to find it, and I have to say the new location isn't much better – it's under File/Office/Orb -> Finish:

This, I feel is hardly obvious. I don't necessarily want to input this data only when I'm finishing off the document. It contains other data, even if we ignore the statistics that can be seen elsewhere (again, on the status bar).
Clicking Properties in the Finish menu, however, doesn't actually open the familiar dialog at all, but a strange new beast – the horizontal pane:

This pane is, I feel, a mistake. There is some justification, perhaps, for the sudden appearance of a Mail Header pane when we send an email from Word. It sticks out a bit, but it brings the familiar Outlook UI, which makes sense when we're sending an email.
Here, however, it's just unexpected. There's no other use of this sort of UI in Word, so consistency is shot. It eats up a huge amount of screen real-estate that doesn't go away until you explicitly close it – wasn't the whole point of the ribbon to avoid all those messy toolbars that users bring up and don't know how to remove?
And all this for 7 text fields which also appear on the Summary tab of the Properties dialog, which can much more intuitively closed by pressing Ok on the dialog. I really feel this is a bad UI choice for Office 2007. I hope they change it in the final release.
Enough of the rant. Now for proposed solutions. I went over this with a friend, and our opinions differed. I suggested sticking with the old familiar dialog for adding/seeing metadata, while he proposed a new solution: Add the metadata as a Cover sheet or End sheet, built into the document itself.
That means we'll add another virtual page to the beginning/end of the document that isn't, by default, shown or printed. The user will add the metadata fields (Creator, Title, etc) the same way he writes the document itself.
I feel this isn't a good idea. To my mind, the metadata is separate from the document text itself. Not only will most users not want to see it (which isn't really a problem if it's disabled by default) but I think that adding metadata is a separate thinking process. Putting it under the Finish submenu shows that Microsoft seem to feel the way I do.
Enough of the rant. Now for proposed solutions. I went over this with a friend, and our opinions differed. I suggested sticking with the old familiar dialog for adding/seeing metadata, while he proposed a new solution: Add the metadata as a Cover sheet or End sheet, built into the document itself.
That means we'll add another virtual page to the beginning/end of the document that isn't, by default, shown or printed. The user will add the metadata fields (Creator, Title, etc) the same way he writes the document itself.
I feel this isn't a good idea. To my mind, the metadata is separate from the document text itself. Not only will most users not want to see it (which isn't really a problem if it's disabled by default) but I think that adding metadata is a separate thinking process. Putting it under the Finish submenu shows that Microsoft seem to feel the way I do. Any opinions or ideas?
The following code is perfectly valid C#, and compiles without errors:
int
_;
_ = 5;
If we take it a bit further, we can do something like this:
int _, __, ___, ____;
_ = 5; __ = 10; ___ = 15; ____ = 20;
_ = __ - _ * ____ / ___;
Now I feel like I'm playing Hangman. I feel I should be filling in the blanks.
I've never run into anything like this in real code, I'm glad to say. But if Dotfuscator or any other obfuscating tool want to make their obfuscated code even harder to read, they should stop using the easy-to-remember "a", "b" .. "aa", "ab" variable names and switch to underscores. It's horrible.
How many times have you connected to a server via Remote Desktop to install some components?
How many have you rebooted a remote server and sat around waiting for it to go up?
How many times have you opened a command prompt and ran ping -t until the server started responding?
Well, your days of manual pinging have come to an end!
The PingNotifier comes to the rescue!
With one small click, you will be able to start pinging a server, and receive a systray notification when the ping is successful, or if an error occurs:

I've attached the full source to this blog post.
(Disclaimer: Code is neither secret nor safe. Does not check validity. Does not care about network load. Does not floss regularly. Does not do tracerouting, change TTLs to try alternate packets sizes. Does not care about the environment. Do not trust the code. Do not trust the code.)
More Posts