YOUR FEEDBACK
Adobe Flex 2 - Answering Tough Questions About Enterprise Development
A Correct Person wrote: Denis Roebrt commented on the 21 Aug 2006 "Tough Que...

SYS-CON.TV
TOP MICROSOFT .NET LINKS


Dependency Injection and Microsoft Windows Forms
A walkthrough using Microsoft's Composite UI Application Block

Digg This!

Page 2 of 2   « previous page

Create the Second Module
The second module, which will hold the details, will be structurally identical to the first. Add a new Class Library project to the solution and name it "ListViewerModule." Create a user control called "ListViewerListBox.cs," a WorkItem class called "ListViewer-WorkItem," and a ModuleInit class called "ListViewerInit," copying the logic from the corresponding classes in the ListOrganizerModule project. The only difference between the modules at this point will be the naming, and the size/shape of the user control, which should be sized to fit in the viewerWorkspace on our ShellForm.

Inject the Modules into the Shell
The solution should now build and run, but the ShellForm will still be empty. Our modules know where they should live on the shell, so we have to tell the shell how to load them up. Here is where we first see how loosely coupled the whole application is - the loading of the modules into the shell is done completely through the use of a configuration file. Neither the shell nor the modules has a reference to one another.

First, modify the project properties for both module projects so that the output directory is the shell's output directory. This property can be found in the properties page for each module on the "Build" tab, toward the bottom. Modify the output directory for the assembly to be:

..\DataViewerShell\bin\Debug\

Next, create a new XML configuration file in the Shell project to specify the module. The XML file should be named "ProfileCatalog.xml," and is a listing of the available "profiles" for the shell application. Each profile is a distinct set of controls that are plugged into the shell. The format of the XML can be seen in Listing 4. Be sure to set the "Copy to Output Directory" property of the XML file in Visual Studio to "copy if newer" or "copy always."

Now you should be able to build and run the solution, and the two list boxes should display in their appropriate positions. Stepping through the process of loading the application, it works like this:

  1. The static void Main() method on the ShellApplication is invoked. This method calls Run() on a new instance of ShellApplicaiton.
  2. ShellApplication inherits from FormShellApplication<TWorkItem, TShell>, which sets up the default WorkItem and the shell form itself.
  3. FormShellApplication<TWorkItem, TShell> inherits (several levels down) from the class CabApplication<TWorkItem>. The Run() method on this class calls a private method called LoadModules().
  4. LoadModules() loads up the names of the module assemblies from the ProfileCatalog XML configuration file.
  5. Each module is initialized, the ParentWorkItem property is set (thanks to the ServiceDependency attribute), and the Load() method is called.
  6. The Load() method on each module creates a new instance of its respective child WorkItem in the ParentWorkItem's collection of WorkItems, and then calls the Run() method on the new instance of the child WorkItem.
  7. The child WorkItem tells the ParentWorkItem to display a new instance of its ListBox control in the appropriate workspace.
Note that the shell doesn't have any reference to either module assembly. It doesn't care what modules it loads up; as long as they are modules, it will load them. Likewise, the modules don't care what shell they go into, as long as the shell has a workspace with the correct name. The property "ParentWorkItem" is initialized because it has an attribute that identifies it as a dependency. Everything is late-bound and as loosely coupled as it can be.

Load the Browser List Box
Next we need to add functionality to the application. We want to use the application to view shopping lists. For simplicity, we will load the data from an XML file. Create a new XML file in the DataViewerShell project and name it "Lists.xml." The contents of the XML file should be in nodes as shown in Listing 5. Set the "Copy to Output Directory" property to "copy if newer" or "copy always."

For this demo, we will be loading the XML in the Load event for the ListBox. Open the ListOrganizerListBox user control, and add a new Load event handler. Load up the XML file into a new untyped DataSet and bind it to the control as shown in Listing 6. Build and run the application - it should now show the items of type "List" in the "Lists" node in the module on the left side of the shell (see Figure 3).

Link the Modules Using Publish/Subscribe
The final step in the walkthrough is to wire up the application so that the second list box shows the contents of the selected item in the first list box. We will use CAB's implementation of the Publish/Subscribe design pattern to do this. This pattern is relatively straightforward; events can be "published" globally, and event handlers can "subscribe" to these events. Whenever the event is fired, all subscribing event handlers that are running in the publication context will get the notification. In CAB, this functionality is handled by an EventBroker.

To publish the OnClick event in the ListOrganizerListBox, we need to do two things. First, add a new System.EventHandler<TEventArgs> delegate for subscribing event handlers. For the TEventArgs type, specify Microsoft.Practices.CompositeUI.Utility.DataEventArgs<string>, which we will use to hold the string value of the item selected in the list box. Mark this delegate with the Microsoft.Practices.CompositeUI.EventBroker.EventPublicationAttribute and pass in a descriptive name for the published event. The delegate declaration should look something like this:

[EventPublication("topic://ListOrganizer/ListSelected")]
public event EventHandler<DataEventArgs<string>> ListSelected;

Now, add a normal event handler to the ListBox Click event. Pass the selected list to the delegate as a parameter. The complete code for the delegate and the Click event handler is shown in Listing 7.

Finally we move to ListViewerList-Box, where we need to subscribe to the ListSelected event publication. Open the code for the ListViewerListBox control and add a new event handler method called OnListSelected, with parameters object sender and DataEventArgs<string> args. This method signature will work with the delegate method to which it is subscribing. Mark the method with the Microsoft.Practices.CompositeUI.EventBroker.EventSubscriptionAttribute, passing in the same descriptive name as you used in the EventPublication attribute.

In the body of the method, load up a DataSet from the XML, filter the results based on the parameter coming in from the event, and bind to the resulting nodes. Obviously the loading of the data should be done more efficiently in a production application; this demo is simplified for clarity. Compile and run the application. It should now look like Figure 4 and work as designed, with selection of an item in the left ListBox causing the right ListBox to display its contents.

Conclusion
Most of the Dependency Injection functionality included in CAB is provided by the Microsoft.Practices.ObjectBuilder assembly. This assembly is not in the CompositeUI namespace for a reason - the ObjectBuilder is slated to be used by many upcoming patterns & practices application blocks. This includes the next version of the Enterprise Library, which is a set of interrelated application blocks that provide common services used by many types of applications.

Dependency Injection comes with a learning curve, but it is a pattern that is gaining popularity. As CAB has proven, Dependency Injection is very effective in a Windows Forms application framework. It provides true reusability of all components of a Windows Forms application.

Resources


Page 2 of 2   « previous page

About Guy Starbuck
Guy Starbuck is a senior application architect for Stericycle, Inc. He has been working in the software industry for over nine years. Guy lives in Arlington Heights, IL with his wife and son.

Assen Bogdanov wrote: Hi, I read and implemented the Dependency Injection article and it works beautifully! I have a question. How does one link the various tab pages as opposed to just the first one? By providing just the control name, e.g. WorkIt em.Workspaces["tabWorkspa ce"], everything always goes to the first TabPage. What would be the way to control which TabPage gets the link? Thank you Regards Assen Bogdanov
read & respond »
realworldsa.dotnetdevelop ersjournal.com wrote: Trackback Added: Dependency Injection, Generics, Enterprise Library 2.0, Composit; The Composite UI Application Block and the Enterprise Library 2.0 use Generics extensively and introduce dependency injection through the P&P ObjectBuilder framework.If you plan on using the Composite UI Application Block or the Enterprise Library 2.
read & respond »
SYS-CON Brazil News Desk wrote: Dependency Injection and Microsoft Windows Forms. The patterns & practices group at Microsoft provides architectural and design guidance for users of Microsoft technologies. Part of the way they do this is by producing and distributing packages called 'application blocks.' An application block consists of a functional subsystem or software framework that can be valuable in several ways. Application blocks can be implemented in many types of applications as time-saving subsystems. They are also reference examples of software designed and developed using the best practices of Microsoft architecture. Application blocks are freely distributed with all source code and documentation.
read & respond »
SYS-CON Belgium News Desk wrote: The patterns & practices group at Microsoft provides architectural and design guidance for users of Microsoft technologies. Part of the way they do this is by producing and distributing packages called 'application blocks.' An application block consists of a functional subsystem or software framework that can be valuable in several ways. Application blocks can be implemented in many types of applications as time-saving subsystems. They are also reference examples of software designed and developed using the best practices of Microsoft architecture. Application blocks are freely distributed with all source code and documentation.
read & respond »
SYS-CON Germany News Desk wrote: Dependency Injection and Microsoft Windows Forms The patterns & practices group at Microsoft provides architectural and design guidance for users of Microsoft technologies. Part of the way they do this is by producing and distributing packages called 'application blocks.' An application block consists of a functional subsystem or software framework that can be valuable in several ways. Application blocks can be implemented in many types of applications as time-saving subsystems. They are also reference examples of software designed and developed using the best practices of Microsoft architecture. Application blocks are freely distributed with all source code and documentation.
read & respond »
.NET News Desk wrote: Dependency Injection and Microsoft Windows Forms. The patterns & practices group at Microsoft provides architectural and design guidance for users of Microsoft technologies. Part of the way they do this is by producing and distributing packages called 'application blocks.' An application block consists of a functional subsystem or software framework that can be valuable in several ways. Application blocks can be implemented in many types of applications as time-saving subsystems. They are also reference examples of software designed and developed using the best practices of Microsoft architecture. Application blocks are freely distributed with all source code and documentation.
read & respond »
MICROSOFT .NET LATEST STORIES
Icahn Moves To Force Microsoft & Yahoo Together
Corporate raider Carl Icahn started his proxy fight for control of Yahoo this morning, beginning with the classic Icahn opening, the letter of reproach to the Yahoo board telling them they have acted 'irrationally and lost the faith of shareholders and Microsoft.'
IBM, Microsoft & Google Eras of Computing
By now it is conventional wisdom to say that there was an IBM Era of computing, then a Microsoft Era, and now we are in the Google Era. In this post, I will explain why Microsoft was not the 'next IBM' and why Google is not the 'next Microsoft' - there are significant qualitative diffe
Book Review: ASP.NET 2.0
ASP.NET developers are bored with traditional books that outline concepts in a lengthy way. These books are good if you like to learn the features in a detailed manner. However, by the time the book is read, a new version will be released. Hence, many learners including myself prefer s
3rd International Virtualization Conference & Expo: Themes & Topics
From Application Virtualization to Xen, a round-up of the virtualization themes & topics being discussed in NYC June 23-24, 2008 by the world-class speaker faculty at the 3rd International Virtualization Conference & Expo being held by SYS-CON Events in The Roosevelt Hotel, in midtown
"RIA" vs "Rich Client Platform": The Term Is Now Up for Debate
'RIA' is slowly fading in terms of its definition. When I first started the RIA Evangelism role in Microsoft, I had this nagging feeling that the term RIA was just all over the place. Depending on which technology you are backing and which stream of alliance you uphold, the truth is th
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS
SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

SYS-CON FEATURED WHITEPAPERS

ADS BY GOOGLE
BREAKING NEWS FROM THE WIRES
Strangeloop Networks Selected for Red Herring 100 North America 2008
Strangeloop Networks (TM) Inc., a leading provider of solutions that accelerate dynamic web