This the second post in my VSL blog series that began with this post.
The design of VSL is guided by the following principles:
Coupling is minimized in several ways by narrowly scoping the functionality of classes and through the use of C++ templates to reduce hard dependencies between classes.
Avoid feature creep
To avoid investing resources in features that may not be needed, only the functionality required for the task at hand is implemented. For example the RichEditWin32Control and ListViewWin32Control classes could provide a complete wrapping of all of the features of the rich edit and list view controls; however, the former only provides those methods needed by the Single View Editor reference sample and the later only provides those methods needed by the Tool Window sample. This is true of most classes in VSL as well. We’re waiting for you to ask for features before we develop them so that we don’t waste resources on feature we think are needed but are not actually needed.
Exploit the C++ language and the Visual C++ compiler
The C++ language and the Visual C++ compiler are exploited in several ways:
The Resource Allocation Is Initialization (RAII) paradigm is simply that when a resource is allocated it is immediately and directly used to initialize an object that will ensure that the allocation is balanced with a de-allocation. RIAA can also be further extended to any action that needs to be balanced by a counter action, which I’ll call XRIAA (eXtendened Resource Allocation Is Initialization) for want of a better name. Code that consistently uses XRIAA correctly is exception safe*, in that nothing will be left unbalanced in the event that an exception is thrown.
Facilitate unit testing
As integrating into VS requires calling into a lot COM interfaces and some Win32 APIs, it is impossible to unit test an VS Package without mocking up a lot of COM interfaces and Win32 APIs. To that end VSL includes mocks for nearly all VS Platform interfaces and nearly all Windows Platform APIs. VSL also provides wrapper classes around some sets of Win32 APIs, and equivalent mocks for those classes. Other VSL classes that make use of the wrapper classes in turn take them as template parameters so that the mocks can be substituted for unit testing (this also facilitates minimizing coupling, as you can also provide your own wrapper class if you so desire).
Re-use without obstruction
We don’t want to box you in. There are lot of macros that can be overridden to make them do whatever you want (that’s compatible of course). Many classes take template parameters to allow you to provide your own custom implementation for a dependency of that class, and there a couple of policy based classes (a smart pointer and a smart resource although the latter will only be first available with the v2 release next month). Many classes also provide optional, statically bound (using __if_exists and __if_notexists) call backs into a derived class (and we are willing to add whatever additional optional, statically bound callbacks you desire to base clssses). That said there are two things we don’t do 1) Make every class suitable for derivation and 2) make all members protected, in order to leave us some room to refactor without causing breaking changes. However, since all of the source is provided in header files even those limitations can be worked around.
Responsive to requests
It’s been our experience that designs are never perfect the first time, and so a principle of VSL development, is a willingness to make breaking changes (i.e. changes that will require VSL consumers to modify their code), as the need arises. In part this both necessitated and enabled by the short cycle time on VS SDK releases (a CTP every month, and an official release every few months). It is necessitated as we can not afford to sit around making the VSL design “perfect” for months on end without actually producing anything consumable. It is enabled, as taking three years worth of breaking changes in one fell swoop is quite unreasonable, but taking a few every few months, is much more reasonable.
* - note that such code is only synchronous exception safe. C++ exceptions are synchronous, but Win32 structured exceptions like access violations, stack overflows, etc. are asynchronous.
Next up: Visual Studio Library (aka VSL): Simple Unit Test Example