I was recently approached by a customer about an intriguing project, unfortunately I can’t tell you too much about it since I’m under an NDA, but it involved creating an add-in for Internet Explorer and a custom Windows Service which would act as the backend. I’ve never created any add-ins for IE before but as a long time Windows developer I know that the Microsoft web browser is heavily dependent on COM. Since I’ve been doing mainly .NET development for the last 10 years or so, and sort of left the COM world behind me, I first started looking for some form of framework that would allow me to develop the add-in using managed code.
I found two different frameworks that I started evaluating. The first is an open source project originally created by Microsoft called SpicIE and the second is a commercial product called Add-In-Express for Internet Explorer. The latter is from the company Add-In Express Ltd who has specialized themselves on creating add-in frameworks and has a wide range of products to create add-ins for Office and IE in both .NET and in VCL for Delphi.
Both of these frameworks takes care of all the COM communication and implements all the necessary COM interfaces so you can concentrate on the more important things, namely what your add-in is supposed to accomplish.
In my case I needed to be able to create a toolbar button and an IE bar, which are those side panes similar to how Favorites and History are displayed within IE. There was no problem creating these in either framework but the Add-In-Express also had an Advanced IE Bar control with some additional features which I liked a lot. They also have visual designers which simplified everything and I was able to create a stub application, that demonstrated the final design, within a few minutes. It took me a bit longer to do the same using SpicIE, mainly because the documentation is a bit sparse (as the case often is with open source projects), but it comes with several demo projects that you can learn from. Add-In Express on the other hand have several video tutorials available on their website, which of course is a lot faster way to learn the basics without digging through a bunch of source code.
SpicIE also comes with this reservation:
Important: SpicIE is released independently of Internet Explorer and related products. It is not an officially supported product by the Internet Explorer team. While SpicIE is a valuable tool for prototyping and testing Internet Explorer extensions, it is not recommended for use with released software.
For me there was no question about which framework we would use for this particular project and if you would ever need to create a commercial product that requires an add-in for Internet Explorer I highly recommend Add-In Express, you’ll get a very stable product and excellent support from the team at Add-In Express Ltd, but this of course comes with a price tag so if you’re just a hobby programmer then go ahead and give SpicIE a try.
The next thing we needed to do was put a team together to start developing this particular system. Since the customers budget was rather tight my manager decided that we should use our offshore company in India for the development of the actual add-in while I should concentrate on the architecture and create the backend system.
I think I have to write a blog post about the experience I’ve had with this and other projects when the development team sits in different continents, with different cultures and in different time zones. It’s both exciting, fun, and very frustrating at the same time, but that have to wait for some other day.
Have fun!
As of today at 10:00 AM PST (19:00 CET) the Visual Studio 2010 SP1 is available for MSDN subscribers. If you don’t have an MSDN subscription you have to wait until Thursday, March 10 before you can download it.
If you already have beta 1 of the service pack installed you don’t have to uninstall that before you install the RTM version since it will be upgraded.
Today, Thursday, December 9, Microsoft is releasing the beta version of the Visual Studio 2010 Service Pack 1 to the public, MSDN subscribers have had it for a couple of days now. It has a Go Live license, so even though it is a beta release you can use it in your products today. Apart from many tweaks and bug fixes it also contains several cool new stuff:
- Intellitrace for 64-bit and Sharepoint.
- Silverlight 4 tools.
- Local help viewer.
- Performance Wizard for Silverlight.
- Unit testing on applications targeting the .Net 3.5 Framework.
All of the above features are great and you can read more about those plus many of the bug fixes and also find links to the downloads on Brian Harry’s blog. However in this post I’m going to spend some time on one particular new feature that, I think, will bring great joy to all VB developers around the world. It is also a big step towards the goal Microsoft has put up to bring language parity between the VB and C# languages. This new feature is simply called: VB Compiler runtime switch.
History Lesson
Visual Basic has a long history, the first version of Visual Basic was released back in 1991, but the history of the language goes back even further than that. VB1 was the first RAD tool for creating Windows applications and created a new way of programming by drawing the user interface using a control toolbox. But the actual language syntax was an extension of the older QuickBasic language.
So VB had a large baggage even before the release of the first version of VB.Net or VB7 back in 2002. At that time the language went through a large transformation, so large that many people didn’t even recognized their favorite language anymore. I must admit that I was one among many that felt the transition to this new framework was painful, not so much because I had to learn a new framework because I enjoyed that part (and I still love to learn new programming languages). The reason was simply because it wasn’t backward compatible and it was a pain to convert an older VB6 application to use the new framework.
Microsoft did their best to make the transition to .Net as smooth as possible and added a lot of legacy functions in the Microsoft.VisualBasic.dll assembly, such as Left(), Mid(), Right(), Chr(), ChDir(), MsgBox() and so on. These functions aren’t really necessary since there are other ways of getting the same result, but it made the transition from VB6 a lot smoother.
A lot of other stuff was also added to this assembly, such as the ability to use late binding (with Option Strict set to Off) and later on many of the My namespace features points to methods within the Microsoft.VisualBasic assembly.
Other “features” also included in this assembly are On Error Goto and On Error Resume Next that still works in VB.Net. The main reason those are kept is probably because the Upgrade Wizard (that existed in versions prior to Visual Studio 2010), that converted VB6 code into VB.Net (at least partially), should be able to work. It’s to hard for a software wizard to convert On Error Goto and On Error Resume Next statements into good Try…Catch blocks.
So what does this have to do with the new compiler switch?
There is nothing wrong with the fact that VB has its own runtime library, after all C# and Visual C++ also have their own runtime assemblies. The difference is the size of these assemblies and what they contain. The Microsoft.CSharp.dll, which was added in .Net 4, contains the runtime builder that adds support for the dynamic keyword, while Microsoft.VisualBasic.dll contains a lot more, as discussed in the previous section.
- So does it matter?
No it doesn’t. At least not if you only want to write code for platforms that include the full .Net framework, such as desktop applications for Windows or ASP.Net applications for the web. But there are other platforms that doesn’t include the full framework, such as Windows Phone 7 or XNA for creating games that runs on the XBox. There can also be other third-party platforms that only contain parts of the .Net framework. When you have limited space for a custom implementation one of the last things you might want to add is the large Microsoft.VisualBasic.dll assembly.
- So what? If I don’t use any of the legacy functions, don’t care about late binding, and always use Try…Catch instead of the terrible On Error statements, why would I need this assembly? Can’t I write VB code without it?
Yes, you can. However the assembly is always referenced by default as soon as you create a VB project, but you can actually remove the reference when you compile the project. However you would need to use the command line compiler to do so. But (and yes there is a but and a rather big one) there is a problem with removing the VB assembly and the name of that problem is the CType operator.
Since CType is an operator and not a function the conversion will be done inline at compile time, or rather the compiler will try to do it inline but that is not always possible. Converting an integer to a double can easily be done during compile time but converting the generic System.Object to a less generic type is not possible until run-time. So there is a helper function in the VB assembly that does the conversion for you, but it can of course only do that if the assembly is available and you have a reference to it.
So the /vbruntime switch, that has existed in the command line compiler (vbc.exe) for a long time, has now been extended. Instead of just excluding the runtime assembly or using another assembly as the runtime, it will now be able to include the key VB runtime as a reference into your application. This will be a great help to get VB support faster for new platforms.
- So will we see VB support for the XNA platform anytime soon?
Well, it might not be that soon since apart from this compiler switch it will also require new templates, a lot of testing and so on, but yes, I think we will be able to use VB for XNA development sometime in a not so distant future.
Have fun!
Have you also heard the rumor that VB and F# is not support on the new Windows Phone 7? Well, Justin Angel, a Silverlight expert, disagree and in this post on his blog he showed that you indeed can use those languages to develop WP7 applications. Check it out it’s a pretty cool workaround.
I must admit that I was a bit skeptic at first since the normal problem with supporting VB on a device that only implement a part of the .Net Framework (such as XNA for writing games for the X-Box) is to include Microsoft.VisualBasic.dll since it, as opposed to Microsoft.CSharp.dll, has a lot of references to other parts of the framework which might not be included in the limited version.
Now, it is actually possible to remove the reference to Microsoft.VisualBasic.dll in a VB project if you use the command line compiler but the problem with doing so is that the CType operator in some cases must use it. Yes, you read it correctly, CType sometimes need to do the conversion during run-time and must then call an internal function in Microsoft.VisualBasic.dll. If you, for example, would convert an integer to a double that would then be handled at compile time and the conversion would be inline but if you would want to convert an Object type to any more generic type the conversion can’t be handled by the compiler and then the internal VB.dll function will be called during run-time.
Well, according to Justin this is not a problem on a WP7 device since Microsoft.VisualBasic.dll is part of the Silverlight 3 distribution which has been ported to WP7. So this leads to the question why we don’t have “pure” VB support on the WP7 device today? Microsoft has said that VB support is coming but the question still remains.
Anyway, in the mean time, as Justin showed in his post, there is a simple workaround.
Thank you Justin (and an extra thank you to Jim Wooley for mailing me the link to Justin’s post)!
Have fun!
I just saw an interesting video blog post by the CTO of Devexpress entitled Pac-Man and Object-Oriented Programming, in which Julian talks about how we’ve been doing object-oriented programming for 20 years now (or even more than that if you come from the SmallTalk world) and how we, as OOP/OOD programmers and designers think about programming. He then quickly moves on to comparing that to a game of Pac-Man.
Now Pac-Man was a great video game developed by Namco in Japan back in 1979 and it was released in Europe and the US the year after. The game was an instant success, maybe because it was different from most of the other video games of the time, such as Space Invaders, Galaxy, and Asteroids, which was mainly shoot ‘em up games in which you should kill and/or destroy everything you saw (much unlike video games of today where we have 3D FPS games in which you walk around and kill/destroy everything you see… Oh, wait there isn’t that much of a difference, is there?). In Pac-Man you play this pie-chart looking character that walks around in a maze eating dots at the same time as you’re trying to avoid getting caught by one of the four colorful ghosts that are, for some reason, hunting you.
Whoops… Sorry! I got a bit nostalgic there for a moment and sort of strayed away from the topic. This blog post was supposed to be about object oriented programming and design and not about gaming. So let’s get back on track, shall we?
If you, as an OOP developer, would design the Pac-Man game today, how would you go about it? You should probably create a class for Pac-Man and another for the ghosts that hunts him. Well, they might actually be subclasses of a common character class since they do share some very basic logic such as they can’t walk through walls and other basic elements that you can think of. But they would still be 2 different classes. You might also have a Maze class that draws the actual maze and have some other logic like knowing which level you’re playing and such. The dots and power ups might also be different classes.
But the logic of the ghosts aren’t that easy. How will they go about to chase Pac-Man? They obviously need to know about his position but how do you calculate the closest path to get to him? The ghosts can’t go through a wall so you must calculate the nearest path around the maze. Doing that in every game cycle on a modern day computer is not such a big deal, but Pac-Man came out back in 1979 and the CPUs used at the time couldn’t do that and still produce a fast pacing game.
The solution Julian suggested was that maybe the ghosts in the game are like blood-hounds and Pac-Man is given away a scent as he moves around in the maze. The square in the maze Pac-Man just left gets a value that as Pac-Man moves on decreases in value until the scent has evaporated. This way the ghosts has no real knowledge about Pac-Man at all since they are just following a scent. The scent itself is now a property of the maze object and not of the ghost object. Julian called this anti-object oriented programming since the logic is not in the “real-world” object of the ghost (is that really a real-world object?). So by changing the logic of the ghost not to actually hunt Pac-Man but to follow a scent when they find it and also added some logic to the maze class, the anti-object, which you probably only used for drawing before.
I love this example since it’s an example of thinking-out-of-the-box when it comes to OOP and OOD. Instead of always trying very hard to make the classes as close to real-world objects as possible make a few changes and simplify the whole idea.
To be completely fair here, this is actually not how the AI of the ghosts in the original game was designed. If you’re interested I invite you to read the Pac-Man Dossier especially chapter 3 and chapter 4 that explains how the actual AI for the ghosts was created. But the fact that the actual design was different is beside the point. Julian showed a simple solution to a hard problem you might face when you’re doing object oriented design.
Have fun!
During the VSLive! keynote in Redmond, Microsoft yesterday announced a new Visual Studio product called LightSwitch.
LightSwitch is a new SKU for Visual Studio that will allow people to create line of business (LOB) applications for the desktop and the cloud without writing a single line of code. It will also be shipped with future version of Visual Studio Pro and above. In a way it reminds me of Access but with the difference that it can use different data sources, including Sharepoint and Azure SQL. Since the announcement there have been a wild discussion within the MVP programmers community, especially among VB and C# MVPs if this is a good or a bad thing.
We have seen tools like this before that are aimed to power users who aren’t full-fledged programmers and when a professional programmer have to take over the project it’s a mess with business logic code mixed up with UI code and data access code. I have not yet made up my mind if this is good or bad, but I do see some great opportunities with LightSwitch. Since it generates .Net code, in either C# or VB, and that it does seem to use an n-tier design I feel that this tool might become very successful. Of course we have to wait until the public beta is released later this month before we can actually see if the generated code lives up to the high standard professional developers demand.
Some of the discussion has questioned if this should have been released as an Office tool rather than as a Visual Studio SKU and even though that is a valid point I truly feel that the fact this tool is made by the Visual Studio team rather than the Office team the code generation will be better since the Office team isn’t really interested in creating development tools but also that more professionals might use this for prototyping or getting a quick start application that they continue to build on. If this will be the actual usage of the tool I don’t care if a power user instead of a programmer does the initial prototyping.
In either case I’m looking forward to giving LightSwitch a try as soon as the beta have been released. Several videos will be released showcasing LightSwitch during the next few days/weeks on the LightSwitch home page. Have a look and make up your own mind. Jason Zander, who held the presentation at VSLive, also wrote an excellent blog post about LightSwitch that demonstrates what it does and what it can be used for.
So what do you think? Are tools that hides the complexity of programming a good or a bad thing? Feel free to leave a comment.
Have fun.
Yesterday Microsoft had a big announcement day. At the same time as Steve Ballmer held his keynotes at the SharePoint Developers Conference (see the video) Microsoft released Visual Studio 2010 Beta 2 for MSDN subscribers, the public release will be tomorrow, October 21st. They also announced that the official release date of Visual Studio 2010 and the .Net 4.0 Framework will be on March 22nd, 2010.
Visual Studio has been given a new blue-purple logo and at the same time the MSDN web site has also been given a face lift using this blue-purple color scheme. If you have visited the Visual Basic Developer Center recently you may have already seen the preview of the new MSDN look. In my opinion it’s much nicer compared to the old red color scheme it had before.
With the beta release Microsoft also released Visual Studio 2010 Tools for SharePoint.
Microsoft have compiled a lot of 2010 resources on the VB and C# Developer Centers: VB 2010 Resources, C# 2010 Resources. They have also released a number of How do I videos. Note, the first two links will be available very soon, if they aren’t already.
I have looked forward to this beta release for a long time now, even though I have used Beta 1 since it was released back in May, beta 2 is much more promising simply because everything should be in place by now. Microsoft will probably not add any new features but rather just fix any bugs that are reported and concentrate on performance issues. So I can now start doing some real world testing and finally concentrate on to fully learn the new features of the framework. This of course also means that you can expect to see a lot more posts about VS2010 on this blog in the near future.
Have fun, I know I will. :)
On October 1st, I was re-awarded as a Microsoft MVP. In fact I almost missed the e-mail since it ended up in my junk e-mail folder. :)
This is the third time that I receive this award and it’s a recognition of my commitment to the programming community and a great honor.
Introduction
Anyone that has ever taken a programming class or read a beginners book on the subject know how important it is to write comments in your code. But is that really true? In this post I’m going to discuss/question the common practice of writing comments in your code.
Bad comments
A couple of weeks ago I was contacted by an old friend of mine that runs a construction company. They have an old custom system that they’ve had since the mid or late '90s sometime. He wanted some slight modifications made to this system, but the consultant business that created it apparently disappeared sometime during the dot-com death era. So he wondered if I could have a look at it and come up with an estimation of how much work it would require to do these customizations he needed.
Since he had all the source code - and because I’m such a nice guy – I asked him to e-mail the source over to me, which he did. When I opened up the old project (which was written in Visual C++ 6.0) the first thing I saw in the main file was this (the name of the developer and company have been changed to protect the guilty).
/***********************************************************************************
*
* File name : CGMain.cpp
* Developed by: John Doe
* Company : Former Dot Com Inc
* E-mail : john.doe@nowheretobefound.com
* Date : 1997-03-21
* Requirements: None
*
*-----------------------------------------------------------------------------------
* Version history
*-----------------------------------------------------------------------------------
*
* 1.0.0 Initial release
* 1997-03-21
* 1.0.1 Minor bug fixes
* 1997-03-24
* 1.0.2 Added 2 functions: AccViewF() and AccViewT()
* Reason: The customer needed to store the AccView creator and delivery
* 1997-04-03
* 1.0.3 Minor bug fix
* 1997-04-05
* 1.0.3 .... This goes on and on ...
* ...
* ...
* 1.2.7 Minor fix
* 1998-04-02
*
***********************************************************************************/
I can assure you that the list was lot longer than what I posted here. What is this good for? Why does a file need a comment header that tells me the name of the file? I already know which file I opened. Do I really care who wrote it? I don’t know that person and the contact information isn’t correct anyway. Could somebody explain to me why you would need a version history typed into the file? Ever heard of source control systems? Those are made to keep track of different versions of your file. The above comment doesn’t bring any useful information my way, or to my friend who isn’t a developer and because of that never even looked at the source code. All it did was made me scroll down a page or two before I got to the actual code.
I can understand that a company that sells class libraries and components with accompanied source code might want to add a (hopefully short) copyright notice on top of each file, but other than that there is really no reason why you want to have a commented header in your file.
When to add comments and when not to
In .Net there is one type of comments I always recommend people to use and that is XML comments. Those are great when they are added to methods and properties of a class library. A library, I might add, that you probably never open up the source code for, at least not if it comes from a third party. The XML comments aren’t meant to be read by humans, they are read by the compiler and shows valuable (hopefully) information in IntelliSense tooltips. Other helpful comments are JavaDoc and PyDoc comments used respectively in Java and Python to create documentation.
I remember once reading a blog post by Jeff Atwood about this very subject, please hold on while I Google it for you……. ah, here it is. Jeff also wrote a long rant about header comments, much like the one above. However in his post he, more or less, said that you shouldn’t use comments at all, which I don’t fully agree with him on. But he has a very important point which I think is also an excellent advice, always aim to write, or refactor, your code so it doesn’t need any comments. With that I (and I think also Jeff, even though I can’t really speak for him) mean that you should always give your methods a very descriptive name, keep them short and to the point.
But unlike Jeff I still think it can be valuable to sometimes stick in a short comment that explains what the code is doing. However you must remember that the comment is then as important as the source code. If you refactor or change the source it is important that you also update the comment. Nothing is as useless as a comment that isn’t valid anymore.
A while back I saw the following comment in the code behind file of an ASP.Net page.
'TODO: The following code is very resource-intensive and
' should be refactored.
The page that contained this comment had been in the web application in question for years. I looked at the code and couldn’t figure out what it was that was so resource-intensive. I stepped through it, and analyzed it very carefully without finding anything special. So somebody must at some point have done what the comment said, but without removing the comment, which made me waste my time to analyze perfectly working code for no reason at all. Here’s another comment from the same project.
'This is probably not a good idea,
'and should be changed but I’ll leave it for now.
Excuse me while I scream and swear… (this text has been censored). What is it that isn’t such a good idea? How am I to know how the original developer was thinking when he wrote the above comment? Did he have a brilliant idea how the code could be refactored but was to lazy to do it now? Has he refactored the code but yet again forgot to remove the comment?
The point here is to never write comments that only make sense to yourself. Code is written once and read many times. Much of the code you write today are legacy tomorrow when you aren’t around anymore and some other poor sob have to update it. Always edit or remove comments when you edit the source.
At this point it probably sounds as if I think you shouldn’t write any comments at all with the exception of XML comments, but that is not the case. As Joel Spolsky have said: Code is easier to write than to read. That is so true. How often haven’t you looked back at some code you wrote just a couple of months ago and wondered: How was I thinking here… Not that you weren't thinking when you wrote it, the code is probably just fine, but at the moment you can’t remember the flow of the source. When you develop you are in the middle of it and probably know exactly why you should call that particular method from this particular place, but a few weeks later (after you’ve been working on something very different) when you revisit your older code you just can’t remember that flow. So it takes a while before you are up to speed with it again. Now, what if that isn’t you that revisit your old code? Somebody else that thinks in a different manner than you will have a much harder time to get the flow before he/she can be productive with your source. This is the main reason why developers want to work on new projects all the time. We usually don’t like to work with old legacy code, especially old code we haven’t written ourselves.
In those cases a few well placed comments might help a lot. Just keep remembering that you need to refactor the comments just as much as you need to refactor the source code.
End words
There are one type of comments I do enjoy to read, and that is your comments on my blog posts. :)
Have fun!
Introduction
I usually stay away from religious discussions when it comes to programming habits and technology choices simply because they don’t usually make any sense at all and are most often just based on emotions. Arguing if VB.Net is better or worse than C# is just nonsense in my book since the differences between them are minor. They both target the same platforms, and use the same framework, of course there are differences but none of them are so great that you would say that this is a much better language. I personally think that XML literals in VB are great but that alone doesn’t make VB a better language. It is just easier to handle XML in VB, so if you do a lot of that VB is a better choice for that particular purpose. I also like the ease with which C# handles iterators, but again that doesn’t make C# a better language, it just make that particular code part easier.
Another discussion I often see on the Web is if the Java J2EE framework is better or worse than the .Net framework. Again this just stir up emotions, if you’re a Java programmer you would of course say that Java is better than .Net and the other way around. It’s not true though… Java is not better than .Net and neither is .Net better than Java. It all comes down to which platform you’re targeting and what the requirements are for the project at hand.
Is an axe better than a saw? No, they are both exceptionally bad tools – if you’re trying to nail two pieces of wood together, that is. In that case you should use a hammer and not an axe and definitely not a saw.
Having said that, this post will still be a rant about a thing that really grinds my gears, copy and paste programming.
Why you should ban Copy and Paste
I want to start by making one thing very clear, I do not think it’s a bad habit to copy a great piece of code you find somewhere on the web and then paste it into your project. As long as you test the code and perhaps refactor it to fit your naming convention then that’s just fine. What I talk about is the habit of copying and pasting the same code all around a project or even between different projects. Come on! If you’re reading this blog there’s a big chance that you’re a .Net developer and as such you use a modern OOP language. The whole purpose of object oriented programming is to create classes for code reuse and to preserve encapsulation. Even if you’re using a structured programming language you can still refactor your code so that you don’t have to repeat the same thing over and over.
Even though older code might be well used and therefore perhaps less buggy doesn’t mean that it will stay that way. Business rules changes and if you need to change how a particular piece of code works you should only need to do that in one place. Also, if the code does contain a bug, you have just introduced the same bug in another place. The next time you feel the urge to copy some code think again and cut it instead. Cutting the code and pasting it elsewhere means you’re refactoring your code and refactoring (to paraphrase Martha Stewart) is a good thing. Cut the code, paste it into a new method and call that method from the place the code used to reside.
If you’re working on a WPF or Silverlight project you don’t even have to copy and paste common XAML code, use a ResourceDictionary instead. But that’s design code, it’s much more important to not copy and paste business logic or data access layer code to different places.
Conclusion
What do you mean conclusion?
Haven’t you paid attention?
Stop copy and paste code! :)
Have fun!

Have you any plans on starting to develop applications for Windows 7 yet?
The Windows API Code Pack can be used to access some of the new features in Win7, but also some existing features in older version of the Windows OS. The team at Microsoft that are behind the code pack have just updated all the sample code so they now come in both VB as well as in C#, and they did a very good job with it too. So go have a look, it’s pretty neat.
Have fun.
Introduction
Last time I demonstrated how to develop a Windows Communication Foundation (WCF) service. This time we’re going to look at the differences between a ASP.Net WebService and a WCF service. The biggest difference between them is probably that a WebService only can be activated via HTTP and they are tightly coupled with ASP.Net HTTP pipeline. A WCF service on the other hand can be bound to a large variety of network protocols. It also doesn’t require that it is hosted on a web server, it can be hosted in a console application, in a Windows Forms app, or in a WPF application. However WCF does have an ASP.Net compatibility mode setting to enable WCF services to be configured like a web service and also mimic their behavior.
Data representation
A WebService relies on the XmlSerializer to serialize types into XML and back to a .Net type. The following is a list of the things XmlSerializer can serialize to and from XML.
- Only the public properties (or fields) of an object.
- Collections can be serialized only if the implement the IEnumerable or ICollection interfaces.
- Classes that implements the IDictionary interface, such as Hashtable, cannot be serialized into XML.
- You can use attributes from the System.Xml.Serialization namespace on your own classes and members to control how instances of that class will be serialized.
- You can also generate classes that can be serialized into XML from definitions of the types in XML Schema using the xsd.exe command line tool.
Point 4 and 5 describes how you can define complex types (classes) that can be serialized to and from XML.
In WCF you would also usually begin with the definition of complex types which is done adding the DataContractAttribute and the DataMemberAttribute to the class and its members, as described in my earlier post. The DataContractAttribute can be used on classes or structures and the DataMemberAttribute on properties and/or fields, which can be either private or public.
A few important differences between the DataContractSerializer and the XmlSerializer are:
- The XmlSerializer serialize all public fields and properties, while you have better control using the DataContractSerializer.
- The DataContractSerializer has better performance over XmlSerializer.
- The DataContractSerializer can serialize Hashtables.
Service Development
To develop a WebService you would normally decorate a class with the WebServiceAttribute and each method with the WebMethodAttribute. This is however not an optimal solution since it does not constitute a contract for the operations performed by the service. ASP.Net 2.0 tried to rectify that by allowing you to use those attributes on an interface as well. That is the preferred method of doing it since the service contract can be reused with various classes that can implement that interface.
A WCF service requires you to create a contract, since the ServiceContractAttribute only can be used on an interface. So a WebService allows you to constitute a contract but doesn’t enforce it while a WCF service do.
A WebService only incorpartes BasicHttpBinding while a WCF service can use a wide range of bindings, such as WSHttpBinding, NetTcpBinding, NetNamedPipeBinding, amongst others.
Hosting the service
ASP.Net web services are hosted on a Web Server. A WCF service can be hosted on a Web Server but can just as well be hosted by a Console- or Windows Forms application.
Conclusion
I don’t want to make any conclusions about which technique is the best to use, because that depends on the specification. A WebService is usually easier to develop but are somewhat limited. A WCF service is more versatile but can be harder to develop. To make a true comparison you should really compare the two techniques if you want to host the service on a Web Server, such as IIS, since if you want to use another host you can’t use an ASP.Net WebService. I just leave the judgment up to you.
Have fun!
Introduction
In this post I’m going to do a tutorial on Windows Communication Foundation, WCF. This tutorial is divided in 4 steps:
- Defining the WCF data and service contracts.
- Implementing the WCF service contract.
- Creating the service-host application.
- Create a client application that uses the service.
So without further ado, let’s get busy.
Here is where we are getting busy
We're going to implement our WCF server as a simple console application so start Visual Studio and create a new Console project. But for now we just leave the Sub Main() empty, since we implement the server in step 3. We also need to add a couple of references, first of all we need to add a reference to the System.ServiceModel.dll, right click on the project node in the Solution Explorer and click Add>Reference and scroll down the list until you find it. We also need to add a reference to the System.Runtime.Serialization.dll, so repeat the earlier step to add that as well.
Before we start with the WCF specific details we’re going to create a Data Access Layer (a DAL) which our service will work against to retrieve data. For the purpose of this article I’ve made a very simple class that can return a list of persons, or a single person. This could be customer information or an employment roll or whatever. In this sample I’ve hardcoded a list of persons, in a real word application you would retrieve this data from a database.
Public Class DataAccess
Private Shared _list As List(Of Person)
Private Shared Function GetPersonList() As List(Of Person)
If _list Is Nothing Then
_list = New List(Of Person)
With _list
.Add(New Person(1, "Homer", "Simpson"))
.Add(New Person(2, "Marge", "Simpson"))
.Add(New Person(3, "Bart", "Simpson"))
.Add(New Person(4, "Lisa", "Simpson"))
.Add(New Person(5, "Maggie", "Simpson"))
End With
End If
Return _list
End Function
Public Shared Function GetPerson(ByVal id As Integer) As Person
Return (From p In GetPersonList() Where p.ID = id).FirstOrDefault
End Function
Public Shared Function GetPersons() As List(Of Person)
Return GetPersonList()
End Function
End Class
As you can see the methods returns either a List(Of Person) or a single Person object. We will create the Person class in the next step.
Defining the WCF data and service contracts
We need to create a data contract for each object a WCF service can return, we also need to mark each property that is returned as a DataMember. We do that by adding attributes to our class and its members. Add a new class to the project, make sure you import the System.ServiceModel and the System.Runtime.Serialization namespaces, that we added a reference to earlier, and add the following code to the class.
Imports System.ServiceModel
Imports System.Runtime.Serialization
<DataContract()> _
Public Class Person
Private _id As Integer
<DataMember()> _
Public Property ID() As Integer
Get
Return _id
End Get
Set(ByVal value As Integer)
_id = value
End Set
End Property
Private _firstName As String
<DataMember()> _
Public Property FirstName() As String
Get
Return _firstName
End Get
Set(ByVal value As String)
_firstName = value
End Set
End Property
Private _lastName As String
<DataMember()> _
Public Property LastName() As String
Get
Return _lastName
End Get
Set(ByVal value As String)
_lastName = value
End Set
End Property
Public Sub New(ByVal id As Integer, ByVal firstName As String, ByVal lastName As String)
_id = id
_firstName = firstName
_lastName = lastName
End Sub
End Class
The next step is to create the service contract for our WCF service. This contract defines what kind of operations our service provides and are defined as interfaces.
<ServiceContract(Namespace:="http://demo.wcf.samples")> _
Public Interface IPerson
<OperationContract()> _
Function GetPerson(ByVal id As Integer) As Person
<OperationContract()> _
Function GetPersons() As List(Of Person)
End Interface
Notice that the interface is decorated with a ServiceContractAttribute, I also changed its namespace, specifying the namespace is a best practice to prevent the default namespace of “http://tempuri.org” being used. Each operation that our service provides must be marked with the OperationContractAttribute, which you can see that I used on the two methods.
OK, now we have our contracts set up so we now need to implement them which we do next.
Implementing the WCF service contract
Since the contract and the service interface have already been designed, creating the service is straightforward and only requires that the interface is implemented.
Public Class PersonService
Implements IPerson
Public Function GetPerson(ByVal id As Integer) As Person _
Implements IPerson.GetPerson
Return DataAccess.GetPerson(id)
End Function
Public Function GetPersons() As List(Of Person) _
Implements IPerson.GetPersons
Return DataAccess.GetPersons()
End Function
End Class
As you can see I simply call the methods in the DataAccess class, that we defined in the introduction, in the implementation of the two methods.
That’s it. Our service is all done. But to be able to use it from a client application later we need to create a service-host application, which will host our service objects. That will be our actual server application and we’ll start creating that next.
Creating the service-host application
As I mentioned in the introduction, we will implement our service-host as a simple console application. So open the module with the Sub Main() definition and import the System.ServiceModel and the System.ServiceModel.Description namespaces. The latter of the namespaces is needed to describe the behavior of the metadata. In our case we will allow a client to get the data via a HTTP GET request.
The first thing we need to do is to configure a base address for the service. We do that by creating a new URI that specifies the address, port number, and the path of our service. We can use any IP port number that is usually not occupied, in this example I will use port 8240.
Dim uri = New Uri("http://localhost:8240/demo/wcf/samples")
As the path of the service I picked the same as I did for the namespace of the service contract we created earlier (which was “http://demo.wcf.samples”).
Next we need to create a ServiceHost reference, to which we must pass the type that implements our service contract and the base address that we just specified.
Dim host As New ServiceHost(GetType(PersonService), uri)
Now that we have our ServiceHost object we need to add an endpoint that exposes the service. To do this, you must specify the type of the contract the endpoint is exposing, a binding, and the address of the endpoint. The contract is our interface, and in this demo we will be using the WSHTTPBinding as the binding, and for the address we simply use the string “PersonService”.
A WCF service can use almost any kind of binding, you can use http binding, tcp binding and so on.
We will also need to enable Metadata exchange, to do that we add a service metadata behavior, as I already mentioned we will allow a client to get data from the service via a HTTP GET request. When this is done all we have to do is to open our host and wait for client requests.
Try
host.AddServiceEndpoint(GetType(IPerson), New WSHttpBinding, "PersonService")
Dim behavior As New ServiceMetadataBehavior()
behavior.HttpGetEnabled = True
host.Description.Behaviors.Add(behavior)
host.Open()
Console.WriteLine("The service has been started.")
Console.WriteLine("Press the ENTER key to terminate service.")
Console.WriteLine()
Console.ReadLine()
host.Close()
Catch ex As CommunicationException
Console.WriteLine("Error: {0}", ex.Message)
host.Abort()
End Try
You can now run the application. Not much will happen though, a console window will be created and the message that the service is started is shown. What we need to do now is to create a client application that can use the service. We’ll do that in the next section.
Create a client application that uses the service
Start by launching a new instance of Visual Studio, and create a new Console Application project. Add a reference to the System.ServiceModel.dll.
The first thing we need to do is to get the meta data of the service, and create the proxy code. You can use the SvcUtil.exe command line tool to do so, but there is an easier way. We can let Visual Studio do this for us by adding a Service Reference. To do this we first must make sure our service is running. So switch back to the previous instance of Visual Studio and start the project. Now switch back to this instance of Visual Studio and right click on the project node in the Solution Explorer and select “Add Service Reference” in the context menu. In the dialog that pops up we type in the URI we specified for our service endpoint in the previous section (http://localhost:8240/demo/wcf/samples) and click on the Go button. You should get the result you can see in the image below.
Click on the OK button and wait a few seconds while Visual Studio creates the proxy code for you.
Our proxy client will get the name PersonClient() which we need to create an instance of to be able to call the methods our service exposes.
Public Sub Main()
Dim client As New ServiceReference1.PersonClient()
Dim pers As ServiceReference1.Person = client.GetPerson(1)
If Not pers Is Nothing Then
Console.WriteLine("Person with ID=1 is {0} {1}", _
pers.FirstName, pers.LastName)
End If
Console.WriteLine("Person list")
For Each p In client.GetPersons()
Console.WriteLine("{0}: {1} {2}", _
p.ID, p.FirstName, p.LastName)
Next
Console.ReadLine()
End Sub
Make sure the service is running before running this code.
Conclusion
That’s all the steps that is needed to create a simple WCF service. It does require more code than an ASP.Net Web Service, in which you basically slap a WebMethodAttribute() to a method and your done, but I like the fact that WCF services encourage developers to use the contract-first principles. Next time, in part 2 of this “At your Service” series, I will do a comparison of an ASP.Net Web Service contra a WCF Service. Until then:
Have fun!
Introduction
In my last article I showed a simple example of how to create a Windows Service using VB. This time we’re going to have a look at how to debug the service from Visual Studio.
Since a service must run from the context of the Service Control Manager you can’t normally debug it in the same manner as you would any other project type. Normally you would need to build the project, install it using the InstallUtil.exe command line tool, and attach a debugger to the process while it’s running. Another approach is to create a separate project (console application) and call your main code from there.
Neither of these are an ideal way of doing the debugging so I’m going to show an alternative method, which you also can use to run your service from the command line, just like any other application.
Converting the service into a command line tool
When you create a Windows Service project in Visual Studio 2008, you get a ServiceBase designer to which you add controls and your code to. Normally you would, at the very least, override the OnLoad() and the OnStop() methods. But the designer also creates a shared (static) Main() method for you, which is the real starting point of the service. To be able to see that you need to open the designer generated code file. In VB this file is normally hidden, so you need to press the Show all files button in the Solution Explorer.
The Main() method looks like this (with some comments removed).
<MTAThread()> _
<System.Diagnostics.DebuggerNonUserCode()> _
Public Shared Sub Main()
Dim ServicesToRun() As System.ServiceProcess.ServiceBase
ServicesToRun = _
New System.ServiceProcess.ServiceBase() {New FileWatcherService}
System.ServiceProcess.ServiceBase.Run(ServicesToRun)
End Sub
A Main() method can receive arguments from the command line, you just have to add a string array as a parameter of the method. The whole idea is that if a specific command line switch is passed to the executable it should not act as a Windows Service but instead run as any other EXE file. So I rewrote the above method to this:
' The main entry point for the process
<MTAThread()> _
<System.Diagnostics.DebuggerNonUserCode()> _
Public Shared Sub Main(ByVal args() As String)
Dim runAsService As Boolean = True
For Each arg As String In args
Select Case arg.ToLower
Case "/c", "-c"
runAsService = False
End Select
Next
If runAsService Then
Dim ServicesToRun() As System.ServiceProcess.ServiceBase
ServicesToRun = _
New System.ServiceProcess.ServiceBase() {New FileWatcherService}
System.ServiceProcess.ServiceBase.Run(ServicesToRun)
Else
Dim service As New FileWatcherService
service.CommandLineExecution = True
service.OnStart(New String() {""})
End If
End Sub
If the /c or –c switch is found among the command line parameters then it will start as a regular program. As you can see, if the switch is found, instead of creating an instance of the ServiceBase class I create an instance of my service class directly and call its OnStart() method. I also added a CommandLineExecution property to the class so I can keep track of how it is supposed to be executed. If you need to set a breakpoint or step through the Main() method you need to remove the DebuggerNonUserCode attribute, otherwise Visual Studio will just run through this method without stopping (this is what you normally would want to do with designer created code).
Now I also needed to make some changes to the OnStart() method.
Protected Overrides Sub OnStart(ByVal args() As String)
Dim handle As IntPtr = Me.ServiceHandle
If Not Me.CommandLineExecution Then
_serviceStatus.currentState = Fix(State.SERVICE_START_PENDING)
SetServiceStatus(handle, _serviceStatus)
End If
Dim logMessage As String = String.Empty
If Not ReadSettings(logMessage) Then
WriteLogMessage(logMessage, EventLogEntryType.Error)
_serviceStatus.currentState = Fix(State.SERVICE_STOPPED)
If Not Me.CommandLineExecution Then
SetServiceStatus(handle, _serviceStatus)
End If
Else
If Not String.IsNullOrEmpty(logMessage) Then
WriteLogMessage(logMessage, EventLogEntryType.Information)
End If
'Start the file watching...
With FileSystemWatcher1
.BeginInit()
.Filter = _fileMask
.IncludeSubdirectories = _includeSubFolders
.Path = _folderName
.EnableRaisingEvents = True
.EndInit()
If Not Me.CommandLineExecution Then
_serviceStatus.currentState = Fix(State.SERVICE_RUNNING)
SetServiceStatus(handle, _serviceStatus)
Else
Threading.Thread.Sleep(Threading.Timeout.Infinite)
End If
End With
End If
End Sub
If the CommandLineExecution property is set to True I skip all the calls to the SetServiceStatus() Win32 API function. I also end the method by letting the current thread sleep for infinity, if I didn’t do that the program would just exit when it reached the end of the method.
I also made a slight change to the WriteLogMessage() method, if the application isn’t running as a service there is no reason to do the logging to the Event Viewer. Instead it simply shows a message box.
Private Sub WriteLogMessage(ByVal message As String, _
ByVal type As EventLogEntryType)
If Not Me.CommandLineExecution Then
If Not EventLog.SourceExists("File Observer") Then
EventLog.CreateEventSource("File Observer", "File Observer Log")
End If
Dim log As New EventLog()
log.Source = "File Observer"
log.WriteEntry(message, type)
Else
MsgBox(String.Format("{0}: {1}", type.ToString, message))
End If
End Sub
Debug the service
To be able to run this service as a regular application from Visual Studio you must pass the command line switch /c. You can specify command line arguments on the Debug tab of the project properties dialog.

Conclusion
In this post I showed you how to turn a Windows Service into a regular executable using a command line switch to allow you to debug it from Visual Studio. Of course, instead of a command line switch you could instead just check if the application is in debug or release mode. But I wanted to be able to run the service as a regular application even after it was compiled and deployed in release mode.
Have fun!
Introduction
Yesterday I got a call from my brother, or actually he sent me a message over MSN. He wanted to know if I could help him create a program with a very specific requirement. Where he works they have a system that creates a lock file when you enter a new journal into the system. However because of a bug (?) in that system, this file is not always deleted after the journal have been entered. If this file is not removed, no more journals can be entered and the system runs amok.
So my brother wanted a program that could monitor a folder for this file, if it’s not removed within a specified time, say 1 minute, an e-mail notification is supposed to be sent. Since this program was supposed to run on the server, it needed to be a Windows Service.
Creating a Windows Service
Creating a Windows Service might not be something you do on a daily bases, during my career I’ve only made 3 or 4 of them, and this one was the very first I’ve created using .Net. Developing a Windows Service used to be pretty darn difficult, but not any more. As it turned out it’s fairly easy these days.
You start by selecting the Windows Service project type in the New Project dialog box in Visual Studio.
Doing that will give you a ServiceBase designer on which you can drop your controls, but since a Service normally don’t interact with the desktop, since it’s supposed to be running even if nobody is logged in, you shouldn’t use input controls such as text boxes or buttons. Using a Timer is a normal way of handling the work the service should do, but in my case I only needed a FileSystemWatcher, so I just dropped that on to the designer surface. The designer also have a handful of properties, many of which are named Can… such as CanPauseAndContinue and CanStop. If you set the CanPauseAndContinue property to True you can override the OnPaus and OnContinue methods. In my case I wasn’t interested in that but I did want an administrator to be able to stop the service so I left the CanStop property as True. If you, like me, leave the properties with their default settings you will have to override the OnStart and OnStop methods and I will cover that shortly.
I needed a way to store settings for this service, such as the time it would wait before sending an e-mail, the folder and file it was going to watch, and various SMTP and mail settings, such as the subject and the body text. To keep it as simple as possible I decided to add an App.Config file. To do that just right click on the project in the solution explorer and select Add > New Item, in the context menu. Find the Application Configuration template and click the Add button. Note, leave the name as app.config Visual Studio will automatically rename this file and copy it to the Bin folder when you build the project. To be able to read the config file you need to add a reference to System.Configuration.
I will not go into the details of using an app.config file but in short you need to add an <appSettings> section under the <configuration> node under which you add your own settings.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="emailSubject" value="Can somebody remove this file please?" />
<!--
more settings go here…
-->
You can then read these values using the ConfigurationManager.AppSettings() method (this requires that you have imported the System.Configuration namespace which we set a reference to earlier).
In my service I added a private method which I simply called ReadSettings. I will not show you all of that code since it’s mainly boiler plate, but a part of it looks like this:
Private Function ReadSettings(ByRef logMessage As String) As Boolean
Dim emailRecipients As String()
_eMailTo = New List(Of String)
Try
emailRecipients = ConfigurationManager.AppSettings("emailTo").Split(";"c)
Catch ex As Exception
logMessage = _
"No e-mail recipients with valid e-mails found, " & _
"edit ""emailTo"" in the config file."
Return False
End Try
For Each email In emailRecipients
email = email.Trim
If Not String.IsNullOrEmpty(email) AndAlso IsValidEmail(email) Then
_eMailTo.Add(email)
End If
Next
If _eMailTo.Count = 0 Then
logMessage = "No e-mail recipients with valid e-mails found."
Return False
End If
Try
_subject = ConfigurationManager.AppSettings("emailSubject")
Catch ex As Exception
logMessage = "No e-mail subject found"
_subject = String.Empty
End Try
'read the rest of the settings
Return True
End Function
This method takes a parameter, logMessage, by reference. In some cases, for example with the e-mail subject, it is allowed to leave that out of the config file and the application will simply send the e-mail without a subject. Other settings, like the address or addresses to send the e-mail to is required. The ReadSettings method will return False if some required setting was not found, or in the wrong format. The actual writing to the log is done by the OnStart method, or rather it’s done by another small helper method that is called by the OnStart method.
Private Sub WriteLogMessage(ByVal message As String, _
ByVal type As EventLogEntryType)
If Not EventLog.SourceExists("File Observer") Then
EventLog.CreateEventSource("File Observer", "File Observer Log")
End If
Dim log As New EventLog()
log.Source = "File Observer"
log.WriteEntry(message, type)
End Sub
I put all validation rules in the ReadSettings() method so that when it’s time to send the e-mail, I know that I have e-mail addresses that are valid (or rather, that they have a valid form, not that I can check if the address itself really exists), and that the SMTP IP port is set to a valid integer and so on.
The OnStart() and OnEnd() methods
Even though you can override the constructor of the ServiceBase control, you shouldn’t really put initialization code there. This is because if the service is stopped and then restarted the constructor is not called again, but the OnStart() method is. So initialization should go into that method.
In my very specific case, I used a FileSystemWatcher to monitor the specified folder for the creation of the specified file. If the ReadSettings() method returned True I started monitoring the folder. If not I needed a way to stop the service from starting and write an error message to the event viewer. Unfortunately the OnStart() method does not have a way of signaling an error, so what you need to do is to call the SetServiceStatus() function which is a Win32 API function. Import the System.Runtime.InteropServices namespace and add the following code to your class.
<StructLayout(LayoutKind.Sequential)> _
Public Structure SERVICE_STATUS
Public serviceType As Integer
Public currentState As Integer
Public controlsAccepted As Integer
Public win32ExitCode As Integer
Public serviceSpecificExitCode As Integer
Public checkPoint As Integer
Public waitHint As Integer
End Structure
Public Enum State
SERVICE_STOPPED = &H1
SERVICE_START_PENDING = &H2
SERVICE_STOP_PENDING = &H3
SERVICE_RUNNING = &H4
SERVICE_CONTINUE_PENDING = &H5
SERVICE_PAUSE_PENDING = &H6
SERVICE_PAUSED = &H7
End Enum
Private Declare Auto Function SetServiceStatus Lib "ADVAPI32.DLL" ( _
ByVal hServiceStatus As IntPtr, _
ByRef lpServiceStatus As SERVICE_STATUS _
) As Boolean
Private _serviceStatus As SERVICE_STATUS
So the following is the code I used in the OnStart() method.
Protected Overrides Sub OnStart(ByVal args() As String)
Dim handle As IntPtr = Me.ServiceHandle
_serviceStatus.currentState = Fix(State.SERVICE_START_PENDING)
SetServiceStatus(handle, _serviceStatus)
Dim logMessage As String = String.Empty
If Not ReadSettings(logMessage) Then
WriteLogMessage(logMessage, EventLogEntryType.Error)
_serviceStatus.currentState = Fix(State.SERVICE_STOPPED)
SetServiceStatus(handle, _serviceStatus)
Else
If Not String.IsNullOrEmpty(logMessage) Then
WriteLogMessage(logMessage, EventLogEntryType.Information)
End If
'Start the file watching...
With FileSystemWatcher1
.BeginInit()
.Filter = _fileMask
.IncludeSubdirectories = _includeSubFolders
.Path = _folderName
.EnableRaisingEvents = True
.EndInit()
_serviceStatus.currentState = Fix(State.SERVICE_RUNNING)
SetServiceStatus(handle, _serviceStatus)
End With
End If
End Sub
So if everything works out the way it should I start the FileSystemWatcher by setting its EnableRaisingEvents property to True. In the OnStop() method I simply set this property to False to disable it.
When the FileSystemWatcher finds that the file that is being watched is created it raises the Created() event, in which I start a new thread that will simply sleep for the specified number of seconds and then check if the file still exists. If it does it sends the e-mail.
Private Sub FileSystemWatcher1_Created( _
ByVal sender As Object, _
ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Created
If e.ChangeType = IO.WatcherChangeTypes.Created Then
Dim thread As New Threading.Thread(AddressOf WatchFile)
thread.Start(e.FullPath)
End If
End Sub
Private Sub WatchFile(ByVal fullPath As Object)
Dim fileName As String = CStr(fullPath)
Threading.Thread.Sleep(_delayTime * 1000)
If IO.File.Exists(fileName) Then
SendMail()
End If
End Sub
Private Sub SendMail()
Dim mail As New System.Net.Mail.MailMessage
For Each email In _eMailTo
mail.To.Add(New Net.Mail.MailAddress(email))
Next
mail.From = New Net.Mail.MailAddress(_emailFrom)
mail.Subject = _subject
mail.Body = _body
Dim smtpClient As New Net.Mail.SmtpClient(_smtpHost)
With smtpClient
.Port = _smtpPort
If _requireAuthentication Then
.Credentials = New Net.NetworkCredential(_authenticateName, _
_authenticatePassword)
End If
Try
.Send(mail)
Catch ex As Exception
WriteLogMessage("Unable to send mail: " & ex.Message, _
EventLogEntryType.Error)
End Try
End With
End Sub
Adding an installer to the project
Since this is a Windows Service it has to be installed as such so that it’s listed in the Service control panel applet. So you need to add an installer to the project. Note that this installer is not the same thing as a setup program, it will just add the necessary code that allows this application to be installed as a service using the InstallUtil.exe command line tool that comes with the .Net framework. More about that tool in a second.
To add an installer select your ServiceBase designer and right click on its surface and select Add Installer in the context menu. This will add a new Installer designer to your project that contains two component, a ServiceInstaller and a ServiceProcessInstaller.
Select the ServiceInstaller and change its DisplayName property. This will be the name that is listed in the control panel applet. You can also change the StartType property to Automatic if you want your service to start directly after it has been installed. In my case I left that property as Manual.
Now select the ServiceProcessInstaller and set the Account property to LocalSystem.
That’s it. You can now build the project. To do the installation open up a Visual Studio Command Prompt and type:
InstallUtil c:\thePath\theNameOfYourAssembly.exe
And presto! Your service should now be listed among the others in the Services control panel applet. Try to start and stop it from there. If you want to uninstall the service, which you must do if you need to make some changes to the source code, then type the following at the command prompt.
InstallUtil /u c:\thePath\theNameOfYourAssembly.exe
Conclusion
Even though this was a Windows Service with some very specific requirements I hope that this article have answered some questions on how you can create your own services.
Have fun!
Introduction
In this article I’m going to try to explain what custom events are and why you should use them in your code. As you will see the term custom event in this context is not just an event you have created for your own class, but also a custom way of storing the delegates for this event.
Most of this article is intended for the VB developer, but with the exception of VB specific parts, especially found in the Background Info section, the information here also applies to C# (but with a slightly different syntax of course).
Background info
If you have used VB or any other .Net language for an extended time, you have probably created one or two user controls, or regular classes that raises events. Events in the .Net framework are implemented as properties that accepts a delegate. A delegate is similar to a function pointer in C or C++ although a delegate is strongly typed. I wont dwelve into the difference between a function pointer and a delegate in this article, since that would be an article of its own. Instead I will just simplify and say that a delegate is an address to a method that will be called by the handler (in this case its the object that exposes the event).
If you want to handle an event raised by an object you can use the AddHandler statement. But VB also has a simplified solution using the Handles keyword. If you drop a Button on a Form you could then handle its click event like this:
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'code for the click event goes here
End Sub
The above code will be called when the Click event occur for the object named Button1. This is made possible by another VB specific keyword that’s been around since VB5, the WithEvents keyword.
When you drop the button on the Form the designer will create the code that declares and initializes the component for you. The declaration of the button the designer creates looks like this:
Friend WithEvents Button1 As System.Windows.Forms.Button
You can use this syntax yourself in your code to handle events raised by objects without the need to call the AddHandler statement. However for clarity I will show the AddHandler approach as well. If the designer wouldn’t use the WithEvents keyword, you wouldn’t be able to use the Handles keyword either to handle the event.
Friend Button1 As System.Windows.Forms.Button
In this case you would need to use the AddHandler in our code.
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load
AddHandler Button1.Click, AddressOf Button1_Click
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) 'No Handles keyword
'code for the click event goes here
End Sub
Creating your own events
It’s very easy to let your own classes/controls expose events. In most cases you would probably declare your events like this within your class:
Public Event MySpecialEvent(ByVal sender As Object, ByVal e As EventArgs)
A class that have the above will expose a MySpecialEvent event. But this is not enough. It’s when you raise the event the code in the event handlers is being executed. So whenever it is time to raise MySpecialEvent you would use code like this:
RaiseEvent MySpecialEvent(Me, New EventArgs)
If you’re coming from a VB6 background, this will seem very familiar to you.
You might call the above a custom event, since that’s what it is. My class has a custom event called MySpecialEvent which I have implemented using the technique I just demonstrated. But as I mentioned in the introduction section, custom event (in the lack of a better name) in this context is much more than this. For Custom events you need to keep track of all the event handlers that is used. More about that in the next section.
Custom events = keeping track of event handlers
There is a problem with how we created our own events in the previous section: It can become a huge waste of memory resources.
Let me again take a regular Button in a Windows Forms application as an example. The Button component exposes no less than 68 different events. If they all would be declared with the Public Event EventName syntax, it would require that 68 fields needs to be created. Lets say a Form contains 10 buttons, that is 680 fields, and in the most likely scenario 670 of these are never used since we’re probably only interested in the Click event. So what we end up with are objects that takes longer to instantiate and more usage of heap memory that can’t be reclaimed, unless you remove the control from the Form and dispose it (and how often do you do that with controls you’ve added to a Form?).
So if you create your own user control or regular class that exposes many events you need a custom event storage. There is a special collection class called EventHandlerList in the Framework, available in the System.ComponentModel namespace, which we can use to store the event handlers.
Let’s say I create a class that contains a few typical mouse events and take advantage of the EventHandlerList to store all event handlers, I would write code similar to the following.
Public Class CommonMouseEvents
Private events As New System.ComponentModel.EventHandlerList
Public Custom Event Click As EventHandler
AddHandler(ByVal value As EventHandler)
events.AddHandler("OnClick", value)
End AddHandler
RemoveHandler(ByVal value As EventHandler)
events.RemoveHandler("OnClick", value)
End RemoveHandler
RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
Dim value As EventHandler = CType(events("OnClick"), EventHandler)
value.Invoke(sender, e)
End RaiseEvent
End Event
Public Custom Event DoubleClick As EventHandler
AddHandler(ByVal value As EventHandler)
events.AddHandler("OnDblClick", value)
End AddHandler
RemoveHandler(ByVal value As EventHandler)
events.RemoveHandler("OnDblClick", value)
End RemoveHandler
RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
Dim value As EventHandler = CType(events("OnDblClick"), EventHandler)
If value IsNot Nothing Then
value.Invoke(sender, e)
End If
End RaiseEvent
End Event
'Move event declarations go here...
End Class
Here we first create an instance of the EventHandlerList class, and then I declare my events.
Notice the Custom keyword and that the event must be declared as an EventHandler or one of its child classes. Inside the event declaration you must write code for the AddHandler(), RemoveHandler(), and RaiseEvent() procedures (the stub for these are added automatically by the designer in Visual Studio).
Now, the above is just the declaration of the events and the custom code to store, remove, and invoke the event handlers. You must still raise the events in the normal fashion, using the RaiseEvent statement.
What exactly are the EventHandlerList?
In the previous section I called the EventHandlerList a collection, but that is not really true. It doesn’t implement the IEnumerable interface, it is instead implemented as a linked list. That means that even though we save a great deal of memory space, we might have a trade-off in access speed since we need to search the list from front to end for an event handler. In the case a event handler doesn’t exist we need to traverse the whole list.
So why wasn’t this list implemented as a hash table instead? The answer is pretty simple, the list will probably not be very large. Normally you will probably not use more than say 10 events (and in most cases probably less than that) on a given object, and with that small amount of data a linked list is actually much faster than a hash table.
Have fun!



Introduction
In this article I’m going to try to explain one of the most misunderstood features of LINQ – deferred execution - and the impact it might have on your code if you don’t fully understand what it means.
What does deferred execution mean?
According to the dictionary the word deferred means delayed or postponed. So deferred execution in LINQ means that the actual execution of a query is postponed to a later time. Let’s say that you’re using LINQ to SQL and want to use the following LINQ query:
Dim cheapProducts = From p In db.Products _
Where p.ListPrice < 100 _
Select p
It’s easy to assume that the above will execute a query against the underlying database, but it wont. It will just create an IQueryable that has a reference to something that knows how this query can be executed (when it comes to LINQ to SQL this reference will point to an expression tree, but you don’t have to know about that since that’s just an implementation that the LINQ to SQL provider uses), but it will not run the actual query. LINQ has postponed, or deferred, the execution to a later time.
-To a later time, you say. So when is that exactly?
In LINQ the execution of a query is performed when you request the data, for example in a loop.
For Each prod In cheapProducts
Console.WriteLine("The list price for {0} is {1}", prod.ProductName, prod.ListPrice)
Next
But you might request the data earlier. Take the following query as an example.
Dim productList = (From p In db.Products _
Where p.ListPrice < 100 _
Select p).ToList()
In this case we request that the result of the query is turned into a List(Of Product). To be able to do that the query has to be executed. But that doesn’t really mean that we didn’t have a deferred execution, it just wasn’t delayed for very long since we immediately request that the data should be turned into a list. This would also be true if we instead of requesting a list would call the Count() extension method or anything else that wouldn’t return an IEnumerable(Of T) or an IQueryable(Of T).
What kind of implications might this have on my code?
For the purpose of this article I’m going to use a Person class that only have a FirstName and LastName property and a little helper method that fills a List(Of T) with a number of persons, which will be used as the data source of our queries. In other words I’m going to use LINQ to Objects, but the same rules apply even if you use any other LINQ provider such as LINQ to SQL or LINQ to XML.
Public Class Person
Private _firstName As String
Public Property FirstName() As String
Get
Return _firstName
End Get
Set(ByVal value As String)
_firstName = value
End Set
End Property
Private _lastName As String
Public Property LastName() As String
Get
Return _lastName
End Get
Set(ByVal value As String)
_lastName = value
End Set
End Property
Public Sub New(ByVal firstName As String, ByVal lastName As String)
_firstName = firstName
_lastName = lastName
End Sub
Public Shared Function GetPersonList() As List(Of Person)
Dim list As New List(Of Person)
With list
.Add(New Person("Bart", "Simpson"))
.Add(New Person("Lisa", "Simpson"))
.Add(New Person("Maggie", "Simpson"))
.Add(New Person("Homer", "Simpson"))
.Add(New Person("Marge", "Simpson"))
.Add(New Person("Ned", "Flanders"))
.Add(New Person("Maude", "Flanders"))
.Add(New Person("Rod", "Flanders"))
.Add(New Person("Todd", "Flanders"))
End With
Return list
End Function
End Class
Now let’s say we have the following code.
Public Sub Main()
Dim personList As List(Of Person) = Person.GetPersonList()
'Get a list of the Simpsons family
Dim lastName As String = "Simpson"
Dim persons = From p In personList _
Where p.LastName = lastName _
Select p
lastName = "Flanders"
For Each pers In persons
Console.WriteLine("{0} {1}", pers.FirstName, pers.LastName)
Next
End Sub
Which are the names that will be written to the console? If you guessed the names of the Simpsons, you haven’t paid attention. The query asks for all persons with the last name “Simpson”, but still the name of the Flanders are written out. Remember that the query is not executed when we define it but rather when we ask for the data. Since we change the lastName variable before the query is executed we have in fact changed the query.
The fact that the execution is delayed until we ask for the data also means that we can reuse the same query. Let’s make some slight changes to the last example.
Public Sub Main()
Dim personList As List(Of Person) = Person.GetPersonList()
'Get a list of the Simpson's family
Dim lastName As String = "Simpson"
Dim persons = From p As Person In personList _
Where p.LastName = lastName _
Select p
For Each pers In persons
Console.WriteLine("{0} {1}", pers.FirstName, pers.LastName)
Next
Console.WriteLine("---------------")
'Change the last name
lastName = "Flanders"
'Reuse the query
For Each pers In persons
Console.WriteLine("{0} {1}", pers.FirstName, pers.LastName)
Next
Console.ReadLine()
End Sub
In this example we first write out the names of the Simpson family. Then we change the lastName variable and loop through it again. Since the query has been changed it will be executed a second time and we’ll get the names of the Flanders family. We reused the same query to get two different results.
Conclusion
LINQ is wonderful thing. It allows you to do complex things with very few lines of code and that can surely bring a big smile to your face. However, that smile can easily be turned into a stupid looking grin if you don’t understand deferred execution. If you don’t understand exactly when the query will be executed you might present completely erroneous data to your end users.
Have fun!
Introduction
In my last post I showed you a VB translation of Eric Lippert’s immutable stack class. There was however one thing that was lost in translation. In Eric’s original code he made the class enumerable (added support for a For Each loop). Because C# has support for iterators with its yield keyword, that was very easy to do… in C#. VB currently doesn’t have this feature so to add the same support we need to implement both the IEnumerable(Of T) and the IEnumerator(Of T), which in turn requires the implementation of the non-generic IEnumarable and IEnumerator and also the IDisposable interfaces.
The Interfaces

As you can see from the above image, that is 7 members that we have to implement. That might sound like a lot, but fortunately it’s mainly boiler-plate code. Firstly, the Reset() method of the IEnumerator interface is rarely used and in our case we will simply throw an NotImplementedException in that method. Secondly, we will end up with two GetEnumerator() methods and two Current() properties. But in our case we will simply make the non-generic versions of these members private and call the generic versions from them. Thirdly, in our case we will not change the code that the designer adds to the Dispose() method of the IDisposable interface, except for one little detail. The designer will mark the Dispose() method as Overridable, but since our Stack() class is sealed (NotInheritable) we only need to remove that keyword.
That leaves us with only 3 members to which we need to add our logic, the IEnumarable(Of T).GetEnumerator() method, the IEnumerator(Of T).Current() property, and the IEnumerator.MoveNext() method.
The implementation
To add support for all of this we first have to make a change to our IStack(Of T) interface.
Public Interface IStack(Of T)
Inherits IEnumerable(Of T), IEnumerator(Of T)
Function Push(ByVal value As T) As IStack(Of T)
Function Pop() As IStack(Of T)
Function Peek() As T
ReadOnly Property IsEmpty() As Boolean
End Interface
If you add this to your existing code, you will get the following in our class implementation:
To fix that simply put the text caret at the end of the Implements line and press the enter key. That will allow the designer to add the empty method and property procedures that we need to implement.
Since there will be two Current() properties and two GetEnumerator() methods, I simply rename the non-generic versions of these and make them private. From them we simply call the generic versions. In the Reset() method we simply throw an NotImplementedException.
Private Function IEnumerator_GetEnumerator() As System.Collections.IEnumerator _
Implements System.Collections.IEnumerable.GetEnumerator
Return GetEnumerator()
End Function
Private ReadOnly Property IEnumerator_Current() As Object _
Implements System.Collections.IEnumerator.Current
Get
Return Current
End Get
End Property
Public Sub Reset() Implements System.Collections.IEnumerator.Reset
Throw New NotImplementedException()
End Sub
The important members to implement is the GetEnumertor() and the MoveNext() methods plus the Current() read-only property. In a regular class that implements these interfaces we would simply return Me in the GetEnumertor() method. However since our stack is immutable we can’t do that since we don’t change the current instance when we Pop a value from the stack. So instead we add a private instance of the object that we will change when needed. We also need a private field to hold the current value.
Private _enumerator As IStack(Of T) = Me
Private _currentValue As T
As you can see we initialize the _enumertor to be a reference to the current object, Me. This is what we return from the GetEnumerator() method.
Public Function GetEnumerator() As _
System.Collections.Generic.IEnumerator(Of T) _
Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator
Return _enumerator
End Function
In the MoveNext() method we are supposed to return a boolean value if we can move to the next object. In our case we simply need to check our IsEmpty() property, if that is false then we can return another item. We also set the _currentValue field to the current value and Pop it from the stack.
Public Function MoveNext() As Boolean _
Implements System.Collections.IEnumerator.MoveNext
If Not _enumerator.IsEmpty Then
_currentValue = _enumerator.Peek()
_enumerator = _enumerator.Pop()
Return True
Else
Return False
End If
End Function
In the Current() property we simply return the _currentValue field that was set in the previous method.
Public ReadOnly Property Current() As T _
Implements System.Collections.Generic.IEnumerator(Of T).Current
Get
Return _currentValue
End Get
End Property
That’s pretty much it. We can now iterate throw our Stack using code similar to this:
Public Sub Main()
Dim myStack As IStack(Of String) = Stack(Of String).Empty
'init the stack
For i As Integer = 0 To 25
myStack = myStack.Push(ChrW(Asc("A") + i).ToString)
Next
'Use a For Each loop on the stack
'Note, since a stack is last in-first out,
'the alphabet will be written in reversed order here
For Each s As String In myStack
Console.Write(s)
Next
End Sub
Conclusion
As you’ve seen, since VB currently doesn’t support iterators in the same manner as C# does, we need to add a lot more code to our class to support it. Most of it are boiler-plate code though so it’s not as hard as it might look at a first glance. If you’re interested in learning more about how to use iterators in VB I highly recommend that you read this Visual Studio Magazine article written by Bill McCarthy.
You can download the code for this article here.
Have fun!
Introduction
In this article I will shamelessly “steal” the great work originally posted by Eric Lippert on his blog. However I will translate his code into VB and try to explain it from a VB developers point of view.
In my last post, I described what immutable objects are and what the advantage of using them would be. It also described how you could create an immutable class and use it as if it was value type. This time we are going to take this a step further and create an immutable stack.
An immutable stack, is that possible?
As Eric pointed out on his blog: This might sound a bit strange to you since a stack is by its very nature something that changes. You push stuff to it and pop things from it, last-in-first-out. So how can something like that be immutable? If we create a new stack object each time we push or pop something to/from the stack wouldn’t we then be allocating a great deal of memory? Well, in this case the answer is nope. Eric showed a very elegant way of saving memory, in some cases it might even be more efficient than a mutable version.
The idea is that you simply have a head object which is the last value or reference object (depending on what you’re storing on the stack) that was push onto the stack, and a tail which is a reference to the old stack. The state the stack was before the last item was pushed upon it.
Creating the Stack
As I’ve already mentioned, I did not create this code, all credit goes to Eric Lippert. All I have done is to translate it to VB, except for one detail. Eric implemented his stack as an IEnumerable(Of T), taking advantage of the iterator support that C# has with its yield keyword. Since VB currently doesn’t support that I simply didn’t implement it here. In the next part of this The Untouchables series I will however extend this stack class with support for iterators. As you will see it currently requires a whole lot more code in VB than it does in C#. If you’re interesting in learning more about how to use iterators in VB now, I would recommend that you read Bill McCarthy’s excellent article about the subject. But for now we just leave them out.
OK, onward! We are going to implement our stack using generics, so that you can use it to push any type onto the stack. The first thing we will do is to define an interface for our class.
Public Interface IStack(Of T)
Function Push(ByVal value As T) As IStack(Of T)
Function Pop() As IStack(Of T)
Function Peek() As T
ReadOnly Property IsEmpty() As Boolean
End Interface
If you have ever used a stack object before, you are probably accustomed that the Pop() method would return the value it just removed from the stack. In this case it doesn’t it simply returns another stack object without the value that was just popped. I must say that I agree with Eric here, that looking at the data should not require you to change it. A Pop which returns the value is a design flaw since it conflates two logically distinct and separate operations into one method. So in our case we use the Peek() method to look at the top value, and Pop() to remove it.
Our Stack class which will implement the above interface will have a constructor, but we will keep that private. You will get a new Stack object by calling the Push() and Pop() methods. However we also need a way to create an empty stack, otherwise we have nothing that we can Push or Pop anything to or from. Since every empty stack is the same, we will have a singleton empty stack that is created via a shared (static) method that we simply call Empty(). So we will be creating a new empty stack object (of strings in this example) in this manner:
Dim myStack As IStack(Of String) = Stack(Of String).Empty
Note that the myStack object above is not declared as Stack(Of String) but rather as our interface IStack(Of String). This is because our Empty() method returns an IStack(Of T) object that contains an instance to a private inner class called EmptyStack that like our Stack(Of T) class also implements the IStack(Of T) interface.
OK, here’s the full listing of the class.
Public NotInheritable Class Stack(Of T)
Implements IStack(Of T)
Private NotInheritable Class EmptyStack
Implements IStack(Of T)
Public ReadOnly Property IsEmpty() As Boolean _
Implements IStack(Of T).IsEmpty
Get
Return True
End Get
End Property
Public Function Peek() As T Implements IStack(Of T).Peek
Throw New Exception("Empty stack")
End Function
Public Function Pop() As IStack(Of T) Implements IStack(Of T).Pop
Throw New Exception("Empty stack")
End Function
Public Function Push(ByVal value As T) As IStack(Of T) _
Implements IStack(Of T).Push
Return New Stack(Of T)(value, Me)
End Function
End Class
Private ReadOnly _head As T
Private ReadOnly _tail As IStack(Of T)
Private Shared ReadOnly _empty As New EmptyStack
Public Shared Function Empty() As IStack(Of T)
Return _empty
End Function
Public ReadOnly Property IsEmpty() As Boolean _
Implements IStack(Of T).IsEmpty
Get
Return False
End Get
End Property
Public Function Peek() As T Implements IStack(Of T).Peek
Return _head
End Function
Public Function Pop() As IStack(Of T) Implements IStack(Of T).Pop
Return _tail
End Function
Public Function Push(ByVal value As T) As IStack(Of T) _
Implements IStack(Of T).Push
Return New Stack(Of T)(value, Me)
End Function
Private Sub New(ByVal head As T, ByVal tail As IStack(Of T))
_head = head
_tail = tail
End Sub
End Class
Notice how each time we Push a new value onto the Stack we call our private constructor that create a new Stack object. However our _tail will simply contain a reference to the old stack, that way we conserve memory resources. Since more than one stack object can share the same tail it will actually be more effective than a regular mutable version of a Stack object.
Dim s1 As IStack(Of Integer) = Stack(Of Integer).Empty
Dim s2 As IStack(Of Integer) = s1.Push(10)
Dim s3 As IStack(Of Integer) = s2.Push(20)
Dim s4 As IStack(Of Integer) = s2.Push(30) 'shares its tail with s3
Remember that the Stack object is immutable so pushing a value onto the stack doesn’t change it. Instead it returns a new Stack object containing the newly pushed value. The following code will raise an exception “Empty Stack” since myStack is still empty.
Dim myStack As IStack(Of String) = Stack(Of String).Empty()
myStack.Push("Hello")
Console.WriteLine(myStack.Peek) 'raises an exception since myStack is empty
That is like calling the Replace() method of a string without assigning the return value to anything. It will not have changed the immutable string. The correct way of doing the above would be this:
Dim myStack As IStack(Of String) = Stack(Of String).Empty()
myStack = myStack.Push("Hello") 'change the reference of myStack
Console.WriteLine(myStack.Peek) 'writes "Hello"
OK, next time I’m going to extend our Stack class to add support for iterators, so that we can use a For Each loop on our stack object. So stay tuned…
Until then, have fun!
There are many articles available on the Internet about immutable objects in .Net. Unfortunately almost all of them are addressed toward C# developers. In this article I’m going to rectify that by providing some information on the subject aimed toward the VB developer.
Immutable objects are a very simple yet powerful concept within programming. An object is immutable if its state cannot change after it has been created, which means that all its members need to be read-only. The integer number 1, for example, is an immutable number. There is nothing you can do that changes it. You can’t make it into an even number, you can’t bribe it, and you can’t make it jump of joy. Yes, you can add 5 to it, and yes you can multiply it with 2, but that doesn’t change 1, instead you end up with another immutable number.
System.String
In .Net the most well-known immutable object is the String. Once you have created a string you can’t change it, you can only create other strings. It’s easy to forget that fact and sometimes you might write code like this:
Dim str As String = "Foo"
str.Replace("F", "f")
The above doesn’t change the str value, the Replace method returns a new string object containing the new text.
Dim str As String = "Foo"
str = str.Replace("F", "f")
Now, some might argue that we above have changed str, and we have, we have changed it’s reference to point to a new string, stored in another place on the heap. But we have not changed the original string “Foo”, we simply just don’t have any reference to the original string anymore, which means that the garbage collector will kick in sooner or later and clean up that memory for us.
Advantages of immutable objects
So what are the advantages of creating our own immutable objects? Well, first of all, since its state can’t be changed, the hash code of the object never changes either. That means we can safely use them as keys in hash tables. Another advantage is that we can compare two objects with equivalence. You can compare two different string objects in the same manner as you would with value types.
Public Function CheckPassword(ByVal password As String) As Boolean
Dim mySecretPassword = "verySecret"
If password = mySecretPassword Then
Return True
Else
Return False
End If
End Function
Public Sub Main()
Console.Write("Enter password: ")
Dim pass As String = Console.ReadLine
If CheckPassword(pass) Then
Console.WriteLine("Access allowed")
Else
Console.WriteLine("Access denied")
End If
End Sub
Even though password and mySecretPassword are two different instances of string, we can still compare them in the same manner as you would do with value types (such as Integers or Doubles). This is possible because we can assume that the identity of an immutable object is its state. If the state could be changed we could not make that assumption.
But the killer argument to use immutable objects is because they simplify multithreading. Why is it that writing proper multithreaded applications are so hard? As Patrick Smacchia points out in this blog post, it’s because it’s hard to synchronize threads accesses to resources (objects or other OS things). The reason that this is so hard is because it’s hard to guarantee that there won’t be any race conditions between the multiple write and read accesses done by multiple threads on multiple objects.
If you had a hard time understanding the previous paragraph then think about it like this: You want to buy a new computer, but you’re not sure you have enough cash to get one. So you check your bank account over the Internet, and sure enough you have just enough to get the latest and best computer on the market. So you run down to the local computer store, but when you’re trying to pay using your Visa (or whatever card you use), your bank rejects the transaction. Why? Well, after the time you checked your balance but before you tried to pay for the computer, your wife (or significant other), which whom you share the bank account with, has bought a new coat (or something other less important thing compared to the computer you wanted). This is an example of a race condition that could happen between two separate threads. One thread checks a resource and then want to change it, or make some other assumption based on the current state, but between the check and the change another thread have already changed the state of the resource. But if the resource was immutable its state cannot be changed and are therefore more secure to use in a multithreaded environment.
So that gives us three great advantages of using immutable objects.
- They can be used as keys in a hash table.
- They simplify state comparison.
- They simplify multithreaded programming.
Creating your own immutable class
Just like the number 1 is immutable, the .Net framework provides two different keywords to create our own immutable values, Const and ReadOnly. Why do we have two keywords and what’s the difference between them? A field that is declared as a Const must be given a value when we create it, that means that there is no way for us to the let the user provide a value. The ReadOnly keyword on the other hand allows us to provide a value for the field in a constructor.
Public Class Person
Private Const _age As Integer = 21
Private ReadOnly _name As String
Public Sub New(ByVal name As String, ByVal age As Integer)
_name = name 'This is OK
_age = age 'This will not compile
End Sub
End Class
The true immutable value is the Const, but the ReadOnly keyword provides us with something that can be initialized when the object is created and then never change again which provides us with some flexibility.
In the rest of this article I will create an immutable Rectangle class. A rectangle has a top-left corner and a bottom-right corner. These four value (Top, Left, Right, and Bottom) are the only things we really need to describe a rectangle. Since the class is immutable we can only set these values, or properties, when we create a new rectangle object.
Private ReadOnly _left As Integer
Public ReadOnly Property Left() As Integer
Get
Return _left
End Get
End Property
So the class have the above property, and three more for the Top, Right, and Bottom values, which are all declared in the same manner. As you see I didn’t only make the property read-only but the backing field as well. This is important! If the class should be treated as immutable, the class itself should not be able to change the value either. I also created a Width and a Height property, but you will never assign any values to these properties since they can be calculated.
Public ReadOnly Property Width() As Integer
Get
Return _right - _left
End Get
End Property
Public ReadOnly Property Height() As Integer
Get
Return _bottom - _top
End Get
End Property
The values are provided to the constructor.
Public Sub New(ByVal left As Integer, _
ByVal top As Integer, _
ByVal right As Integer, _
ByVal bottom As Integer)
If bottom < top OrElse right < left Then
Throw New Exception( _
"Left cannot be larger than Right and Top cannot be larger than Bottom.")
Else
_left = left
_top = top
_right = right
_bottom = bottom
End If
End Sub
The class also provides two different methods, Intersect and Union. Both of these creates a new rectangle object. The dashed red rectangle in the following image shows what a union between the yellow and the green rectangle would result in.
The next image shows the intersection of the yellow and the green rectangle.
If a union or an intersection of the two rectangles can’t be created the methods return Nothing (null). Since there are an IntersectRect and an UnionRect function provided by the Win32 API, I didn’t bother about writing the logic for these methods myself.
Private Declare Function IntersectRect Lib "user32" ( _
ByRef lpDestRect As RECT, _
ByRef lpSrc1Rect As RECT, _
ByRef lpSrc2Rect As RECT) As Integer
Private Declare Function UnionRect Lib "user32" ( _
ByRef lpDestRect As RECT, _
ByRef lpSrc1Rect As RECT, _
ByRef lpSrc2Rect As RECT) As Integer
<StructLayout(LayoutKind.Sequential)> _
Private Structure RECT
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
End Structure
I however needed to be able to convert my object into the RECT structure that these functions uses, so I wrote a quick little private helper method. I made this method shared (static) so I could use it on any rectangle object.
Private Shared Function ToRect(ByVal r As Rectangle) As RECT
ToRect.Left = r.Left
ToRect.Top = r.Top
ToRect.Bottom = r.Bottom
ToRect.Right = r.Right
End Function
With this in place, creating the methods was a breeze.
Public Function Intersect(ByVal other As Rectangle) As Rectangle
If other Is Nothing Then
Return Nothing
Else
Dim r1, r2, r3 As RECT
r1 = Rectangle.ToRect(Me)
r2 = Rectangle.ToRect(other)
If IntersectRect(r3, r1, r2) <> 0 Then
Return New Rectangle(r3.Left, r3.Top, r3.Right, r3.Bottom)
Else
Return Nothing
End If
End If
End Function
Public Function Union(ByVal other As Rectangle) As Rectangle
If other Is Nothing Then
Return Nothing
Else
Dim r1, r2, r3 As RECT
r1 = Rectangle.ToRect(Me)
r2 = Rectangle.ToRect(other)
If UnionRect(r3, r1, r2) <> 0 Then
Return New Rectangle(r3.Left, r3.Top, r3.Right, r3.Bottom)
Else
Return Nothing
End If
End If
End Function
OK, so that’s all the logic in this class. But since we want this class to act as a value type we need to override the Equals() method. However whenever you override that method you also need to override the GetHashCode() method. The hash code of one Rectangle must be equal to another identical Rectangle. That is two rectangles with the same top, left, bottom, and right values.
Public Overrides Function GetHashCode() As Integer
Return (_top.GetHashCode Or _left.GetHashCode) Or _
(_bottom.GetHashCode Or _right.GetHashCode)
End Function
Public Overrides Function Equals(ByVal obj As Object) As Boolean
If obj IsNot Nothing AndAlso obj.GetType() Is Me.GetType() Then
Dim other As Rectangle = CType(obj, Rectangle)
Return (other.Left = Me.Left AndAlso other.Right = Me.Right) AndAlso _
(other.Top = Me.Top AndAlso other.Bottom = Me.Bottom)
Else
Return False
End If
End Function
We also want to be able to compare one Rectangle object to another using the = (equal) operator, please note that this is not the assignment operator which you can’t overload using VB since that is really a statement and not an operator. If we overload the equal operator we also need to overload its opposite, the not equal <> operator. Operator overloads are always shared (static).
Public Shared Operator =(ByVal r1 As Rectangle, _
ByVal r2 As Rectangle) As Boolean
If r1 Is Nothing Then
Return (r2 Is Nothing)
Else
Return r1.Equals(r2)
End If
End Operator
Public Shared Operator <>(ByVal r1 As Rectangle, _
ByVal r2 As Rectangle) As Boolean
Return Not (r1 = r2)
End Operator
So that’s it, put it all together and you’ve just created your own immutable class. OK, for your convenient I’ll show you the complete class below.
Imports System.Runtime.InteropServices
Public Class Rectangle
Private Declare Function IntersectRect Lib "user32" ( _
ByRef lpDestRect As RECT, _
ByRef lpSrc1Rect As RECT, _
ByRef lpSrc2Rect As RECT) As Integer
Private Declare Function UnionRect Lib "user32" ( _
ByRef lpDestRect As RECT, _
ByRef lpSrc1Rect As RECT, _
ByRef lpSrc2Rect As RECT) As Integer
<StructLayout(LayoutKind.Sequential)> _
Private Structure RECT
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
End Structure
Private ReadOnly _left As Integer
Public ReadOnly Property Left() As Integer
Get
Return _left
End Get
End Property
Private ReadOnly _top As Integer
Public ReadOnly Property Top() As Integer
Get
Return _top
End Get
End Property
Private ReadOnly _right As Integer
Public ReadOnly Property Right() As Integer
Get
Return _right
End Get
End Property
Private ReadOnly _bottom As Integer
Public ReadOnly Property Bottom() As Integer
Get
Return _bottom
End Get
End Property
Public ReadOnly Property Width() As Integer
Get
Return _right - _left
End Get
End Property
Public ReadOnly Property Height() As Integer
Get
Return _bottom - _top
End Get
End Property
Public Sub New(ByVal left As Integer, _
ByVal top As Integer, _
ByVal right As Integer, _
ByVal bottom As Integer)
If bottom < top OrElse right < left Then
Throw New Exception( _
"Left cannot be larger than Right and Top cannot be larger than Bottom")
Else
_left = left
_top = top
_right = right
_bottom = bottom
End If
End Sub
Private Shared Function ToRect(ByVal r As Rectangle) As RECT
ToRect.Left = r.Left
ToRect.Top = r.Top
ToRect.Bottom = r.Bottom
ToRect.Right = r.Right
End Function
Public Function Intersect(ByVal other As Rectangle) As Rectangle
If other Is Nothing Then
Return Nothing
Else
Dim r1, r2, r3 As RECT
r1 = Rectangle.ToRect(Me)
r2 = Rectangle.ToRect(other)
If IntersectRect(r3, r1, r2) <> 0 Then
Return New Rectangle(r3.Left, r3.Top, r3.Right, r3.Bottom)
Else
Return Nothing
End If
End If
End Function
Public Function Union(ByVal other As Rectangle) As Rectangle
If other Is Nothing Then
Return Nothing
Else
Dim r1, r2, r3 As RECT
r1 = Rectangle.ToRect(Me)
r2 = Rectangle.ToRect(other)
If UnionRect(r3, r1, r2) <> 0 Then
Return New Rectangle(r3.Left, r3.Top, r3.Right, r3.Bottom)
Else
Return Nothing
End If
End If
End Function
Public Overrides Function GetHashCode() As Integer
Return (_top.GetHashCode Or _left.GetHashCode) Or _
(_bottom.GetHashCode Or _right.GetHashCode)
End Function
Public Overrides Function Equals(ByVal obj As Object) As Boolean
If obj IsNot Nothing AndAlso obj.GetType() Is Me.GetType() Then
Dim other As Rectangle = CType(obj, Rectangle)
Return (other.Left = Me.Left AndAlso other.Right = Me.Right) AndAlso _
(other.Top = Me.Top AndAlso other.Bottom = Me.Bottom)
Else
Return False
End If
End Function
Public Shared Operator =(ByVal r1 As Rectangle, _
ByVal r2 As Rectangle) As Boolean
If r1 Is Nothing Then
Return (r2 Is Nothing)
Else
Return r1.Equals(r2)
End If
End Operator
Public Shared Operator <>(ByVal r1 As Rectangle, _
ByVal r2 As Rectangle) As Boolean
Return Not (r1 = r2)
End Operator
End Class
Have fun.
More Posts
Next page »