[
object,
uuid(9F56969F-339A-11D2-B37E-006008A667FD),
dual,
pointer_default(unique)
]
interface IBankAccounts : IDispatch
{
[propget, id(1)] HRESULT Savings([out, retval] CURRENCY *pVal);
[propput, id(1)] HRESULT Savings([in] CURRENCY newVal);
[propget, id(1)] HRESULT Checking([out, retval] CURRENCY *pVal);
[propput, id(1)] HRESULT Checking([in] CURRENCY newVal);
[propget, id(1)] HRESULT CreditLine([out, retval] CURRENCY *pVal);
[propput, id(1)] HRESULT CreditLine([in] CURRENCY newVal);
};
Figure 3 An Improved Version
[
object,
uuid(9F56969F-339A-11D2-B37E-006008A667FD),
dual,
pointer_default(unique)
]
interface IBankAccounts : IDispatch
{
[propget, restricted, id(DISPID_NEWENUM)] HRESULT _NewEnum(
[out, retval] IUnknown** pVal);
[id(DISPID_VALUE)] HRESULT Item([in] VARIANT index,
[out, retval] IDispatch** ppItem);
[propget, id(1)] HRESULT Count([out, retval] long *pVal);
[id(2)] HRESULT AddAccount([in] BSTR name, [out, retval] IDispatch** ppItem);
[id(3)] HRESULT RemoveAccount([in] VARIANT index);
};
interface IBankAccount : IDispatch
{
[propget, id(1)] HRESULT Name([out, retval] BSTR* pbstrName);
[propget, id(2)] HRESULT Balance([out, retval] CURRENCY* pVal);
[id(3)] HRESULT MakeDeposit([in] CURRENCY amount, [in] DATE date);
[id(4)] HRESULT MakeWithdrawal([in] CURRENCY amount, [in] DATE date);
[id(5)] HRESULT TransferTo([in] IBankAccount* pAccount],
[in] CURRENCY amount);
[id(6)] HRESULT TransferFrom([in] IBankAccount* pAccount],
[in] CURRENCY amount);
};
Figure 4 Handling Component Versioning
Versioning Technique | Requirements | Advantages | Disadvantages |
Support both old and new interfaces in a single component that replaces the old one. | Must still support old CLSID through use of the TreatAs registry keyword or by giving the new component the same CLSID as the old component. | No need to rewrite the setup program or rename the COM server because you simply install it on top of the old one. | You must extensively test the new component with old clients to make sure that the recompilation (even though it supports the old interface) does not introduce bugs into the system. |
Support new interface in separate component, leaving the old one alone. | Must use a new CLSID. Must install the COM server using a different installation path. Using same ProgID is inadvisable because legacy clients may create the component using the versionless ProgID. | Because old clients still use the old component, backwards-compatibility testing is almost trivial. The new component does not carry the baggage imposed by the old interface. | Over time, this approach tends to clutter up the system with different versions of the component. |