Rich Newman

September 23, 2007

Table of Contents for ‘Introduction to CAB/SCSF’ Articles

Filed under: .net, CAB, introduction — richnewman @ 9:38 pm

I have added a Table of Contents page for the Introduction to CAB/SCSF articles in an attempt to make it a little easier to navigate around them.

This is available from the recent posts menu.

Events in the CAB (Introduction to CAB/SCSF Part 12)

Filed under: .net, beginners guide, CAB, Composite Application Block, dotnet, events, introduction — richnewman @ 8:51 pm

Introduction

Part 11 of this series of articles gave a general introduction to events in the CAB. This article investigates what we can do with these events in a little more detail.

Parameters of the Fire Method

As shown in part 11, the Fire method has four parameters:

workItem.EventTopics["MyEvent"].Fire(this, EventArgs.Empty, null, PublicationScope.Global);

The first two are easily understood: they are the parameters that will be passed into the EventSubscription method. The first is an object, and is intended to contain the sender of the event. The second is an EventArgs parameter, and can be used to pass data into the EventSubscription method as with normal EventArgs classes.

The third and fourth parameters control the scope that the CAB will use for searching for appropriate EventSubscription methods to be called. The third parameter is a WorkItem, and the fourth an item from the CAB PublicationScope enum. It is expected that you will pass in the WorkItem that contains the code firing the event, although you don’t have to. For these purposes the EventSubscription is treated as being contained in the WorkItem that its parent subscriber object is in (remember it has to be in the Items collection of a WorkItem for the eventing to work).

The PublicationScope enum has the following possible values:

  • Global: the WorkItem parameter is ignored and ANY EventSubscription method with the correct name in the entire WorkItem hierarchy will be called.
  • WorkItem: ONLY EventSubscription methods with the correct name in the WorkItem passed in as the third parameter will be called. If no WorkItem is passed in no EventSubscription method will be called.
  • Descendants: EventSubscription methods with the correct name in the WorkItem passed in and any child WorkItems of that WorkItem will be called.

Code Example

A code example that shows these possibilities is available. This defines a hierarchy of WorkItems. Each WorkItem has its own Subscriber class to an event (“MyEvent”). The EventSubscriptions in each Subscriber class display an appropriate message when the event is fired. We then have three buttons that fire the event. The calls to the Fire method pass in as parameters a WorkItem in the middle of the hierarchy, with different PublicationScopes depending on which button is clicked.

Thus clicking the buttons shows how the PublicationScope affects which EventSubscriptions get called.

The EventTopics Collection

There are actually two WorkItems in the call to the Fire method:

workItem.EventTopics["MyEvent"].Fire(this, EventArgs.Empty, childWorkItem1, PublicationScope.WorkItem);

‘childWorkItem1’ is used to control the scope of the Fire method as discussed above.

‘workItem’ is used to access the EventTopics collection and hence our specific ‘MyEvent’ EventTopic.

Note that ANY WorkItem in the hierarchy can be used here to access the EventTopics collection, and the same EventTopic will be returned. In fact, behind the scenes there is only one EventTopics collection, and this is stored on the RootWorkItem. Any other WorkItem using the syntax workItem.EventTopics gets the same collection returned.

Thus the first WorkItem in the call does not affect the scope of the EventSubscriptions called at all.

Invoking onto the user interface thread

If you are familiar with .NET events you will know that one problem with them is that they can be fired on threads other than the user interface thread but may need to access user interface components. Threads that are not on the user interface thread should not interact with Microsoft’s GUI components as these are not thread-safe. As a result with .NET eventing it is quite common to ‘invoke’ back onto the user interface thread in an event handler as the first thing you do:

        private void RunIt()
        {
            if (((ISynchronizeInvoke)this).InvokeRequired)
                this.Invoke(new MethodInvoker(RunIt));
            else
                this.label1.Text = "Hello";
        }

Don’t worry if you don’t recognize and understand this syntax: just accept that we may need to get code running back on the user interface thread in certain circumstances, and that this is the way we do it.

Clearly CAB events can suffer from the same problem. Once again we have a very neat solution to this, however. We simply add a parameter to our EventSubscription attribute as below:

        [EventSubscription("MyEvent", ThreadOption.UserInterface)]
        public void MyEventHandler(object sender, EventArgs e)
        {
            MessageBox.Show("Hello from the CAB event handler");
        }

This has the effect of invoking the code onto the user interface thread when the event is fired and the code is called. It’s somewhat easier than the .NET code in the previous example.

The ThreadOption Enumeration

There are two other values in the ThreadOption enumeration that we can use here (other than ThreadOption.UserInterface as above):

  • ThreadOption.Publisher: forces the code to run on the same thread as the one the EventTopic was fired on. This is the default if we don’t specify a ThreadOption on our EventSubscription.
  • ThreadOption.Background: forces the code to run asynchronously on a background thread. This means the code in the EventSubscription does not block the thread in the class the calls ‘Fire’. With normal .NET events we would normally have to explicitly start a second thread to get this behaviour, so again the syntax is much simpler.

AddSubscription/RemoveSubscription

The syntax shown above for setting up a subscription to an EventTopic using the EventSubscription attribute is very clean. However, there will be times when we want to dynamically add or remove subscriptions in code rather than using attributes. This is analogous to the use of the ‘+=’ and ‘-=’ syntax for hooking up our usual .NET events to event handlers.

To support this EventTopic has AddSubscription and RemoveSubscription methods. Obviously we use AddSubscription to add an EventSubscription to an EventTopic, as below:

RootWorkItem.EventTopics["MyEvent"].AddSubscription(subscriber, "MyEventHandler", workItem1, ThreadOption.UserInterface);

This should be fairly self-explanatory: we are setting up an EventSubscription for the method MyEventHandler in our subscription object. We are setting up this subscription in workItem1, and when the event handler is called it will run on the user interface thread.

Similarly we use RemoveSubscription to remove an EventSubscription from an EventTopic:

eventTopic.RemoveSubscription(subscriber, "MyEventHandler");

Here we simply need to identify the object and the event handler name that we are trying to remove.

We are only permitted to have one subscription to a given event handler on a given object. This is why RemoveSubscription only needs the two parameters to uniquely identify the subscription to be removed. If we try to add a subscription that already exists then the CAB won’t throw an exception, nor will it add a second subscription. Similarly we can try to remove a subscription that doesn’t exist and the CAB won’t throw an exception (but won’t actually do anything of course).

An example that demonstrates AddSubscription and RemoveSubscription is available.

Note that in the CAB if we want to prevent our EventSubscriptions from running when an event is fired we don’t have to remove them entirely. The EventTopic has an Enabled property that can be used. There are more details on this later in this article.

AddPublication/RemovePublication

The AddPublication method of an EventTopic is used to add .NET events as ‘Publications’ into a CAB EventTopic. What this means is that we can fire a .NET event and have CAB EventSubscriptions run without the need to set up .NET event handlers directly ourselves, or to explicitly call the Fire method of the EventTopic. Similarly we have a RemovePublication event to disable this behaviour.

AddPublication: what is a ‘Publication’?

The ‘Publication’ nomenclature is a little confusing. As we have seen the CAB eventing mechanism uses ‘Subscriptions’ to an EventTopic, which are methods that run when the associated EventTopic is fired.

However, in general the CAB eventing mechanism doesn’t use ‘Publications’. The Subscriptions will run without an explicit ‘Publication’ being set up at all: we can just Fire the EventTopic when we need to.

The method containing the Fire event code can be thought of as a ‘Publication’. However, if we look at the PublicationCount of an EventTopic after it has been fired directly with the ‘Fire’ method we see that it is zero: normally we don’t need a Publication for a CAB event to work.

A code example that shows this is available. It also shows how to use the ContainsSubscription method of an EventTopic (which is straightforward).

With the AddPublication method we ARE explicitly creating a Publication, and in the example below the PublicationCount will be one when an EventTopic is fired. But this is only for the special case where we want to hook .NET events up to CAB event subscriptions.

AddPublication: code example

A code example of how to use AddPublication is available. In this example we have a button on the Shell form that fires our CAB event, but there is NO .NET event handler set up for the click event of that button. Instead at when the application starts up we hook up the EventTopic to the button directly:

RootWorkItem.EventTopics["MyEvent"].AddPublication(Shell.cabEventFirerButton, "Click", RootWorkItem, PublicationScope.Global);

Here Shell.cabEventFirerButton is the button on the Shell form, and obviously ‘Click’ is the name of the .NET event that we want to be a Publication in our MyEvent EventTopic. Once this code has been run if we click the button the EventTopic will fire and any associated EventSubscriptions will run. We don’t need to explicitly call the Fire event of the EventTopic.

In the section ‘Parameters of the Fire Method’ we saw that when we call the ‘Fire’ method we can specify the scope that the CAB will use to search for EventSubscriptions. If we use AddPublication as shown here we are not calling the ‘Fire’ method directly. Instead we can specify the scope parameters in the AddPublication call: they are the final two parameters to the call as shown above. These are a WorkItem and a member of the PublicationScope enum as before, and work in the same way.

Issues with AddPublication

The AddPublication syntax is a very powerful way of hooking up .NET events to CAB EventSubscriptions. However, it needs to be used with care. Developers expect there to be a .NET event handler for a .NET event, and it can be very confusing if code is running as a result of an AddPublication call.

For example, in the code above if you were trying to work out what happens when you click the button you could easily think there’s no code going to run at all. There’s no easy way to find out that the click event is a CAB publication and what the associated EventTopic is.

As a result my feeling is that direct use of AddPublication as shown in the example above should be used sparingly. It’s clearer to hook up the .NET event handler and then call the ‘Fire’ event of your EventTopic directly in the handler.

EventTopic Enabled Property

The EventTopic class has an ‘Enabled’ property. By default this is set to true, meaning that when the EventTopic is fired all the associated EventSubscriptions will run. However, we can simply set this property to false to disable all the EventSubscriptions of the EventTopic.

Once again this can be useful and there’s no easy way of doing it with traditional .NET eventing.

An example showing this is available. This modifies the example above used to demonstrate changing PublicationScope. The example is set up to have multiple EventSubscriptions to one EventTopic. All of these normally get called when a button is clicked and the EventTopic is fired.

The example uses a checkbox. When the checkbox is checked the EventTopic is enabled and firing the EventTopic runs all the EventSubscriptions, when it is cleared the EventTopic is disabled and the EventSubscriptions do not run. This is achieved with the code below in the CheckedChanged event of the checkbox:

        private void eventsEnabledCheckbox_CheckedChanged(object sender, EventArgs e)
        {
            rootWorkItem.EventTopics["MyEvent"].Enabled = eventsEnabledCheckbox.Checked;
        }

Conclusion

Events in the CAB are syntactically cleaner and are easier to use than normal .NET events, and can give us greater control over the scope of what runs when they are fired.

September 22, 2007

Introduction to Events in the CAB (Introduction to CAB/SCSF Part 11)

Introduction

Part 10 of this series of articles
described how the CAB implements commands. The CAB also provides a new way of raising and sinking events. This article will describe how this works.

Overview of events in .NET

Events in .NET are a publish-subscribe mechanism. We declare an event in a publisher class, instantiate the class, and then other objects can subscribe to the event. When they subscribe these objects identify a method that will be called when the event is fired.

We can then ‘publish’ by firing the event from the original publisher object. The methods on the subscriber objects are called.

This is an implementation of the Observer design pattern, and gives the benefits and liabilities of that pattern as outlined in the book ‘Design Patterns’ by Gamma, Helm, Johnson and Vlissides. In particular it allows for loose coupling between classes. Events are a callback mechanism, allowing code to be called without the caller necessarily having any direct reference to the object being called.

This mechanism is used throughout the .NET framework, particularly for such things as handling events raised by user interface components (e.g. button clicks).

This article assumes you know and understand all this.

Why do we need a new way of handling events?

Events in .NET are based on delegates and are extremely powerful. In many ways they are a key advantage of the language. For instance Java, which doesn’t have delegates, has some pretty nasty syntax for dealing with GUI events, and has no standard way of setting up the Observer pattern in more general cases.

So if events in .NET are so good, why have we got a new way of dealing with them in the CAB? What’s wrong with the usual events in .NET?

Problems with Events in .NET (1): Syntax

One problem with the current .NET eventing mechanism is that the syntax isn’t all that transparent. This is particularly true in C# (Visual Basic has neater syntax). You have to declare a delegate, declare an event based on that delegate in your publisher class, hook subscriber methods up to the event by creating an instance of the delegate and using the ‘+=’ syntax, and then fire the event with the Invoke method. The event can only be fired directly from your publisher class, so often we’ll additionally expose a method on the publisher class to allow other objects to fire the event (this is customarily called something like ‘OnMyEvent’).

Actually things have got a little simpler than that in .NET 2.0: now there are some syntactic shortcuts (we don’t need to create an instance of the delegate directly to add our event handler to the event, for instance). But to be able to use events effectively you really need to understand the previous paragraph, which clearly isn’t straightforward.

Problems with Events in .NET (2): Hooking Up Publishers and Subscribers

Another problem with events in .NET is that it isn’t always easy to structure your code well. The aim is to have a publisher object and a subscriber object linked by an event, but without necessarily having a direct reference to each other.

To set up the event code somewhere has to be able to add the method in the subscriber object to the event in the publisher object (with the ‘+=’ syntax). This code clearly has to have a reference to both objects. This can be tricky to do in a clean way in a highly object-oriented system.

For example, I’ve seen systems where we construct a switchboard object. This is a global singleton that caches references to all of our publisher objects. The switchboard object exposes methods that allow our subscribers to subscribe to our publishers’ events, and other methods to allow the events to be raised. It can also ensure that the publisher objects can be cleanly disposed of. This works, but can get messy as the temptation is to put all publishers into the switchboard, even if they are completely unrelated.

An alternative is to create all our publishers and subscribers at start up, and to hook up the events in the start up code. This is a more standard approach, and is also in many ways the approach used by the .NET framework when it auto-generates code to hook up user interface events. However, it isn’t always practical to do it in this way.

Events in the CAB

The CAB gives us the ability to handle events in a much cleaner way. Our WorkItem containers give us a way of handling scope issues for objects, and this enables us to hook up events with a more straightforward syntax than the usual .NET syntax.

Basic Example

Yet again the easiest way to understand what we can do with CAB events is to look at a simple example.

Events can be confusing, but if you think about the basics they are actually quite simple. We want to identify some code in one or more objects (our subscribers) that will get called when another object (the publisher) says so. The difficulty is that we don’t want the publisher to have to call the subscribers directly itself: this is a callback mechanism, and we want loose coupling between our objects. We just want the publisher to be able to say ‘fire my event’.

To do this in the CAB we first give our event a string name. We then identify all the code that will get executed when the event fires by applying an attribute with this name as a parameter, as below:

        [EventSubscription("MyEvent")]
        public void MyEventHandler(object sender, EventArgs e)
        {
            MessageBox.Show("Hello from the CAB event handler");
        }

Note that the method has to be public, and to have a method signature as shown. Of course this is the usual method signature for events in .NET, although usually event handlers don’t have to be public.

This is all the set up we need to do. We can now fire the event whenever we want, again using the string name to identify it:

workItem.EventTopics["MyEvent"].Fire(this, EventArgs.Empty, null, PublicationScope.Global);

That’s all there is to it. When this code is executed the event will fire and all methods decorated with the EventSubscription(“MyEvent”) attribute will get executed. We don’t have to create delegates and events specifically, or hook anything up with the ‘+=’ syntax. It’s also much clearer what’s happening.

Note that the containing classes for both the pieces of code above must be in the Items collection of a CAB WorkItem for this to work (although not necessarily the same WorkItem, as we shall see in part 11). Also, as shown, you need to have access to the WorkItem itself to fire the event, which you can obtain by dependency injection. If you’ve been reading this series of articles you should be used to that by now.

Sample Code

Code demonstrating this is available. This has an event example with separate Publisher and Subscriber classes. However the CAB events really don’t need a specific Publisher class: you can just fire the event with the syntax shown when you need it. A second example in the same code demonstrates this. The sample code also shows that you can easily have multiple publishers of and multiple subscribers to the same event by just duplicating the syntax above.

Conclusion

This article has provided a basic introduction to events in the CAB. Part 12 of this series of articles will examine these events in some more details.

September 16, 2007

Commands in the CAB (Introduction to CAB/SCSF Part 10)

Introduction

Part 9 of this series of articles discussed the Command design pattern. Commands in the CAB are a neat way of implementing this pattern. This article will examine them in some detail.

Commands and Events

As already discussed in part 9, commands in the CAB are closely related to events. In fact one of the ways that commands are intended to be used in the CAB is to hook up menus and toolbars in your application to the underlying code. This, of course, is something that is normally done in .NET using events. To make matters somewhat confusing, the CAB also has its own way of handling events. Part 11 of this series of articles will discuss CAB events, and how they relate to commands. In a later article I will discuss the Action Catalog (which is part of the SCSF code) and how that relates to both commands and events.

Basic Example

The easiest way to understand what we can do with CAB commands is to look at a simple example. The code for this is available.

This is a normal CAB application as described earlier in this series of articles. The main Shell Form has a standard ToolStrip with a button labelled ‘Call Command’ on it. When we click this button the application will display a message box saying ‘Hello World using CAB commands’.

Normally to do this in .NET we’d set up a standard event handler in the code behind the Shell Form, probably by just double-clicking the button in the designer, and then put our message box code in the handler. An example of this is also in the simple example code. We have a second button labelled ‘Call Event’. When it’s clicked it uses .NET events to display a message box saying ‘Hello World using .NET events’.

To use CAB commands we assign a named command to the button’s click event. We do this by referring to a named command in a WorkItem’s Commands collection:

Command helloCommand = RootWorkItem.Commands["HelloCommand"];

When the CAB sees this code it lazy-initializes the Command. That is, if a Command called ‘HelloCommand’ already exists in the collection it returns it, if it doesn’t exist it creates it and returns it.

(In the sample application the Command object actually gets created before this code, because the CAB scans for the CommandHandler attribute and creates commands based on that.)

Next we obtain a reference to our button (a ToolStripItem), and assign an ‘Invoker’ to the Command object:

            ToolStripItem toolStripItem = this.Shell.mainToolStrip.Items["toolStripButton1"];
            helloCommand.AddInvoker(toolStripItem, "Click");

In our Command design pattern discussion above we saw that an invoker is any piece of code that calls the Execute method on a Command object. Here we are saying that the toolStripItem’s Click event is an invoker for the helloCommand object. That is, when the event fires the Execute method on the Command will get called.

In simple terms we are just hooking up the Click event to our Command object.

Now we want to set up a receiver for the Command. Remember that a Receiver, if we have one, is code that actually does the work for the command. In the CAB we always have a Receiver: we never put the underlying functionality into the Command object. Note that this means the Command class itself is just plumbing code, and as developers we don’t need to change it.

We do this by simply applying the CommandHandler attribute to a method with an appropriate signature as below:

        [CommandHandler("HelloCommand")]
        public void HelloHandler(object sender, EventArgs e)
        {
            MessageBox.Show("Hello world using CAB commands");
        }

For this to work the object the code is in must be in a WorkItem collection of some kind. Of course, this is true of most of the CAB functionality as we’ve seen before. Here we really are using WorkItems as Inversion of Control containers. We set up the code as above and the framework calls us back as appropriate.

In the example code the command handler is in the code behind the Shell Form, which as we’ve seen before is in the WorkItem’s Items collection.

That’s all there is to it. Now when we click our toolstrip button the handler gets called and ‘Hello world’ gets displayed.

Points to Note

  1. The command handler’s method signature has to be as shown. It has to be public, and it has to have object and EventArgs parameters. I’ll discuss the parameters further below.
  2. There’s no ICommand interface in the CAB’s implementation. The interface to a Command object is just the default public interface on the Command class.
  3. As we’d expect, the Command object also has a RemoveInvoker method that lets us detach a command from its invoker.

Why Are We Doing This?

An obvious question at this point is ‘why we would want to do this?’ After all, we already have a perfectly good way of handling menu and toolstrip click events in .NET. Using a Gang of Four design pattern is nice, but is it giving us any real advantages?

We discussed one advantage of the Command pattern approach above. We can easily swap one command for another. This is particularly useful, for example, if we set up a standard toolbar that is going to be used with slightly different functionality for multiple screens in an application.

Another advantage is that our command handlers don’t have to be in the same class as the toolbar or menu they are supporting. This can make the code a lot cleaner. For example, suppose you have a Help/About menu item that shows a dialog, and you want the same functionality on all your menus. With .NET events you’d have to mess around setting up all the handlers to work correctly, probably with some singleton class to actually accept the calls. With the CAB command approach you can just set up a class with command handlers in it, add it to a WorkItem collection (Items) and then just call AddInvoker for every menu you want hooked up.

In fact the Command pattern lets us write incredibly simple and powerful menu systems for enterprise applications. We can do this in a way that is difficult to do with the standard event approach. I will write specifically about this at a later date, as there seems to be a lot of confusion about how you’re meant to set up menus using the CAB/SCSF.

Command Status

One other useful thing that you can do with CAB commands is to enable, disable or hide the ToolStrip buttons or menu items associated with a command simply by setting the status property on the associated command (the one that will be invoked when you click the button).

An example of this is available. This has two buttons on a ToolStrip on its Shell Form. If you click the ‘Enable/Disable CAB Command’ button the command handler below will run:

        [CommandHandler("EnableDisableHelloCommand")]
        public void EnableDisableHelloCommandHandler(object sender, EventArgs e)
        {
            Command helloCommand = _workItem.Commands["HelloCommand"];
            if (helloCommand.Status == CommandStatus.Enabled)
                helloCommand.Status = CommandStatus.Disabled;
                // Change this to the line below if you want to hide the cabCommandToolStripButton
                //helloCommand.Status = CommandStatus.Unavailable;
            else
                helloCommand.Status = CommandStatus.Enabled;
        }

As you can see this gets a reference to the helloCommand command in the Commands collection. This is the command associated with another button on the ToolStrip. The handler just flips the Status associated with the command from CommandStatus.Enabled to CommandStatus.Disabled or vice-versa. If you run this code you will see that this disables or re-enables the associated button.

Command Handler Parameters

Note that our command handler has the usual .NET event parameters. These are sender (an object) and e (EventArgs). However, if you put a breakpoint in the command handler you’ll see that sender is the Command object, and e is set to EventArgs.Empty. It isn’t possible to pass other values to these parameters if you are using commands.

In the discussion on the Command design pattern above we saw that we don’t pass any parameters to our Execute method. This is true of the Execute method in the CAB framework as well. However, behind the scenes the CAB uses normal .NET events to implement the Command pattern, and this allows it to pass more normal parameters to the command handler.

Note also that this is not significantly different from the .NET events we would normally use with a ToolStripItem. If we set up a normal event handler this has the same parameters, but again the EventArgs parameter is always set to EventArgs.Empty, and the object parameter is set to the ToolStripItem. Again, there’s no easy way of passing other values to these parameters.

When you are using .NET events in this way it can be useful to have access to the ToolStripItem that raised the event, which you can do via the object parameter. This is more difficult with commands. We can access a list of invokers for the command, and get the associated ToolStripItems from the list (although even this is difficult). However, we don’t necessarily know which of the invokers called the command handler.

Where’s the Execute Method?

In the examples here we haven’t seen any reference to an Execute method, in spite of this seeming to be a key part of the Command design pattern as described above.

Rest assured that behind the scenes in the CAB code the Command object DOES have an Execute method that gets called by the invoker. However, all we needed to do in our example was to set up the invoker with some simple syntax to get it to call the Execute method. We didn’t need to call it ourselves.

We can call the Execute method on our Command object directly from code, as this example shows. This lets us use commands in other ways than the standard invoker example seen above.

Which Events can we use as Invokers?

We’ve seen in our example that a ToolStrip button ‘Click’ event can be an invoker for a command. As mentioned above, the key use of commands is intended to be for menu systems, where they are very powerful.

However, we can only use the syntax in the examples above for standard .NET events on ToolStripItems and anything that derives from the Control class. If we want to hook anything else up as an invoker we need to do a little more work. Behind the scenes the CAB is using something called a CommandAdapter to hook up these events as invokers to our commands. The only CommandAdapters that are registered by default are those for ToolStripItem and Control.

We can use standard .NET events on one of our own classes as an invoker. However, to do this we need to create a CommandAdapter and tell the CommandAdapterMapService that it relates to our own class. Fortunately there is a generic EventCommandAdapter<> class that we can use (with our class type as the generic), rather than having to write our own CommandAdapter class.

A full code example of how to do this is available.

We would have to write our own CommandAdapter class if we wanted to use something other than a .NET event as an invoker (and still wanted to use the CommandHandler etc pattern). To do this we inherit the abstract base class CommandAdapter and override its abstact methods (which, predictably, include AddInvoker and RemoveInvoker).

Conclusion

CAB commands provide a powerful way of setting up flexible menus. However, using the Command pattern in a more general way can be a little confusing. Writing your own CommandAdapter class, or indeed using your own events as invokers as illustrated above, isn’t necessarily straightforward. Also, as we shall see in the part 11, in fact CAB events are probably better suited for this sort of thing. It may be better to think of CAB commands as primarily something you use to get powerful menu systems, and to move on.

September 15, 2007

The Command Design Pattern (Introduction To The CAB/SCSF Part 9)

Introduction

Part 8 of this series of articles concluded our discussion of services in the CAB.

This article and part 10 of this series will talk about commands in the CAB. Commands are a neat way of implementing the Command design pattern. This article will briefly recap what the Command pattern is and why it is useful. Part 10 will show how this is implemented in the CAB.

The Basics of the Command Pattern

‘Command’ is a design pattern from the original ‘Design Patterns’ book by Gamma, Helm, Johnson and Vlissides (the ‘Gang of Four’). The intent of the pattern is to:

“Encapsulate a request as an object, thereby letting you parameterize clients with different requests.”

The class diagram for this is below:

Command Design Pattern

The Command Class and Interface

The diagram looks more difficult than it is. What it is saying is that we define a simple interface, ICommand, which always has just one method, Execute (with no parameters and no return value). We then implement this interface on various Command classes. So a Command is just a class that does something useful in response to an ‘Execute’ call. However, because all our commands implement Execute using the same interface we have polymorphism: we can use them interchangeably in client code without having to change the client code.

The Invoker

In the class diagram above the Invoker is just any code that calls the Execute method on a Command object through its ICommand interface. This will usually be done in a way that allows us to use the polymorphism discussed above. That is, we should be able to swap around which underlying Command object the Invoker is calling, without the Invoker having to change.

The Receiver

In the simplest case the Execute method itself can just ‘be’ the command: it will do something useful. That may lead to our Command objects being very complicated however, so we may split out the underlying functionality into another class. This is the Receiver in the class diagram above. With a Receiver, whenever the Execute method is called on our Command it simply relays the call to the Receiver class which then does the work. If the command is complex there may be more than one Receiver class, with the Command class calling the Receivers as appropriate.

The Client

In the diagram above we also have the usual Gang of Four ‘Client’ class. This is code that gets us started by creating the other classes and hooking them up appropriately so that they will work. In real applications this may well be more than one class, but it makes the diagram neater to bucket all this functionality into one neat little box.

In the Command pattern the client code will instantiate our Commands and Receivers and give the Command objects appropriate references to the Receiver objects.

Finally note that in this pattern we are not passing any parameters to our Command objects, or returning any values from them. The method signature we are using is void Execute().

Why Is This Useful?

This pattern is useful because it decouples the code for actually executing a command from the code that calls the command code, providing a logical separation of duties and making the code easier to maintain.

Furthermore the pattern encapsulates the command logic in classes (the Receivers, if any, and the Command) that have a clearly defined interface. This lets us flexibly change which command we use in different circumstances using polymorphism.

For example we may have a class or set of classes that perform actions (our invokers), but want to vary those actions in a simple way based on the current state of the system. We can encapsulate the varying actions themselves into Command classes and then tell the invoker which one to use depending on the system state.

Menu Systems

The canonical example here, as discussed in the Design Patterns book, is a menu system in an application. The book describes how menu ‘toolkits’ are usually written as part of a framework, meaning that we need some way to allow a developer to write code to respond to menu events without having access to the menu code itself. We can do this by allowing the developer to write the commands and assign them to the Invokers (the menu items), without having to change the Invokers. Also, with menus we DO have the situation where we might want to swap around the commands that an Invoker is invoking.

For example, we might have a File/New menu item. This might create a different sort of ‘new’ item depending on what screen the application was displaying. If the application was displaying a report it might create a new report; if the application was displaying a list of users it might create a new user; and so on. We could set this up so that the menu item was given a Command object and simply invoked it when File/New was selected. We could then have CreateNewReportCommand and CreateNewUserCommand objects that the client code would give to the menu item as the screens in the application changed. The menu itself wouldn’t then need any business logic, nor would the code behind the screen it was hosted on.

.NET Delegates, .NET Events and the Command Pattern

It’s also worth bearing in mind that in many ways a simple use of a .NET delegate is a Command pattern, albeit a cumbersome one. The delegate itself is the command. It points to one or more methods in classes which are our Receivers. There will be some code to create the delegate and point it at the methods, which is the Client. Finally there will be some code to invoke the delegate (via the Invoke method), which is our Invoker.

Similarly .NET events, which are just special sorts of delegates, can be viewed as an implementation of the Command pattern.

This is fine, and of course very useful. But as we will see in part 10 the CAB gives us a more explicit way of using the pattern which is both simple and powerful.

.NET Menu Systems and the Command Pattern

Menu systems are a key use for the Command pattern as far as the Gang of Four are concerned. Normally in the .NET framework we use events for hooking up menu and toolbar items to underlying code. As discussed above, this can be regarded as an implementation of the Command pattern. However, the CAB implementation of the Command pattern is specifically intended to be used for menu systems and to replace the normal approach. We will examine the benefits it gives in part 10.

References

Data and Object Factory Page on the Command Pattern
http://www.dofactory.com/Patterns/PatternCommand.aspx

‘Gang of Four’ Book: Design Patterns: Elements of Reusable Object-Oriented Software
http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612/ref=sr_1_1/104-5057575-3250306?ie=UTF8&s=books&qid=1185705878&sr=1-1

‘Head First Design Patterns’ (excellent book, although Java-based):
http://www.amazon.com/Head-First-Design-Patterns/dp/0596007124/ref=pd_bbs_sr_3/104-5057575-3250306?ie=UTF8&s=books&qid=1185706020&sr=1-3

September 9, 2007

Creating and Using Services in the CAB (Introduction to the CAB/SCSF Part 8)

Introduction

Part 7 of this series of articles gave us a general introduction to services in the CAB. This article will go into more detail on the various ways we can create and use such services.

Ways of Creating a Service

We start with the various ways services can be created. This can be done with the various ‘Add’ methods, with XML configuration files or by using the ‘Service’ attribute.

Ways of Creating a Service (1) – Add Methods

In the basic example in part 7 we used the AddNew method to create a service:

            RootWorkItem.Services.AddNew<MyService>();

We have seen this before: it both instantiates the object and adds it to the collection. As before, we can also add objects that already exist to the Services collection with the Add method.

The Services collection also has an ‘AddOnDemand’ method. If we use this in place of AddNew in the example in part 7 the service does not immediately get created (the MyService class is not instantiated). Instead a placeholder is added to the Services collection until such time as some client code retrieves the service (using the same syntax as before). When this happens the service object will get instantiated so that it can be used. This example shows this:

            // Use AddOnDemand to set up the service: the MyService constructor
            // is not called
            RootWorkItem.Services.AddOnDemand<MyService>();
            // When we dislay the Services collection we can see there's a placeholder
            // for MyService in there
            DisplayWorkItemCollections(RootWorkItem);
            // Only when we use .Get to retrieve the service is MyService actually
            // instantiated (note we have code in MyService to show when the constructor
            // is called by writing to the Output window)
            UseMyService();
            // Now our Services collection has a fully fledged MyService service available
            DisplayWorkItemCollections(RootWorkItem);

There are also Contains and Remove methods on the Services collection. Remember we can only have one service of a given type: if a service already exists and we want to replace it these methods can be useful.

Ways of Creating a Service (2) – XML Configuration File

It is also possible to create services using the app.config file. To do this in our simple example we just take out the line:

            RootWorkItem.Services.AddNew<MyService>();

Then in an App.Config file we add a ‘services’ section with an ‘add’ element to a CompositeUI config section as below:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
      <section name="CompositeUI" type="Microsoft.Practices.CompositeUI.Configuration.SettingsSection, Microsoft.Practices.CompositeUI"  allowExeDefinition="MachineToLocalUser" />
    </configSections>
  <CompositeUI>
    <services>
      <add serviceType ="Shell.MyService, Shell" instanceType ="Shell.MyService, Shell" />    
    </services>
  </CompositeUI>
</configuration>

The code for this is available.

In general I’m not a fan of writing code in XML if there are proper C# alternatives. Here the XML is certainly less transparent than the one-line C# equivalent, and as usual debugging becomes more difficult with XML. However, one potential advantage of using the configuration file is that we could in theory change our service at runtime without having to recompile the code.

Ways of Creating a Service (3) – the Service Attribute

As mentioned previously, we can create a service simply by decorating our concrete class with the ‘Service’ attribute. We can register the service with a separate interface (as in the section ‘Splitting the Interface from the Implementation’ in part 7) by providing a positional type parameter. We can also make our service one that gets added on demand to the Services collection by adding a named boolean parameter called ‘AddOnDemand’. These attributes are illustrated below:

    [Service(typeof(IMyService), AddOnDemand=true)]
    public class MyService : IMyService
    {
        public string GetHello()
        {
            return "Hello World";
        }
    }

If we declare our service class in this way we have no need to explicitly add it to the Services collection before using it. There’s also no need to explicitly instantiate the class. Just adding the attribute ensures that when the code runs the service will get set up. The code showing this working is available.

Why the Service Attribute is Unusual

The ‘Service’ attribute is in some ways quite different from other attributes we’ve seen used with the CAB. Most CAB attributes only work for objects that are already in a collection associated with a WorkItem. For examples see the discussion about ComponentDependency, ServiceDependency and CreateNew in part 5 of this series of articles. In particular CreateNew will only work on a setter if that setter is in an object that is already in a WorkItem collection. We can’t just put CreateNew in any old class and expect it to work.

In contrast the Service attribute will work with ‘any old class’, provided it’s in a module (see part 1 for a discussion of modules). The Service attribute really couldn’t work any other way. The attribute when applied to a class is telling the CAB to add an object of that type to the Services collection of the WorkItem. It wouldn’t make much sense if it only worked if the object was already in a collection of the WorkItem.

Where the CAB is Looking for the Service Attribute

So how does the CAB find these Service objects and use them? The answer is that when a module loads the CAB uses reflection to find all public classes in the assembly which have the ‘Service’ attribute applied. All of these classes get instantiated and added in to the Services collection of the root WorkItem of the CAB application.

Note that the CAB only scans assemblies that are explicitly listed as modules (in ProfileCatalog.xml usually). An assembly won’t get scanned if it’s just referenced from a module project.

Drawbacks of the Service Attribute

One problem with this is that we don’t have a lot of control over where the service gets created. Our new service always gets added to the root WorkItem, meaning we can’t create services at a lower level in the WorkItem hierarchy. Another problem is that we have no control over when our service is created: in particular we have no way of ensuring that our services are created in a specific order.

My personal opinion is that setting up services using the Service attribute can be a little confusing. The services appear magically as if from nowhere. If we explicitly create the service and add it to the appropriate WorkItem we have more control and what we are doing is more transparent.

Ways of Retrieving a Service

There are two main ways of retrieving a service. We have already seen examples of these, but a recap is given below.

Ways of Retrieving a Service (1) – Get Method

In the basic example in part 7 we used the Get method of the Services collection to retrieve MyService. For example, the code below is taken from the final example (‘Splitting the Interface from the Implementation’):

        private void UseMyService()
        {
            IMyService service = RootWorkItem.Services.Get<IMyService>();
            System.Diagnostics.Debug.WriteLine(service.GetHello());
        }

Ways of Retrieving a Service (2) – Dependency Injection

We can also retrieve a service via dependency injection by using the ServiceDependency attribute. We saw some examples of this in part 5.

To set up a service in a class we can decorate a setter of the appropriate type in a class with the ServiceDependency attribute. The class can then use the service:

    public class ServiceClient
    {
        private IMyService service;
 
        [ServiceDependency]
        public IMyService Service
        {
            set
            {
                service = value;
            }
        }
 
        internal string UseMyService()
        {
            return service.GetHello();
        }
    }

As discussed previously, the CAB looks for the ServiceDependency attribute when an object of type ServiceClient is added to one of the WorkItem collections. When that happens the CAB looks for a service of type IMyService in the Services collection of the WorkItem. When it finds one it retrieves it and sets it on the ServiceClient object by calling the setter.

So to set up this class we need to ensure that an IMyService service has been created, and then we can just create a ServiceClient object in our WorkItem:

            // Create the service
            RootWorkItem.Services.AddNew<MyService, IMyService>();
 
            // Add a ServiceClient object to our Items collection:
            // this causes the CAB to inject our service into the ServiceClient
            // because it has a setter decorated with ServiceDependency
            ServiceClient serviceClient = RootWorkItem.Items.AddNew<ServiceClient>();

Now we can call the service on the ServiceClient object:

            System.Diagnostics.Debug.WriteLine(serviceClient.UseMyService());

The code for this example is available.

We can also use the ServiceDependency attribute with constructor injection as discussed in part 6. This is a simple change to the ServiceClient class in the example above:

    public class ServiceClient
    {
        private IMyService service;
 
        public ServiceClient([ServiceDependency]IMyService service)
        {
            this.service = service;
        }
 
        internal string UseMyService()
        {
            return service.GetHello();
        }
    }

The code for this example is also available.

Finding Services Higher Up the Hierarchy

As already discussed, if the CAB can’t find a service in the Services collection of the current WorkItem it will look in the Services collections of parent WorkItems. We can illustrate this by adding a new WorkItem called ‘testWorkItem’ to our basic example from part 7. We still add our service to the RootWorkItem:

        WorkItem testWorkItem = null;
        protected override void AfterShellCreated()
        {
            testWorkItem = RootWorkItem.WorkItems.AddNew<WorkItem>();
 
            RootWorkItem.Services.AddNew<MyService, IMyService>();
            UseMyService();
            DisplayWorkItemCollections(RootWorkItem);
        }
 
        private void UseMyService()
        {
            IMyService service = testWorkItem.Services.Get<IMyService>();
            System.Diagnostics.Debug.WriteLine(service.GetHello());
        }

When we come to use the service in UseMyService (immediately above) we try to retrieve it from the testWorkItem. The code still works even though the service isn’t in testWorkItem’s Services collection: the CAB retrieves it from the parent RootWorkItem. Once again the code for this example is available.

Services Not Found

If the CAB attempts to retrieve a service and can’t find it at all it usually does not throw an exception. It simply returns null. Consider the changes to our basic example from part 7 below:

        protected override void AfterShellCreated()
        {
            //RootWorkItem.Services.AddNew<MyService, IMyService>();
            UseMyService();
            DisplayWorkItemCollections(RootWorkItem);
        }
 
        private void UseMyService()
        {
            // There's no IMyService available, so the CAB sets service = null below
            IMyService service = RootWorkItem.Services.Get<IMyService>();
            // We get a NullReferenceException when we try to use the service
            System.Diagnostics.Debug.WriteLine(service.GetHello());
        }

Here we have commented out the line that creates the service so it never gets created. As a result the call to ‘Get’ the service returns null, and we get a NullReferenceException when we try to call GetHello.

This may not be the behaviour we want. It may be better to throw an exception as soon as we know the service does not exist before we attempt to use it. Fortunately the Get method is overloaded to allow us to do this. It can take a boolean argument, EnsureExists, which if set to true throws a ServiceMissingException immediately the service cannot be retrieved:

IMyService service = RootWorkItem.Services.Get<IMyService>(true);

The code for this example is available.

Conclusion

This article has shown us how to use services in the CAB in some details. The next two articles will examine commands in the CAB: part 9 will recap the Command design pattern, and part 10 will explain how this is implemented for menus using commands in the CAB.

September 8, 2007

Introduction to Services in the CAB (Introduction to the CAB/SCSF Part 7)

Introduction

Part 6 of this series of articles concluded our discussion of dependency injection in the CAB.

This article and part 8 of the series will discuss services in the CAB in some more detail. This article discusses services in general terms, whilst part 8 will show in detail the various ways of creating and using services.

What is a ‘Service’?

You probably already have an intuitive idea of what a ‘service’ is in computer programming. Wikipedia defines a service in the context of a Service-oriented architecture as ‘a discretely defined set of contiguous and autonomous business or technical functionality’. The CAB documentation defines a service as ‘a supporting class that provides functionality to other components in a loosely coupled way’. CabPedia has a good definition:

‘Services allow easy access to a chunk of functionality that may be used frequently throughout an application. Error handlers, loggers and the event broker are good examples of functionality that can be exposed as a service.’

So think of a service as a chunk of related functionality. In the CAB each service is exposed through one class (and maybe an associated interface) that provides a gateway into the functionality.

We have already seen how to use CAB services in earlier articles in this series. Part 2 described how one of the collection classes on a WorkItem is the Services collection. Part 5 showed how we can inject a service (which is just any item in the Services collection) by using a setter with a ServiceDependency attribute. We saw that we can inject the WorkItem itself in this way. This is because a WorkItem is automatically a ‘service’ in its own Services collection.

The Services Collection versus the Items Collection

Part 5 of this series of articles also touched on the fact that the Services collection on a WorkItem has some important differences with the Items collection. This is separate from the fact that the intent of the two collections is different: services are meant to be objects that expose chunks of related functionality, whereas items are just any objects that we want to be able to access through the WorkItem.

The differences between the collections can be confusing so I’ll start this discussion by comparing the two collections.

Services vs Items (1): Unique Types

The most obvious of these conceptual differences is the fact that the Services collection can only ever contain one object of a given type. If we attempt to add a second service of the same type to a Services collection we get an ArgumentException with message ‘A service of this type already exists’.

In contrast, the Items collection of a WorkItem can contain multiple objects of the same type. To accommodate this all objects added to the Items collection are assigned a unique string ID, either by the user explicitly, or by the CAB implicitly (a random GUID is assigned).

However, this means that if we want to access a specific object in the Items collection we have to know its ID. Hence the ComponentDependency attribute, which injects an object from the Items collection, needs an ID passed as an argument.

We don’t need an ID to access an object in the Services collection. Because we can identify a service uniquely by its type the ServiceDependency attribute can be used to inject a service without the need for any ID.

Services vs Items (2): Searching the Hierarchy

Another difference between the Services collection and the Items collection is what happens if we request a specific object from the collection and the CAB can’t find it in the WorkItem’s collection. When trying to retrieve a service the CAB will then search in any parent WorkItem’s Services collections for the object, and return it if found. With the Items collection the CAB will just return null if the object cannot be found in the specific Items collection for the WorkItem.

Basic Service Example without Dependency Injection

A simple example of how to create and use a service without using dependency injection is available. The ‘service’ here is just one class (MyService) with one method (GetHello) that returns the string “Hello World”:

    public class MyService
    {
        public string GetHello()
        {
            return "Hello World";
        }
    }

We can make this simple class into a CAB service by adding it to the Services collection of a WorkItem. In this case we add it to the Services of the RootWorkItem in AfterShellCreated:

        protected override void AfterShellCreated()
        {
            RootWorkItem.Services.AddNew<MyService>();
            UseMyService();
            ...

We use the service in routine UseMyService. Here we retrieve the service using the Get method of the Services collection, telling it the type of the service we want to retrieve. We then call our method and output the results to the Output window:

        private void UseMyService()
        {
            MyService service = RootWorkItem.Services.Get<MyService>();
            System.Diagnostics.Debug.WriteLine(service.GetHello());
        }

It’s as simple as that. The full code also outputs all of the services that have been set up in the application, and shows that our MyService service is in there. You can see that there are a surprisingly large number of services set up by default by the CAB even in a simple application of this kind:

SERVICES:
[Microsoft.Practices.CompositeUI.WorkItem, Microsoft.Practices.CompositeUI.WorkItem]
[Microsoft.Practices.CompositeUI.Services.ICryptographyService, Microsoft.Practices.CompositeUI.Collections.ServiceCollection+DemandAddPlaceholder]
[Microsoft.Practices.CompositeUI.ITraceSourceCatalogService, Microsoft.Practices.CompositeUI.TraceSourceCatalogService]
[Microsoft.Practices.CompositeUI.Services.IWorkItemExtensionService, Microsoft.Practices.CompositeUI.Services.WorkItemExtensionService]
[Microsoft.Practices.CompositeUI.Services.IWorkItemTypeCatalogService, Microsoft.Practices.CompositeUI.Services.WorkItemTypeCatalogService]
[Microsoft.Practices.CompositeUI.IWorkItemActivationService, Microsoft.Practices.CompositeUI.SimpleWorkItemActivationService]
[Microsoft.Practices.CompositeUI.Services.IAuthenticationService, Microsoft.Practices.CompositeUI.Services.WindowsPrincipalAuthenticationService]
[Microsoft.Practices.CompositeUI.Services.IModuleLoaderService, Microsoft.Practices.CompositeUI.Services.ModuleLoaderService]
[Microsoft.Practices.CompositeUI.Services.IModuleEnumerator, Microsoft.Practices.CompositeUI.Services.FileCatalogModuleEnumerator]
[Microsoft.Practices.CompositeUI.Commands.ICommandAdapterMapService, Microsoft.Practices.CompositeUI.Commands.CommandAdapterMapService]
[Microsoft.Practices.CompositeUI.UIElements.IUIElementAdapterFactoryCatalog, Microsoft.Practices.CompositeUI.UIElements.UIElementAdapterFactoryCatalog]
[Microsoft.Practices.CompositeUI.WinForms.IControlActivationService, Microsoft.Practices.CompositeUI.WinForms.ControlActivationService]
[Shell.MyService, Shell.MyService]

Splitting the Interface from the Implementation

As we all know, for services it is considered good practice to separate our interface from our implementation. This allows us to vary the way the service is implemented without having necessarily to change the interface and thus affect client code. This can be important in a composite smart client application where different teams may be working on different parts of the application.

This can be very easily done for our basic example. We simply set up an interface with our method signature in it:

    public interface IMyService
    {
        string GetHello();
    }

We then implement this interface on our MyService class:

    public class MyService : IMyService
    {
        public string GetHello()
        {
            return "Hello World";
        }
    }

Another change we need to make is how we create the service. We want the type associated with it in the Services collection to be IMyService, but clearly we need to tell the CAB that it is creating an object of type MyService (it can’t just instantiate the interface). The syntax for this is as below:

            RootWorkItem.Services.AddNew<MyService, IMyService>();

The UseMyService method now retrieves the service using the IMyService interface. It doesn’t need to know about the MyService class:

        private void UseMyService()
        {
            IMyService service = RootWorkItem.Services.Get<IMyService>();
            System.Diagnostics.Debug.WriteLine(service.GetHello());
        }
 

These are the only changes that need to be made. The code for this example is available.

Conclusion

That concludes our initial introduction to services in the CAB. Part 8 will show the various options for creating and using services in more detail.

References

CabPedia page on Services
http://www.cabpedia.com/index.php?title=Services

Wikipedia on Services in an SOA
http://en.wikipedia.org/wiki/Service_%28Systems_Architecture%29

September 4, 2007

Constructor Injection in the CAB (Introduction to the CAB/SCSF Part 6)

Introduction

Part 3 of this series of articles described the different types of dependency injection that we can use in general. These are setter injection, constructor injection and interface injection.

Part 5 showed how dependency injection works in the CAB. The examples given there exclusively used setter injection. In general we don’t use interface injection in CAB projects, but we can use constructor injection. This short article will show you how.

Constructor Injection Example

As is fairly obvious, constructor injection injects your dependencies in a constructor rather than a setter. To do this in the CAB we once again use attributes.

We can return to our original example of setter injection and rework it to use constructor injection. To do this we add a constructor to our Component2 class as below, and we remove the setters we were using previously (they are commented out below):

    public class Component2
    {
        private Component1 component11;
        //[ComponentDependency("FirstComponent1")]
        //public Component1 Component11
        //{
        //    set { component11 = value; }
        //}
 
        private Component1 component12;
        //[CreateNew]
        //public Component1 Component12
        //{
        //    set { component12 = value; }
        //}
 
        [InjectionConstructor]
        public Component2([ComponentDependency("FirstComponent1")]Component1 component, [CreateNew]Component1 component2)
        {
            component11 = component;
            component12 = component2;
        }
    }
 

The constructor will inject the same dependencies as the setters did previously if we create Component2 with the AddNew method of a WorkItem’s Items collection as below:

RootWorkItem.Items.AddNew<Component2>("Component2");

When the CAB creates a component with AddNew it looks for a constructor decorated with the InjectionConstructor attribute. If it finds one it calls that constructor, and injects dependencies via the constructor parameters as shown. It applies the usual rules if any of the constructor parameters are decorated with the CreateNew, ServiceDependency or ComponentDependency attributes.

The code for this example is available.

Constructor Injection Issues

Note that if there’s only one constructor in the class you don’t actually need the InjectionConstructor attribute. The CAB assumes you mean to use that one constructor as the injection constructor. Our example above will work without the attribute. If you have more than one constructor in the class you do need the attribute, and in general it’s probably good practice to include the attribute if you are using constructor injection.

Note also that in the original example in part 5 we created the Component2 instance with a standard ‘new’ keyword and then added it to the items collection:

            Component2 component2 = new Component2();
            RootWorkItem.Items.Add(component2);

If we do this with our new Component2 the injection will not work. In fact the code won’t even compile as we no longer have a constructor that doesn’t take any arguments. Even if we put a constructor with no arguments into Component2 we’re clearly not going to get any dependency injection as we are not creating the component with the CAB and the standard ‘new’ keyword doesn’t know how to do constructor injection.

Finally it’s worth noting that if you don’t put any attribute on an argument of an injection constructor the CAB treats it as if it had a ServiceDependency attribute. That is, it tries to inject a service of the appropriate type. If there’s no such service it creates a new one and adds it to the Services collection. This is NOT the behaviour you get with the ServiceDependency attribute: if you apply the ServiceDependency attribute and there’s no such service you get a ServiceMissingException when you try to create the new object.

Setter Injection vs Constructor Injection

Whether you use setter injection or constructor injection is really a personal choice. There isn’t much to choose between them in terms of functionality. As we’ve seen if you create your object with the ‘new’ keyword initially and then add it to a CAB collection you can’t use constructor injection. Also arguably the syntax for the constructors is a little cumbersome. But normally your CAB objects will be created and added to CAB collections with the AddNew keyword or something equivalent. In this case both setter injection and constructor injection inject the dependencies on creation of the object, and the two types of injection are functionally equivalent.

Conclusion

We’ve now covered dependency injection in the CAB in some detail. Part 7 of this series will discuss services in the CAB.

The Shocking Blue Green Theme Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 80 other followers