I am caught between two conceptual models of how to construct objects, and am having trouble working out what standard I want to adopt.
I prefer to program in .NET and often try to use RAII and read-only properties to make immutable objects with their data passed in through constructor parameters. This has been a major advance compared to the VB6 days when we had to simulate constructors and by convention call “Init” or “Factory.Create” to get objects into a good state.
However, I am often making COM-callable wrappers to let me call functions via Automation from other applications. As you probably know, COM wants objects to have a constructor without any parameters. This is a dissonance with the RAII/immutable scheme that I have been using with such success in the .NET world.
I remember older object models like ADO where you would usually instantiate an object, set properties like ConnectionString, then call Open. The object could be immutable not via a ReadOnly declaration, but via throwing an “Can’t change while open” exception on the property setter.
Is this the best pattern to use for COM? Am I missing a better way to skin this cat? Since RAII came out of the C++ community, how do they handle COM being based on a different initialization scheme?
1
RAII doesn’t necessarily mean you have a fully working object. It means you have a fully constructed object that is ready to work. So if your object needs an initialisation call to set its state, that’s fine – its nothing to do with RAII that ensures you have an object that is possible to fill with state (ie its not half-built in some uncertain state).
I think its best to think of this as the difference between application and system state. ie the object is fully ready to go as far as the system is concerned, its correctly laid out in memory etc. Then your application can work with it.
Read this Martin Fowler article that discusses the difference between creating an object and initialising it via its constructor or subsequent property setting (eg Initialisation).
So. given you cannot create a COM object with constructor-style property setting, you have to either wrap its construction in an object you do have control over (so the constructor of your object only returns a valid object if the COM dependent is created and initialised)
C++ would do the same kind of thing, only C++ tends to be more concerned about lifetime using RAII (where the object is properly destroyed when it goes out of scope) than about initialisation. Many people wrap a COM object in a smart pointer (eg CComPtr to name one) but this still doesn’t set its properties like you want. There’s still nothing stopping you wrapping the smart pointer further with a constructor that does it all.
3