According to GoF a proxy is a surrogate or placeholder for a another object to control access to it. The text later goes on to explain that a reason for controlling access to an object is to defer the full cost of its creation and initialization until we actually need to use it. Makes sense doesn’t it? A proxy is nothing more than a light weight way of accessing an object (regardless if it lives in the same address space as the caller).
Recently, for one of our work projects, we’ve been using a lot of Enterprise Services (ES) in order to have two-phase transactions between SQL Server and DB2 for z/OS 390. Our pain? ES proxy deployment. For those of you out there unfamiliar with ES, there are several ways of exposing your components for remote access. They are of course (in no order of precedence),
Each of these methods have their pro’s and con’s that will fit nicely into your problem scope. For us, our solution was DCOM. Why? Our customer has a lot of VB6 applications that can’t be migrated/converted to .NET at once and DCOM required the least ammount of programming effort to work with VB6.
To simplify our development of components, we created a base component class that inherits directly from System.EnterpriseServices.ServicedComponent. This class had the transaction, object pooling, JITA, etc attributes attached to it to simplify the development of other components. Also, this class contains several protected methods that provide some nice abstraction and reusability to the classes that extend it. The fun for these components comes during deployment.
The Component Services (COM+) MMC plug-in gives you a nice option of exporting your applications so they can be installed and run in other computers. Also, they also allow the exporting of a proxy so remote clients can gain access to your components (through DCOM). The proxy/application can be exported using a friendly wizard that generates an MSI file for you to run to install the proxy/application on the client computer.
Unfortunately, the proxies created by the wizard are nothing more than the same components installed on your server. That’s right, they’re the same object! The only difference is that when the proxy is installed on a client computer, the properties for the component are disabled. The only property a user change is the name of the remote server the object actually resides in.
This might not seem much of an issue, but if you’re like us and your components inherit from another object living in assembly A that has dependencies in assemblies B, C and D; well, your deployment list just (indirectly) got bigger! Let me explain this just a bit better for you…
When a request is made to your proxy object, COM+ needs to get type information so it knows exactly where to redirect the call to. Well, in order to get type information, the assembly containing your base class needs to be either in the GAC or in the probing path of COM+. If your base class’ assembly has any dependencies, they have to be in the GAC or in the same probing path! Get the picture? (yuck!)
If you’re using ASMX or .NET Remoting, you can bypass this problem because your component proxies are light. They offer a localized version of the component’s contract and not its full implementation (like ES proxies do). All the calls are sent to the remote object via HTTP or TPC. This makes the deployment of your web services or CAO/SAO pretty easy.
How do we ease our pain? We’ll, I have a working solution but that’s another post. For the meantime, have any of you run into this similar issue?