This Friday (May 20th) come to the Microsoft Alpharetta office for the .NET Experience Expo! This is a free event where you can come hear all about some of the hottest topics for developers and architects. This is a huge opportunity to learn more about what Microsoft is doing for developers (and it’s a great chance to win an Xbox!) All attendees will receive a free copy of beta 2 (yep, Team Suite... the full deal), a copy of "Introducing ASP.NET 2.0", and a swank .NET shirt. We will have a reception at the end of the day (who can beat free beer?) There will be partners attending as well in the partner pavillion (AmberPoint, Avanade, AVIcode, RDA, Internosis).
But wait... there's more! We will have a Hands On Lab room where you can play with the bits (BizTalk, SharePoint, VS 2005, and more), Ask the Experts sessions, an Ask the MVPs session with some of the Atlanta MVPs, and lots of time to interact with the Developer Evangelist team!
Make sure to sign up using the registration link:
Come for the Experience… stay for the beer.
DATE: Friday, May 20th, 2005
LOCATION: Microsoft Atlanta Office
1125 Sanctuary Parkway
Alpharetta, GA 30004
|Time||Line of Business Development||patterns & practices||Back Office Development|
|7:00 - 8:00||Registration, Partner Pavillion, and Hands On Labs|
|8:30 - 9:15||Opening Keynote - Visual Studio 2005 and Visual Studio Team System|
|9:30 - 10:30||.NET Fx 2.0 - New Features for Windows Forms||Service Orientation in Practice||.NET Fx 2.0 - New Features for the CLR|
|10:45 - 11:45||Mobile Clients & Compact Framework||Enterprise Library||.NET for Operations|
|11:45 - 1:00||Lunch, Partner Pavillion, Hands On Labs, and Ask the Experts|
|1:00 - 2:00||Microsoft Office - A New Breed of Smart Clients||Workflow and Business Process using BizTalk Server 2004||SharePoint for the Developer|
|2:15 - 3:15||Deploying Smart Clients using ClickOnce||Writing Secure Code||Identity Management Using Active Directory, ADAM, and MIIS|
|3:30 - 4:30||Web Applications - Innovations in ASP.NET 2.0||Distributed Architecture on the .NET Platform||SQL Server 2005 & SQL Reporting Services - What's in it for the Developers?|
|4:45 - 5:30||Closing Keynote|
To register,sign up with the following link:
Some great stuff going on with XML lately.
- Jan Tielens shows how to use InfoPath to access a secondary datasource, such as a SharePoint list
- Matt Warren then delves into some XML bestiary and shows a binary XML parser based on XmlReader.
- Cazz (the one and only avid bathreader) shows how to iterate over XPathNodeIterator nodes, provided that you know the underlying type that is being iterated over.
- WSE 2.0 is code complete. I am really late to the game posting this, but it is great news.
I really hope I get some time to finish and post up the 2 code tidbits I have been working on to further the XML bestiary.
Someone asked me about using a typed DataSet on both ends of the wire using a web service. I honestly don't work with typed DataSets, but this question was to accomodate the client's existing architecture. We both tried it, and couldn't get it to work. This shouldn't be that hard,so I asked quite a few people... nada. Most admitted they just frankly don't use typed DataSets.So, I settledin behind the keyboard to fight through it. The answer turned out to be simple, but non obvious.
Suppose you have a typed DataSet and you want to use that with a Web Service. If you plan on exposing that web service to any clients not running .NET (such as VB6 using the Soap Toolkit), then you should not return a typed DataSet from a web service method. For more background on the interoperability problems, read Aaron Skonnard's "Web Services and DataSets" article to see the effect on the WSDL when returning a DataSet. Aaron's article shows that one workaround is to use an XmlDataDocument and return that to the client as an XmlNode type. I quote that article often, but hadn't actually tried to implement the solution.
I created a C# Class Library project file and left the name as ClassLibrary1. I added an XML Schema to the project, and dragged some tables from Northwind to the design surface. Then I tweaked the schema for a little while (I am a control freak about the XML Schema layout, no big deal). The reason for the library is so that I can create a typed DataSet that is used by both the WinForms client and the web service.
In the same .sln, I added a C# Web Service project and named it WebService1 (clever, huh?). I set a project reference to ClassLibrary1 above so that I could use the typed DataSet. Here is the HelloWorld code, uncommented and modified:
public XmlNode HelloWorld()
System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection("Data Source=L00261;User ID=sa;Password=asdfasdf;Initial Catalog=Northwind;");
System.Data.SqlClient.SqlDataAdapter adap = new System.Data.SqlClient.SqlDataAdapter("SELECT * FROM CUSTOMERS",cn);
ClassLibrary1.Document s = new ClassLibrary1.Document();
System.Xml.XmlDataDocument doc = new XmlDataDocument(s);
Using this web service method, the contents of the SOAP body will be the same as if you used:
Once you have the web service running and you can invoke it from the ?wsdl test page (for example, my new service was http://localhost/webservice1/service1.asmx?wsdl), you can create the client.
Create a WinForms client and set a project reference to ClassLibrary1. Then create a Web Reference to your service, using the WSDL endpoint specified above. Drop a DataGrid and a Button onto Form1. Double-click the button and add the following code:
localhost.Service1 s = new localhost.Service1();
System.Xml.XmlNode n = s.HelloWorld();
ClassLibrary1.Document x = new ClassLibrary1.Document();
x.ReadXml( new System.Xml.XmlNodeReader(n),XmlReadMode.IgnoreSchema );
this.dataGrid1.DataSource = x;
The trick to using the typed DataSet on both ends of the wire is that you have to specify XmlReadMode.IgnoreSchema, or you will not see any data show up in your DataGrid control.
Douglas Reilly has a great post on what seems to be a recurring theme throughout my career. He talks about being tasked to write a system with features that he knows are fragile, implement it in such a way that maintenance and support costs are exponentially increased, and defend his position when he proposes what seems like a no-brainer fix to a problem that shouldn't even exist. In summary:
“They are millionaires, I am not.“
This statement wraps up what seems to be a pervasive topic in the business applications industry in general. A company's owners make the decision to implement a system to help reduce costs, increase revenue, and hopefully both at the same time. This vision is passed to the management for implementation, who then forms a team of developers to implement. Contractors and consultants are brought on with specific skills to round out the existing teams' skills, and there is no looking back from that point forward. Do not question the goals of the project, you have deadlines. Do not question a particular feature set, one of the owners says it is essential. Before architecting the system, nobody thought to check to see if there was already a product that performs this task for them and if it fits their needs.
I have worked at several clients where I recognize within several minutes of talking with them about planned features for a system they are developing that their dream system is already implemented in BizTalk. And I am not talking about stretching BizTalk to do some bizarre tasks that don't fit its purpose, I am talking about basic connected systems design.
For example, one application needs to interface with a data entry clerk, perform basic validation, then queue the message through several different legacy systems depending on the message's contents. This is a classic example of the EAI scenario that BizTalk solves through Orchestration. Rather than look at BizTalk (it costs too much), they instead invested 18 man-years to develop a system that was fragile, impossibly complex to configure, and built around a concept of reusability that made the system anything but reusable. The developers' joke about the system was that it was a brick house built with absolutely no mortar. Sure, you can add a new wing onto your house pretty quickly, but doing so means you have to tear down the entire top portion of your home. I heard that portions of that system are being re-evaluated for a face-lift using .NET and BizTalk
Another application needed only to process inbound purchase order messages from any one of 25 diffferent customers, each with a different input format and transport protocol, and convert the messages to a common purchase order format. This is a glowing example of the B2B scenario for BizTalk where you configure different receive ports and channels, configure several orchestrations, and you are able to reuse the process again and again for newly added customers with little configuration. Again, the argument against BizTalk was cost. This time, I presented the case in a very strong manner, demonstrating through lots of neat charts how the projected costs for the custom solution (12 man years at an average of $50K per developer, or around $600,000) compared to that of a BizTalk solution (roughly $350,000). This system was being written with VB6 around the time that .NET was first introduced in Beta, so I pointed out architectural limitations of their current architecture and how it would make moving to a new platform difficult. They went with the custom solution. Just a few short years later, they are now rewriting the same system with .NET and BizTalk.
This is not gloating, this is remorse. Both customers are facing significant system rewrites with a tangible financial impact because they would not listen to the merits of using a product that was “not invented here.” Of course, they would likely be looking at additional costs for upgrading to BizTalk 2004 in the near future since it absolutely rocks, but those costs should be dwarfed by the cost of rewriting a system from scratch to help solve some of the mysterious COM+ errors that suddenly appear in the Event Log without rhyme or reason.
How far should a consultant push a concept when they know they are right? Do you risk alienating the project manager because a contractor proposed a system that would reduce his project time from 9 months to 2? Do you risk alienating the architect(s) on the project because their system is notoriously fragile yet designed to some elusive requirements specification that nobody seems to remember exactly where the latest copy is?
Douglas quotes a cynical, yet realistic view from The Career Programmer:
I'm hired to write software, not to manage companies. Furthermore, if they want to pay me twice to write the same system, my bank makes little distinction when it comes to the deposits.
I see that simply keeping quiet and cashing checks is a definite option. This keeps you employed as a consultant, and often the consultants who rock the boat the least are the ones with the greatest longevity on a project. But why is there such little credit given to the career programmers who live and breathe technology enough to recommend solutions that will save hundreds of thousands of dollars?
In questioning the credence given to the developers, I am reminded of a recent post by Jim Fawcette about Wal-Marting of Software:
I argued that outsourcing software posed other risks, because it essentially exports and helps nurture competition in the one area that is a key, strategic advantage for the
U.S.and, to a lesser degree, Europe. Software IP is the key differentiator for our economies, a technology whose impact is pervasive. From the human genome project to Pixar's movies, software is the core technology that makes it work.
This drew baffled looks. "Programming is a commodity, grunt work," said the board member. "Software isn't different from the textile industry," the CEO said.
I think Jim's post hits the nail on the head. Software exists to increase revenue or decrease expenses. The people implementing that software should be paid the least amount possible accorrding to the laws of supply and demand, and often business software is viewed as a necessary evil or expense center rather than as a profit center. What many of the MBA types seem to forget from Management 101 in college is that investments depreciate in utility over time, and this effect is magnified for technological investments. Further, the associated maintenance costs of technological investments often increase over time. Make or buy decisions are often discussed right after Maslow's Hierarchy of Needs and Herzberg's Motivational Theory, so why is make or buy such an overlooked concept in the software industry? Why is “not invented here syndrome“ so pervasive throughout the corporate world's IT centers?
This week's misinformed prroject management quote is actually one from several years ago:
“You say 12 man years like it will really take that long. Remember, we have a deadline here.”
I am actually not a fan of individuals posting aggregated feeds, but I found a set of posts tonight that all hit around my areas of interest. This will not be a common occurrence for me, as I am posting these mainly as a selfish set of pointers.
- For those that have been putting off looking at Indigo for awhile, there is a sample chapter of an upcoming book, “Inside Indigo“ on MSDN.
- Klaus posts on including a service layer in the more traditional layer stack (Presentation, Service, Business, Data). This was an interview question for a position as an architect, and we debated the merits of this approach versus the implicit tradeoffs.
- Owen Allen states that the RTM of BizTalk 2004 will be available to MSDN subscribers on March 2nd.
- Paul Wilson has been doing a lot of spelunking with the Garbage Collector in .NET. Rather than link to all of the posts, just look at Paul's February posts.
- Dare comments on Cazz' question of XSD as a type system. Is there an impedance mismatch when considering the serialization aspects of XmlSerializer alone, or should we further consider the schema as the type basis for a message contract? For the former, XSD and CLR typing are simplistic, but the latter seems to spark many of the issues that Dare lists.
- Dr. Rys is posting on moving FOR XML Explicit to the new PATH mode. Bryant Likes, the SQLXML guru, follows up here and here.
- I know this has been posted a lot, but for posterity I wanted to keep a pointer: Benjamin M has a diagram of the progression of connected systems
- On xml-dev, Michael Kay and Kurt Cagle take opposite approaches on the relative approachability of XSLT and XQuery. Oleg questions Kay's statement.
- Clemens tries to clarify the terms “Component” and “Service” for the general developer's lexicon. Good luck, since SOA right now seems commonly defined as “Web Services.“
Zapthink wrote up an article on when SOA is not a good idea. This is their list of when SOA is not a good idea:
- ...when you have a homogeneous IT environment
- ...when true real-time performance is critical
- ...when things don't change
- ...when tight coupling is a pro, not a con
Of course the real message here is that
- Okay...the one company that has a homogeneous IT environment, you don't need SOA.
- Okay...some specific robotic control systems don't need SOA
- Okay...hmmm...I guess those folks who are still using Multiplan and Wordstar don't need SOA
- Okay...when you specifically don't want any of your systems to integrate with any other systems then you don't need SOA.
So all six of the people who the above rules apply to - they don't need SOA.
The rest of us should probably look pretty closely at SOA.
I accepted an offer from Microsoft: I will be swallowing the red pill on March 1st. My new position is Developer Evangelist for the telco vertical, and I will be based in Atlanta.
A new hire is meandering around the work area at a company I have consulted with. The HR manager walks in.
”Hi, welcome (name withheld to protect the innocent), we are so glad to have you. Here is where your cube is, if you have any questions let me know. We are so glad to have you join us! Let me walk you through the area.”
Stops in front of my cube...
“You can tell the associates from the temps based on the company name on the name badge.”
Inside 4 sentences and literally 30 seconds, the HR manager had degraded the consultants and contractors as “temps”. I found it ironic that the manager did not find it necessary to introduce any of the developers that the new associate would be working with... but she felt compelled to introduce an admin assistant who happened to be one of the only full-timers in sight.
OK, not “project management”, but Dilbert-esque all the same.
An interesting thread on the API Design Hall of Shame on Brad Abrams' blog.
I have a question, how was the decision for these 2 classes ctor parameters made...
Constructor for ArgumentNullException
public ArgumentNullException( string paramName, string message)
Constructor for ArgumentException
public ArgumentException( string message, string paramName)
Well, in short Jeff, this was a design mistake. In fact it is up on the internal “API Design Hall of Shame”. Here is the text from that site:
ArgumentNullException does not follow the constructor pattern given in the Design Guidelines spec.
Result: Habit wins out and people commonly type:
throw new ArgumentNullException (“must pass an employee name”);
throw new ArgumentNullException (“Name”, “must pass an employee name”);
so we end up with error message such as:
Unhandled Exception: System.ArgumentNullException: Value cannot be null. Parameter name: must pass employee name
Lesson: Just follow the pattern!
Got any other examples that should be in my API Design Hall of Shame?
Even more interesting are the comments to this post, where Dwayne points out:
There is no base data access exception for the data access libraries. For example, the System.Data.SqlClient.SqlException derives from System.SystemException. So does the System.Data.OracleClient.OracleException class. This makes it more difficult to create a common data access interface that uses these classes internally but throws an implementation agnostic exception. It would have been nice if they had a System.Data.DataException that these exceptions derived from, so that my interfaces could be consistent.
Great point. It would be convenient to have a System.Data.DataException, where each provider extends from that base type. Instead, you have two choices: explicitly filter for each provider that your layer supports, or catch System.SystemException... which is still not optimal. However, this is leaps and bounds better than VB's prior “On Error“ statement, where you were to explictly check for the error number in an active error label. Exceptions based on rich type information are a big win for the .NET framework.
I get the impression that the various teams could not always agree on the best place to branch off their exception hierarchy. For example, some exceptions from the framework are based off ApplicationException.
This is actually noted in Chapter 7 (IIRC) of Richter's book, that there is inconsistency in the framework itself on the appropriate use of ApplicationException and SystemException. He notes that SystemException intends to capture all of the exceptions relating to the framework, but this guideline was not consistently followed. The general guidelines should be:
If you have a procedure that checks arguments and throws exceptions if the arguments are null or out of range, by all means use the ArgumentOutOfRangeException and ArgumentNullException (noting the parameter order shift explained above). Using a custom exception provides no extra information.
If your method is created to open a file, then throw a System.IO exception. The user should expect an IO exception possibility when they are asking to work with a file.
If your method is supposed to provide information from the database and employs a caching scheme for a local file, exposing a System.IO exception makes little sense because the consumer has no concept that there is a file involved... they were asking for something from the database. In this case, throw a custom exception derived from ApplicationException, and in its constructor, provide the InnerException argument containing the System.IO.Exception. The informaiton is preserved and much more meaningful to the consumer of your method.
Some very interesting work has been going on with the classes in the System.Xml namespace. Daniel Cazzulino blogs about an XseReader implementation he has been working on for providing XML Streaming Events. I had been using a similar implementation for trying to write a .NET version of an RssValidatingReader awhile back, but gave up due to the complexity of managing an ambiguous stack for co-occurrence validation. Oleg commented on the implementation and notes the use of an XPathNavigator over an XmlReader to provide a ForwardOnlyXPathNavigator, a hypthetical implementation that Dare mentioned in his XML Journal article. Dare then comments on his blog about the new implementation he has been considering, XPathReader, which is similar to the implementation in BizTalk 2004.
I have been working with BizTalk 2004 for about 2 months now here and there, mostly spelunking to find out more about ways to extend it using WSE and looking at how it implements XML Schemas. I hadn't run across the types in BizTalk that Dare and Oleg mentioned in their posts, so I brought out Reflector... sure enough, there in the GAC:
The XPathReader, XPathExpression, and XPathCollection types seem to be the core classes for the implementation.
Steve Maine has a great article on using anonymous methods and higher-order procedures in C#.
A point not necessarily highlighted in the article's text but rather through the code examples is that not all problems are solved through inheritance.
Suppose you have a class that provides methods for working with a certain datastructure. You might prefer thhe consumer of the class not be required to inherit from your class to effectively use it, and it is not feasible to require the consumer to implement an interface to support your behavior. A great design pattern involves the use of function pointers, implemented as delegates in .NET.
Consider the example below: I have an XmlDOMNavigator type that is responsible for loading XML and providing a reference to its root element. Rather than define the various navigation methods that could possibly occur within the XmlDOMNavigator method, we let the consumer define the implementation of the Traverse method by providing a method that accepts an XmlNode type and returns an XmlNode type.
static void Main(string args)
XmlDOMNavigator nav = new XmlDOMNavigator();
MyNavigator myNav = new MyNavigator();
//Define the move method's type
//Set the type to a new instance
MoveChildMethod = new XmlDOMNavigator.NavigationMethod(myNav.MoveFirstChild);
XmlNode nodeRef = nav.DocumentElement;
while(null != nodeRef)
nodeRef = nav.Traverse(nodeRef,MoveChildMethod);
public class MyNavigator
public XmlNode MoveFirstChild(XmlNode context)
public class XmlDOMNavigator
private XmlDocument _doc = new XmlDocument();
public delegate XmlNode NavigationMethod(XmlNode n);
public void Load(string path)
public XmlNode DocumentElement
public XmlNode Traverse(XmlNode context, NavigationMethod customMethod)
Paul Wilson emailed me with some questions regarding perceived memory leaks related to System.Xml.Serialization.XmlSerializer. I questioned whether it would be a “memory leak”, but pinged Christoph Schittko for some backup evidence. He said he doubted it as well, else web services everywhere would be falling on their faces. I pointed him to Doug Purdy's post on inspecting theXmlSerializer's interim assembly, and Chris Sells' utility for precompiling XmlSerializer types.
Paul emailed back that, in fact, they pinpointed the leak, and it was related to the XmlSerializer. But it is not a memory leak... it is a dynamically created assembly “leak“, and is not by accident, but rather by design.
XmlSerializer manages the generation and execution of per-type reader/writer pairs. These pairs are dynamically generated types that extend the internal types XmlSerializationReader and XmlSerializationWriter, respectively. When instantiating an XmlSerializer, you must provide a System.Type object that represents the type the new serializer object will be used with. To avoid generating redundant assemblies, the XmlSerializer constructor looks in an AppDomain-wide cache of generated reader/writer assemblies and reuses the cached assembly if one is found. If one is not found, the XmlSerializer constructor generates a new dynamic assembly by reflecting against the presented System.Type object. This new assembly is added to the cache so subsequent XmlSerializer objects can reuse it, reducing overall code size and codegen overhead. Unfortunately, the cache only works for some constructors of XMLSerializer, since the lookup index gets more complex with more overrides. Users can cache the serializer themselves—it's freethreaded so you can serialize across threads.
Christoph followed up with (via IM):
I got used to the pattern of having a static serializer instance in my apps ... Just instantiate it once, assign it to a private or internal static property somewhere in the assembly. Then you don't even need to hit the cache ...
It's also interesting to note, that System.Messaging does not rely on the cache and keeps its own cache around.
For those that haven't read it, you really need to read Christoph's blog entry on troubleshooting the XmlSerializer.
I thought I would add a category for rants on Project Management practices.
Misinformed PM quote of the week:
“Our business model simply does not allow confirming requirements before construction. The software development team is helping to shape requirements by confirming newly introduced functionality.”