Handling Interdependent Objects in Automation – An Example of a Bank Server Object

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

–>

Bank : This application explains component creatability with a Client application perspective.
I got most of my inputs by using Microsoft Schedule+ Application . It supports lots of objects like
Appointments, Alarm, Schedule, etc,. One important thing in that application is that, most of these
components, any Client application can’t create as it is. What I mean by that, in VC++, Client can’t
creat these compnents by calling CoCreateInstance function, as these classes don’t have coclass
property attached to them. Similary in VB Client, you can’t just say ” Dim AlarmObj as New Alarm “.
That means, there are objects which the Microsoft Schedule+ server exposes, which the Client applications
can’t directly create. So, to creat them, user uses some other objects (whcih can be created directly).
For example, assume a case where a SingleAppointment object is there with you. You can create a Alarm Object
by calling one of its method i.e. ” Set AlarmObject = SingleAppointments.Alarm “. This is very nice
feature, which enable lots of inherent security in your object design.

The Server component that I have developed, is a Simple Bank object. The main security in this server is, even
though it exposes a BankAccount object, any Client application can’t create a BankAccount object directly.
This is very much true in real life also. For example, any Account you can think of is never existant in
real world, unless it is given out by a Bank. So, nobody can have a Bank account with himself without the
account being related to some Bank. Sorry.. for saying the same things again. But, it is very necessary
to expain this.
You see, the flexibility that you provide for creating the objects from your Server component
is a very critical issue. Generally, I have seen some applications, where in the Server allows user to
create all the objects they have without ever bringing out the creatability in to picture.

I have developed this server, keeping all these things in mind. It has been developed using ATL and VC++ 5.0.
I have also written two sample Test applications to demonstrate my point of view. One test application is written
using VB 5.0 and other is written using VC++ 5.0.

For simplicity sake, I have considered only three objects. viz. Bank , IAccount , IAccountManager.
One more thing that I have done in this server application is that, it implements COM Collection class. It
also shows how to use STL vector library. The server is a inproc server and has MFC support also.

There is very well defined clear heirarchy existing in creating the three components the server exposes.
In fact initially Client application can creat only one (i.e Bank Object) of these three components. Other
components (AccountManager and Account) can’t be created. Of course in real life, an AccountManager and an
Account can’t exist, without being related to particular bank.

As mentioned earlier, the Client will creat first the Bank object. Once he is throug with this, he will ask
the created Bank object, to get the AccountManager using one of its methods (i.e. GetAccountManager()). Once
he gets the AccountManager, he will go for creating an account. The AccountManager object, acts like a collection
class. He maintains a list of Account that are there in the Bank. The client calls Add method of AccountManager to
create a new Account. If the AccountManager feel it is ok to create a new account, it will return a Account object.
Thus in turn, Bank object is managing the whole show. The whole control is with the Bank Object.

One main thing to observe is the IDL file. In this you can clearly make out that we have AccountManager and Account
objects.


——————-
// BankAccount.idl : IDL source for BankAccount.dll
//

// This file will be processed by the MIDL tool to
// produce the type library (BankAccount.tlb) and marshalling code.

import “oaidl.idl”;
import “ocidl.idl”;

[
uuid(68B00060-801D-11D2-A7DE-00C04F79FED8),
version(1.0),
helpstring(“BankAccount 1.0 Type Library”)
]
library BANKACCOUNTLib
{
importlib(“stdole32.tlb”);
importlib(“stdole2.tlb”);

typedef enum
{
ACCOUNT_SAVINGS,
ACCOUNT_CURRENT,
ACCOUNT_MISC
}Enum_Account_Type;

[
object,
uuid(68B00071-801D-11D2-A7DE-00C04F79FED8),
dual,
helpstring(“IAccountManager Interface”),
pointer_default(unique)
]
interface IAccountManager : IDispatch
{
[id(1), helpstring(“Add an account”)] HRESULT Add([out, retval] IDispatch** ppAccount);
[id(2), helpstring(“Remove the current selected item (if any)”)] HRESULT Remove();
[id(3), helpstring(“Item get the One based Indexed Account”)] HRESULT Item([in] short int nIndex,[out, retval] IDispatch** ppAccount);
[id(4), helpstring(“Returns Number of Accounts “)] HRESULT Count([out, retval] short int* nNoOfAccounts);
[id(-4), helpstring(“method _Enum”)] HRESULT _Enum([out, restricted] short int* pSafeArray);
};
[
object,
uuid(68B00073-801D-11D2-A7DE-00C04F79FED8),
dual,
helpstring(“IAccount Interface”),
pointer_default(unique)
]
interface IAccount : IDispatch
{
[propget, id(1), helpstring(“property Type”)] HRESULT Type([out, retval] Enum_Account_Type *pVal);
[propput, id(1), helpstring(“property Type”)] HRESULT Type([in] Enum_Account_Type newVal);
[propget, id(2), helpstring(“Account Holder’s Name”)] HRESULT Name([out, retval] BSTR *pVal);
[propput, id(2), helpstring(“Account Holder’s Name”)] HRESULT Name([in] BSTR newVal);
};

[
object,
uuid(68B0006F-801D-11D2-A7DE-00C04F79FED8),
dual,
helpstring(“IBank Interface”),
pointer_default(unique)
]
interface IBank : IDispatch
{
[id(1), helpstring(“Method to get AccountManager object of the Bank”)] HRESULT GetMeAccountManager([out, retval] IDispatch** ppAccountManager);
};
[
uuid(68B00070-801D-11D2-A7DE-00C04F79FED8),
helpstring(“Bank Class”)
]
coclass Bank
{
[default] interface IBank;
};
/*
[
uuid(68B00072-801D-11D2-A7DE-00C04F79FED8),
helpstring(“AccountManager Class”)
]
coclass AccountManager
{
[default] interface IAccountManager;
};
[
uuid(68B00074-801D-11D2-A7DE-00C04F79FED8),
helpstring(“Account Class”)
]
coclass Account
{
[default] interface IAccount;
};
*/

};

Probably there might be some more articles about Collection class objects.

VC Test project – 5 KB

VB Test project sources zip file name here – 18 KB

Bank Server Download source – 53 KB

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read