Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Example of Code Structure for COM+ Component

In this article Jimmy Nilsson shows you his ordinary code structure for COM+ components, that you can use as a template for your own apps. The article is filled with tips and advice about where to get a reference to the ObjectContext, how to build a robust error handler, how to work with interfaces, and more.


In this article I show you my ordinary code structure for COM+ components. I show this in preparation for further articles about debugging tips. When I show this example, I guess I will also get a lot of flaming mails since everybody has different opinions on this topic...


In my latest article at VB-2-The-Max An error that must be trappedI promised to continue with a couple of debug-related articles. Before I do that, I’d like to show an example of my typical code structure. It’s very much debug-centred so it’s not totally off the topic. I believe that I have to show it to you before I dig into my debug tips because they rely on this structure. If I start discussing the debug tips before showing the structure, the risk is that you wouldn’t be able to "see the forest for all the trees".

Before I continue I’d like to tell a little story. Right now I’m working on renovating a room in our house. Yes, I’m doing the work myself. No, it’s not a good idea, but my wife asked if we shouldn’t hire a pro, so I didn’t have a choice. Why am I telling you this? Well, as always, the preparations are very important for the end result, for example when you are re-papering the walls. It’s exactly the same when it comes to system development. Especially when you’re building distributed applications. If you don’t prepare up front for debugging for example, you will suffer in the end.

I have developed and used several proposals for code structure, but the one I’m going to show here today is what I like the best (at least today). I also know that Michael D. Long uses a similar structure so I will ask him for help to find arguments when you start to complain. I will also try not to duplicate comments made by Mike in his article Building a Better Mousetrap for COM+ (MTS) from last week.

You don’t have to like all of it. I myself just love to look at code from other developers because I always get inspiration for how to refine my own. Perhaps you will get one or two such ideas yourself by looking at my code.


I have often written disclaimers for my error trapping and code structure in articles. Since the purpose of those articles has been others, I have chosen not to show the error trapping code and so on. Today, I’m trying to fix that old problem by doing things the other way around. The code shown here today won’t do anything useful at all.

But as always, there is a disclaimer here too. Don’t use any code you find in articles without testing it out thoroughly. That goes here too of course.


OK, let’s start with the code. I will show you a piece at a time and then comment on it.

Option Explicit

Implements ObjectControl
Implements ISomething
Private mobjCtx As ObjectContext

As you can see above, I choose to implement the ObjectControl interface and I keep a module-global variable called mobjCtx for the ObjectContext. You could call GetObjectContext() whenever you need a context-object, but I prefer this style.

I have also chosen to implement a user-defined interface called ISomething, but that is only to give you an example of how this is handled in this proposal. I will not use the default interface for the class, but will always call the component through this user-defined interface instead.

Private Sub ObjectControl_Activate()
  Set mobjCtx = jnskActivate(TypeName(Me))
End Sub

Private Sub ObjectControl_Deactivate()
  jnskDeactivate TypeName(Me), mobjCtx
End Sub

The only thing I always do in ObjectControl_Activate is to set the mobjCtx variable. I hide the call to GetObjectContext() in my own function called jnskActivate. The reason for this is amongst others to have a central place for adding tracing. (I will discuss this a lot in greater depth in an upcoming article.) Note that I use TypeName(Me) as a parameter. This lets me tell jnskActivate which class the call was made from. Earlier I used a constant for each module (both class modules and code modules) with the name of the module, but last spring Francesco Balena told me about this call that I had totally missed. Thanks Francesco! You could also use a module-global variable and set it once, but then... Sorry, let’s not get stuck with small details now.

The sub jnskDeactivate will set the mobjCtx to Nothing. You should always clean up after yourself, right? I won’t show you my implementations for jnsk-subs/functions today, but you can easily build the basic stuff in them on your own. You will find my implementations in coming articles. Stay tuned!

Of course, there must be an implementation of ObjectControl_CanBePooled also, but I only return False.

Public Function ISomething_SomethingFix() As Long
  ISomething_SomethingFix = SomethingFix()
End Function

As I said before, I use a user-defined interface called ISomething for calling the methods of this component. I don’t like to have the implementation code in the interface procedure itself. Compare with how you take care of events in the user interface. Most developers don’t think it’s good to have all the code directly in the click-event for a command button. Instead they will call another function/sub from the click-event. There is of course a cost involved in doing it like this, but this redirection is cheap and it also creates a place for putting in code to change output from Recordset to XML, for example. There is also a cost involved in not using the default interface, but once again, in my opinion the benefits outweigh this small runtime overhead. (Well, there are other drawbacks too. When it comes to script-clients, they can only reach the default interface.)

Private Function SomethingFix() As Long
  Dim strSource As String
  Dim lngErr As Long
  Dim strError As String
  Dim lngErl As Long
  strSource = TypeName(Me) & ".SomethingFix"
  On Error Goto ErrorHandler

Above, you have the beginning of the function that will be called. Note that it is private and can in the class only be called from the interface procedure above.

As you can see, I have a variable in each method that holds information about where I am. Unfortunately I can’t ask VB for help with the name of the method so I have to add that myself.

Another comment is that I have all the variables for holding error information locally. If you haven’t heard about the danger of using global variables in VB/COM+, please read MTS (and COM+) and global variables. You could also use module-global variables, but I think this proposal is less bug-risky.

Finally I activate error trapping, and I always use a label called ErrorHandler. (If you like to write tools for working with your own code, you will love standardised placeholders such as this!)

It’s of course possible to add source information to the interface function too, but I usually skip that.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date