Notes on (extreme) Performance requirements for CAB


Object Builder, the Dependency Injection framework that provides the underlying infrastructure for all of the “CAB Magic”, uses reflection.

Objects in CAB are never “newed”. They are always created through a factory that inspects the metadata in a type and processes it before returning an instance. This allows CAB to wire events, inject properties, inject parameters in constructors, etc. like in the following code snippet:

[InjectionConstructor]
public Module([ServiceDependency] WorkItem rootWorkItem)
{
_rootWorkItem = rootWorkItem;
}

Object Builder is extensible, meaning that you can insert your own strategies to analyze other metadata beyond those shipped out of the box.

Examples of these extensions are shown in the SCSF Reference Implementation (see BankBranchWorkbench):

[Action(ActionNames.ShowCreditCardAccountViewAction)]
public void ShowCreditCardAccountViewAction(object caller, object target)

Action is a newly defined attribute that is added to ObjectBuilder:

builder.Strategies.AddNew<ActionStrategy>(BuilderStage.Initialization);

Another example is shown in the CAB Hands-On-Labs.

By default all this metadata analysis happens at runtime, meaning that each time an object is created through Object Builder, the type will be inspected, the strategies defined in Object Builder will be executed and the instance will be returned; and this of course provides a great deal of flexibility but also takes time. The CAB Object Builder strategies use public reflection which is significantly faster than private reflection, but there’s an inevitable overhead.

In almost all cases (the vast majority from my experience so far) the performance of this implementation is enough, but there are always exceptions.

For example, when we ported CAB into the Compact Framework for mobile development, performance was a key requirement. Mobile devices normally don’t have the same memory and CPU power desktops have and reflection was a big tax.

The solution was to create a tool (2 actually: CABGen and OBGen) that “compiles” the dependencies and dynamically generates an assembly with all the required relationships. Enabling these tools required minor changes in CAB & Object Builder (a code diff between the 2 versions will reveal those).

The end result is that the code runs faster because everything is resolved upfront, the price you pay is the flexibility of loading modules on the fly. However, the system works in hybrid modes too, meaning that you can mix modules that have been “CAB and OBgen’ed” with standard ones. So you still have the choice of only optimizing those that are critical for your performance requirements.

CABGen and OBGen are included in the Mobile Client Software Factory (also in source code), and although they were originally meant for the Compact Framework of CAB, nothing really prevents you to use it on the full framework, although we haven’t tested it.

As I said, we haven’t really tested this, but if you have a performance stretch scenario, it might be something worth looking at, and we’d love to hear what the results were.

Comments (13)

  1. I might mention that this is more of a resource-constraint issue than one of performance – but that might be just splitting hairs. By and large, the performance of reflection is perfectly fine for user interaction.

  2. eugeniop says:

    "By and large, the performance of reflection is perfectly fine for user interaction."

    Yes, as I said, that is my experience for desktop apps. It is definitely faster on the Compact Framework, the initial reason we did this (following the YAGNI principle)

  3. Until 2 weeks ago, it had been about 8 months since I had an opportunity to look at any offerings from…

  4. Sam Gentile says:

    Steve has two posts. The first describes how I (and others) are pushing to integrate WPF into CAB on

  5. Abdallah Mossad says:

    hi, i would like to know how to use this tools (CabGen ObGen) on the regullar Microsoft.Practice instead of the mobile edition , i already try it but it dosent work for some reason .

    can any one provide me with an example on how to accomplish this since i have an performance issue with my app.

    Thanks

  6. NG says:

    At what places is the object builder invoked.Is it only at the time of module loading or whenever something is added to a workitem.Suppose I have an object which has neither service dependency nor component dependency and i do a new on it,Is the object builder invoked in this case

  7. Sam Gentile says:

    Steve has two posts. The first describes how I (and others) are pushing to integrate WPF into CAB on

  8. alik levin's says:

    Rich Newman posted awesome guides for Composite Application Block (CAB) programming: Table of Contents:

  9. Wilder Lopes says:

    I don’t now how i can use obgen and cabgen. Please, are there any tutorial about it? I’m using Microsoft Mobile Client Software Factory and now my application is crashing memory.

    Please. Help me…

  10. Steve has two posts. The first describes how I (and others) are pushing to integrate WPF into CAB on our project. The way I see it architecturally, is that we need to have the &quot;Grand Convergence&quot; of the Smart Client UI and the Browser based