White Papers                  Home |  White Papers  |  Message Board |  Search |  Products |  Purchase | News |  
 
HTML Help Builder  

The two faces of .Net
(or how I learned to live with Jeckyll and Hyde)

 

by Rick Strahl

West Wind Technologies

http://www.west-wind.com/

rstrahl@west-wind.com

 

Updated: 01/10/2003

 

Developing applications with .Net sometimes feels like working with a dual personality. Now that .Net has been around long enough, I and many of you undoubtedly have had a chance to put .Net through its paces with some real applications rather than just little samples to dabble with. For me, the .Net learning curve has been a long one and I often feel like I'm dealing with Dr. Jeckyll and Mr. Hyde. I find working with .Net both exciting and frustrating at the same time. Talking to other developers I think I'm not alone.

The good

.Net has a new and fresh feel to it which gives it an air of a new start. Prior to .Net we had reached a point of technology and tools mish-mash with Windows development that has been very prohibitive to get into and become proficient at. Win32 API coding, COM, system level programming, COM+, XML and various sub technologies all using their own specialized syntax and architectures. If you have grown up with this technology over the years you might have actually had a decent handle on it, but if you were starting out from scratch trying to put all the pieces together to use all of this technology efficiently was very difficult. .Net provides much needed relieve in this area with a framework that wraps a very large part of the currently needed technology into a relatively consistent and easy(ier) to use framework of components. There's consistency in commonly used patterns that are wrapped into components that share the same layout. For example, the various security and identity objects required for authentication are the same regardless of whether you are building a Windows Forms, Web Form or Web Service application. Stream usage for everything from strings to files, XML data, to i/o ports and protocols is another one that you use on a daily basis. This reusability of skills learned once makes it easier to implement applications quicker even when the overall syntax for these objects may at first seem more complex and even awkward.

Regardless of whether your background is in C++ or whether you come from a high level language like Visual Basic 6 or Visual FoxPro, .Net is bound to have some features that you either couldn't implement previously at all, required extensive code or a number of third party controls. The ease with which you can implement advanced features like multi-threading, creation of Windows Services, event handling, accessing native Windows event processing and graphics programming is a big win for developers who come from 4th generation languages that in the past have often felt hampered by their runtime implementations. Lower level programmers coming from C++ on the other hand likely appreciate the ease with which many things can be implemented and the fact that only a fraction of the amount of code is required to accomplish the same thing. As a developer coming from a 4G language I love the feeling of being able to dig into lower level functionality and integrate it directly into my application without having to build another project in C++ to integrate into my app. With .Net many tasks that required splitting things out into other tools can now be handled with one tool which is very liberating.

Shedding the shackles of the complexities of COM is another big bonus in my book. While COM could be made to work well, it has always been such a hassle to install applications and keep them running especially in applications that contain many different COM components. I just finished a small .Net utility application and it was such a joy to have deployable application that contained various advanced Windows controls, multi-threading support and ship it as a single 130k EXE file. No support files, no installation – just a single EXE that can be copied into a directory and run. The app could even run directly off a URL on the Internet by simply placing it on a Web server and accessing the EXE through Internet Explorer. .Net's deployment models even for Fat Client applications offer huge potential to deliver the flexibility of Web applications without the shackles of HTML development.

Then there's Visual Studio .Net, which as a development environment is also impressive to work with. While there are some usability issues that Microsoft should work out to make tasks easier, overall the environment provides everything that you need at your fingertips in an understandable although complex environment. It takes getting used to, but once you do you can really appreciate all the helper tools and support that the environment provides. Beefed up Intellisense, code comment exports and outlining are some of my favorite features in VS.Net editor. Multiple project solutions that can be run as one single application and be debugged is another high on the list.

Certainly there's much more: ADO.Net's distributed data paradigm which is a huge step up from ADO, and of course ASP.Net's new Web Form metaphor which is changing the way we think about Web development. If you follow the trade papers you surely have heard all the accolades about .Net so I won't go on. Suffice it to say there's much to be liked about .Net even by a cynic like myself.

The Bad

Although I am very excited with .Net as a platform it's also infuriatingly frustrating to work with at times. A lot of things are difficult to do or implemented in nearly incomprehensible fashion when it seems there could have been easier and cleaner interfaces. And like any 1.0 release from Microsoft there are number of unexpected behaviors that can make life difficult. It seems like .Net is making the difficult things easy and the easy things more difficult.

My number one beef with .Net centers around databinding both in Windows forms and Web forms. As many things in .Net the databinding mechanisms try to do too much by trying to address 100% of scenarios at the cost of significant complexity rather than addressing the 95% scenario and making it easy. Yes, the databinding mechanism is very powerful with its ability to bind anything to anything and the ability to page through data if it uses enumerable interfaces. But it takes a lot of hand written code to accomplish this. So much in fact that it's almost easier to bind data to controls manually than using the databinding functionality. In Windows forms specifically, databinding code has to be manually written and can't be controlled via properties on the controls the data is bound to. For an example of complexity, try binding a textbox to a property of a business object rather than a field from a dataset and see how much code is required to display the data and keep it updated as you move through a list box. It isn't pretty. Granted you can do it – it's just very tedious and very error prone because much of the code you write deals with indirect referencing (ie. it's not type-safe) and you don't get Intellisense or the compiler to help you out. If you do use DataSets exclusively life becomes a little easier as you can use the Builders, but this process is still too time consuming and produces reams of unmanageable code. And of course it doesn't fit if you're using business objects that contain data properties.

Not only does it take a lot of code to perform these tasks, but the mechanism is also so convoluted involving a number of different objects that just understanding how databinding works is a major task. Forget trying to figure it out from the .Net docs. There are several third party articles and books that explain this topic well, but even with a good description the topic is confusing at best. No doubt the power is all there and for me ultimately the solution was to build my own databinding subclasses of the .Net Windows Forms classes that simplify the process by adding properties to my custom controls that can be set in the property sheet. After all if you write database applications almost all controls are databound and you surely don't want to write code to bind each and every control manually.

Databinding in Web Forms thankfully is simpler, but it also has a major problem: It's is one-way only. You can only display databound data, but you can't write it back to the datasource. It's hard to even call this behavior databinding. Granted ASP.Net still makes the population part easy by using the form controls to retrieve the data, but this still leaves me scratching my head as to why there isn't some way to grab the data from the controls and bind them back to the data since the control binding is already there? Just about every single data driven Web page needs to do this so why isn't this built-in?

Along the same lines data validation also is far from trivial. Instead of providing easy tools and masks on the various controls external objects and extra event handlers are required to make validation work. Again there's lots of code and many opportunities for errors. Whatever happened to simple format string based validation that covers the 90% scenario? .Net opts for completeness and complexity instead of the ease of use scenario. As developers we can address this with wrapper classes, but since most of us will be re-writing this stuff over and over again, why couldn't this sort of thing have been included in the framework?

The Obnoxious

The UI designers themselves are another major cause of frustration. Both the Windows Forms and Web Forms designers have quirks that make them less than ideal to use on a regular basis. The designers are two-way code generators. Code is good – you can look at it and understand it. But code is also a hassle, because if something happens to go into the code that the designer can't deal with your form goes kaput. I've had at least 5 forms 'blow up' on me where the form designer all of a sudden decided that all contained controls no longer exist. The code is all still there, and the form compiles and runs correctly, but the designer doesn't show any of it. Saving at that point would wipe the missing designer controls from the source file. Ironically, it's the form designer's own code generated that caused this problem. In many cases the problem was fixed by moving around the Windows Forms generated code section immediately following the property section, but figuring that out took quite a bit of digging and help from somebody who'd had this problem before. Again – hours and hours of wasted time.

Rather than using real containership forms use code generation to hook up events and property settings. Both designers have problems if you copy controls around – try copying a button with some code attached and paste it onto another or the same form. It doesn't keep the code with it! Or try renaming a control after you've added some code to it. The events you implemented retain the original name like Button1_Click rather than updating to the now actual control's name. Code generation can bite you in a variety of ways like this.

Another example is how the main form of a Windows Form application is hard wired via the static Main function that gets embedded into a form. If you remove the form your entry point is gone. There's no way to regenerate the 'main' form as such – you now have to know and manually create the static main method somewhere. Why not just generate a startup class that references the appropriate main form so the form itself can be renamed or removed easily and an error generated would be obvious to catch?

Web forms don't fare much better. The Visual Studio .Net HTML designer is incredibly tedious to work with if you need to create or manipulate HTML manually. It offers Intellisense but no additional help for templates or inserts of any sort. And it's even worse at manipulating anything but simple HTML in design view. For example try to resize an HTML table with the designer – you might get lucky and pull on the right handle to stretch a cell or you might stretch the entire table. Or add a column. For a tool that puts such a heavy emphasis on the Web developer, the HTML designer is almost embarrassing. You can't even select a control in the visual designer and switch to HTML view and edit the HTML code quickly. Instead you'll have to find your place using the Search dialog or manually look through the document. How hard could it have been to implement this simple feature which at least would have allowed reasonably easy back and forth coding between WYSIWYG and HTML view? Luckily other companies have figured out how to build HTML editors that lets developers work both in visual and code modes simultaneously, but you can bet the majority of developers torment themselves with the VS editor. Visual HTML editing in the development environment has been Microsoft's weakest spot for years in the development tools even though it could provide the biggest productivity boost in Web application development.

Both the Windows and Web form designers suffer from the twitchy User Interface of the Property Sheet. When you click onto a property in the property sheet the field is not auto-selected to simply overtype the text. Instead you have to use the cursor keys or mouse to position the cursor when practically all of the time you simply want to write in a new value. The property sheet can't be navigated by keyboard easily either – you can't use up and down keys to move to the next property while in the value of a property. You can only navigate from the property name field. In the editor the various alignment tools are next to useless due to the scale and positioning of the various controls. Try right aligning a set of controls. Getting controls to line up requires manual movement of controls even though there are supposed alignment tools. These are little things but they cause lots of wasted time during everyday development.

And let's not forget about the Windows Forms UI itself – the stock controls aren't XP Themes aware, the way stock menus and toolbars look seems to come out of the last century. A 'state of the art' tool should support the latest Windows look and feel, but .Net doesn't provide it. Menus don’t support images natively (you have to owner draw them with a fair amount of code), toolbars aren't movable. And while the menu designer is easy to use, it requires a new event handler for every single menu button – there's no central handler event you can pipe selections through. Some of the controls like the tree and listview seem slow and flickery and have odd behaviors when default images are used. They don't have 90% events such as NodeClick(). Instead you have to handle 4 or 5 events to capture a selection of a node by keyboard, click and reclick correctly for all situations.

One of my biggest complaints is the lack of a built-in Web Browser control. The Web Browser control which has become such a mainstay of the modern user interface mysteriously wasn't provided as a managed control. Instead every time you like to use a Web control in your application you have to import the ActiveX control. This causes several problems: You have to use object variables for most parameters on events and properties and pass variables by reference. Since the ActiveX control was based on optional parameters you now have to pass complete parameter lists which .Net requires when calling COM components. What's worse is some important events like BeforeNavigate2 – which is needed to capture clicks in the browser control – don’t fire. Although that's a bug in the ActiveX control, this still renders usage of the control in .Net very limited. This is a known bug in the control for over 2 years that Microsoft acknowledges but refuses to fix. Several third parties have created more complete COM wrappers for the control that work more reliably, but it's non-obvious to find these solutions, likely only after a futile attempt at getting the ActiveX import to work correctly. Using an ActiveX control in this fashion also poses a security problem – since ActiveX controls are unmanaged code you'll run into security issues in applications that run over the network unless security is adjusted.

The .Net documentation in MSDN is a major issue as well, especially for more advanced topics. I've been working on an application that implements the ASP.Net runtime in a desktop application, and trying to find information on this topic has been very painful. Ultimately, with the help of several developer papers and a decompiler I was able to figure out what was happening behind the scenes when a new Application Domain is created for hosting the ASP.Net runtime, but this is not documented anywhere in the MSDN docs. Most methods that are related to this topic are documented with one liners in MSDN that say little more than the name of the method name with spaces in it. No example, no explanation of when this or that event would fire and what gets passed. I can't tell you how much time I've wasted searching for information in MSDN that ultimately wasn't there or utterly useless. It seems to me that a policy is needed at Microsoft to document functionality as the specs and the code are created, not afterwards when nobody is around to explain how the functionality is supposed to work. Without adequate documentation .Net is a huge time sink for unproductive research time.

Many things in .Net seem to be designed without having been thought all the way through especially in the Windows Forms engine where many features are implemented in a dead end way that can't be extended without throwing everything away and starting over. For example, menus can't be handled with a single event handler, but must add a method for every single menu option which yields extremely unwieldy source code even a moderately sized menu. The Help provider has no generic events that can be captured when help fires which means you can't hook any external Help tools for editing help. To fix this you need to completely throw out the built in behavior and built your own handlers or resort to third party tools that get it right.

The Unknown

.Net touts easy installation and when you build applications that you have full control over it certainly seems that .Net delivers on this count. You easily can deploy applications as Web apps, Web Services or Rich client applications. Rich client apps can take the form of Windows Forms apps running locally or from the Web or as Web Browser controls. Cool, right? Well, not so fast. The Web deployment scenario is certainly clean. You can pretty much copy a directory and create a virtual on the Web server to move it. But for Rich client applications things are considerably more difficult. It always looks so easy in the prospectus.

You can build attractive rich client applications with .Net, but I wonder whether .Net is really the right tool to build vertical or shrink wrap applications. .Net applications are monsters. Even the smallest of .Net applications requires close to 8 megs of memory at startup. And startup is slow as the code compiles on the fly. A simple Windows Forms application will run around 12 megs or so of memory usage. While memory is cheap these days, it just doesn't seem right to build small utility applications that take this much memory. Especially if you want to have it run all the time as might be the case with a Windows Service. Most administrators would have a fit to have a simple app take 10 megs to run when it loads at startup.

Security is also a big issue for shrink wrapped applications. The only environment an application will likely be able to run from once the client gets it is the local machine. If the application is loaded from the network and no specific security policy has been set, the application will run into a host of security violations from any code that tries to access the file system, call unmanaged code (which a lot of code from any third party provider is likely to do) or access content on the network. While this is configurable via machine and network policies, do you as a software developer/publisher want to be in the business on telling people how to configure their machines just so they can run your application? Security might be an important feature for Microsoft in large IT departments but it's not going to go over well with small businesses or sales to consumers who might want to do something as silly as run the application from a network share via their Wireless connection. .Net might be a sketchy platform to develop consumer or even business end user applications with. Security and security configuration in .Net is a very complex topic – I have three different .Net Framework Security books on my book shelf each more than 800 pages and most of it dealing with trying to justify the security features of .Net along with explaining the complex hierarchy of Code Access Security. Security is good, but providing a model too complex that it gets in the way of applications that need to run can be a problem too. At the very least the configuration tools need to get easier or ship with more default policies that can be easily applied to real life application scenarios.

There's also the issue of versioning applications as new versions of the .Net runtime become available. We've already seen that this is not a painless process with the beta version of the .Net 1.1 framework. If you've built an application using the original version of .Net upgrading to 1.1 is not as simple as simply recompiling your application, but you have to actually swap out your application references for the new versions of the runtime assemblies. In my applications which are rather simple to boot, not a single application ran under the new version of .Net. Some errors that occurred were changes to parameters and types of VS.Net generated code which were difficult to track down and fix (and not mentioned in the 'update' documents). In fact on two apps I simply gave up and decided to be content with leaving the app at version 1.0. Incremental application updates as the platform matures should be relatively painless, instead you end up with a 'legacy' application that's a pain to bring up to the latest date. This is not how I would envision a great 'deployment story'.

Summary

I certainly don't want to be a naysayer as I really believe that .Net has accomplished a lot of technical milestones even in this first release that makes it very capable development platform, and I enjoy working with it. I merely point out a few of the issues that I have run into as a developer myself – I'm sure many of you have many more to add to this small personal list. Some of these things are minor and more annoyances. Others such security and deployment still make me wonder just how viable .Net is for building desktop applications that are shipped to many users.

Yet the trade press is all up in arms over how perfect .Net is for every type of application and how well integrated and powerful the environment is. Indeed there are strengths but it is also important to voice some of the shortcomings if nothing else than to spur workarounds and solutions and to let Microsoft know that certain things require fixing.

There's so much great information from third parties out there today about .Net – if there's a problem somebody's probably figured it out and found a workaround today and most people are free about sharing the knowledge which is awesome. However, that still makes it difficult to find all of this knowledge and ultimately much of this is Microsoft's responsibility to provide out of the box in an environment where the information is more accessible namely via MSDN and the .Net Help.

This is a call for better usability in the tools. For me this alone is a huge loss in productivity every day as I roll my mouse around the screen for things that should be automatically positioned or handled more naturally. This is also a call to try and keep things simple when they can be made simple. This doesn't mean to give up power, but it means supporting the powerful features with easy to use, common use features that require less code and are more intuitive. This may mean providing simpler subclasses of existing classes (potential bloat) or sometimes maybe even breaking encapsulation in the class hierarchy chain to provide improved usability for common use scenarios. But I think for a tool that has so much RAD potential it would be a shame to miss this opportunity to provide better developer productivity and reduce the learning curve.

As always if you have any comments or questions about this or any Code magazine article or commentary you can discuss them at http://www.west-wind.com/wwthreads/default.asp?Forum=Code+Magazine

 

Rick Strahl is president of West Wind Technologies on Maui, Hawaii. The company specializes in Web and distributed application development and tools with focus on Windows Server, .Net and Visual Studio. Rick is author of West Wind Web Connection, a powerful and widely used Web application framework for Visual FoxPro and West Wind HTML Help Builder. He's also a Microsoft Most Valuable Professional, and a frequent contributor to magazines and books. He is co-publisher and co-editor of CoDe magazine, and his book, "Internet Applications with Visual FoxPro 6.0", is published by Hentzenwerke Publishing. For more information please visit: http://www.west-wind.com/ or email Rick at rstrahl@west-wind.com.

 

Amazon Honor System Click Here to Pay Learn More

 

 

 

 

  White Papers                  Home |  White Papers  |  Message Board |  Search |  Products |  Purchase | News |