Implementing the IObjectControl Interface

[Previous] [Next]

You're not required to implement the IObjectControl interface in every MTS component, but we highly recommend it. For every component built in Visual Basic that implements this interface, MTS calls three methods as objects are activated and deactivated:

  • MTS calls the Activate method just after the Initialize event.
  • MTS calls the Deactivate method shortly before the Terminate event.
  • MTS calls the CanBePooled method just after the Deactivate event and just before object termination.

The CanBePooled Method

We'll start with the CanBePooled method, even though it's in fact the last one to be called. The CanBePooled method allows you, the developer, to control whether objects based on this component take advantage of object pooling.

Object pooling isn't supported by MTS, so in MTS it doesn't matter what you make this method return. COM+ does support object pooling, however, so if you return True, COM+ might put the object in the object pool when deactivated rather than have it killed. We'll talk more about object pooling in Chapter 15, "A COM+ Overview."

MTS always kills the object when deactivating it; so as long as you're running MTS rather than COM+, it doesn't matter what you have the object return. We recommend, however, that you make all your MTS objects' CanBePooled methods return False. Why is that? Well, there are two reasons:

  • When you allow a component to have its objects pooled, you should be absolutely certain that it will behave exactly as you want it to behave. Under no circumstances should an object be allowed to create confusion for its clients by behaving differently when it comes from the object pool than when it's created fresh, perhaps remembering something it should have forgotten. Until you're absolutely sure this will never happen, you'd better have your CanBePooled methods return False. For the client, a pooled object must behave exactly as a nonpooled object behaves.
  • An object that comes out of the pool must be able to accept any thread that COM+ wants to put it on. This flexibility isn't a feature of components written in and compiled by Visual Basic. Visual Basic objects can act only according to the apartment threading model, and this restriction means that they have what is known as thread affinity. They fall in love with the thread they're created on, and they never accept running on another thread. This is the present situation, and until it's changed Visual Basic components can't be pooled. Until you're absolutely sure that the threading issue is OK, you shouldn't even try to have your Visual Basic components pooled.

You might encounter other complications with pooled objects. Until you know exactly which these complications are for your special case, you should avoid pooled objects like the plague. The only bulletproof way of doing this is to have the CanBePooled method return False. Here follows a code example that shows you how to avoid object pooling:

Private Function ObjectControl_CanBePooled() As Boolean ObjectControl_CanBePooled = False End Function

The Deactivate Method

Just before MTS calls the CanBePooled method, it calls the Deactivate method. The Deactivate method is one of the possible places for cleanup code, the other place being the Activate method. The object, as well as its context object, is still alive when the Deactivate method is called by MTS, whereas both object and context object are already gone when the object's Terminate event is fired. So if you have any cleanup code at all in the Terminate method, you should probably move it to the Deactivate method. But in many cases, especially if you can't or won't take advantage of object pooling, you can leave the Deactivate method empty:

Private Sub ObjectControl_Deactivate() End Sub

The Activate Method

The Activate method is the first of the ObjectControl methods that MTS calls. You can use it for different purposes. Here are three interesting ones:

  • You can use the Activate method to make sure that objects instantiated by the component behave the same whether they come out of the pool or are freshly created. You can, for instance, make sure that the object owns certain other objects whether it's old or new.
  • You can use the Activate method to get a reference to the context object.
  • You can use this reference to set a variable that indicates whether or not the object is running inside MTS.

Here's a small code example that actually takes into account the fact that this object might come from the object pool rather than being newborn. If an object comes from the object pool, it already has a reference to its context object; when it's newborn, it doesn't. By investigating the content of the mobjMySubObject variable, the code snippet also finds out whether the object already has a required subobject. If not, it creates one, using the subobject's ProgId.

Private Sub ObjectControl_Activate() If mobjCTX Is Nothing Then Set mobjCTX = GetObjectContext End If If mobjMySubObject Is Nothing Then Set mobjMySubObject = mobjCTX.CreateInstance("<ProgId>") End If End Sub

Later in this chapter, you'll see how we use the IObjectControl Activate method to get a reference to the context object and also to set a variable that indicates whether or not the object runs under the control of MTS.



Designing for scalability with Microsoft Windows DNA
Designing for Scalability with Microsoft Windows DNA (DV-MPS Designing)
ISBN: 0735609683
EAN: 2147483647
Year: 2000
Pages: 133

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net