Geeks With Blogs

News
View Szymon Kobalczyk's profile on LinkedIn

Szymon Kobalczyk's Blog A Developer's Notebook

Next important part of Composite UI, if not the most significant, is the WorkItem. According to documentation it “a run-time container for components that are working together to fulfill a use case. These components may consist of SmartParts, controllers, services, UIElements, and other components.” So if we look at Outlook as example here, we have use cases like: browsing email, scheduling appointments or looking up contacts. As I understand, these would correspond to main WorkItems of EmailWorkItem, CalendarWorkItem and ContactWorkItem. Of course each of them can have child WorkItems like ComposeEmailWorkItem or EditContactWorkItem. What's more there can be also some cross references like you can call “add contact” use case from “browse emails”.

What is important here is that WorkItem is the only component that has access to all other components mentioned above. Visibility of all other elements to one another is limited and basically all communication goes through the WorkItem. This architecture nicely supports two most common design patterns for moder UI: Model-View-Controller (MVC) and Model-View-Presenter (MVP). The purpose of both patterns is to separate the user interface logic from the business logic. The primary difference between them is that MVC requires events that are exposed from the model to update the view, whereas MVP depends on the presenter to update the view directly. Diagram below compares the two patterns.

Model-View-Controller vs. Model-View-Presenter

Here Forms, SmartParts and user controls play the role of View, and WorkItems hold state and other data that form the Model. To implement the Controller we can derive from the base class with the same name that contains references to owning WorkItem and associated State. 


Lets get back to the PetShop sample and try to discover what WorkItems exist here. I would try to group the pages (now SmartParts) into following three functional areas:

  • Inventory - Category, Items, ItemDetails, Search, 
  • Account - EditAccount, CreateAccount, SignIn, SignOut,
  • Order - ShoppingCart, Checkout, OrderBilling, OrderProcess, OrderShipping.

I will start with the InventoryWorkItem because it is first thing we would probably use in the PetShop. The Category, Items and ItemDetails views are all similar - they just show bunch of data for given identifier. For first two I would use DataGridView and a BindingSource and on the last one will just throw some labels. The interesting part is how to assign the identifier to the corresponding view. For this I would implement methods in InventoryWorkItem that create the view, put it into the workspace and order it to load data for given identifier. Here is one such method:

public void ShowCategory(string categoryId)

{

CategoryView categoryView = this.SmartParts.AddNew<CategoryView>();

this.Workspaces["content"].Show(categoryView);

categoryView.LoadData(categoryId);

}

Methods ShowProduct and ShowItemDetails are implemented in similar way. But who would call these methods? Looking at the Inventory use case we have a scenario that selecting a product in a category would open a list of items for that product and then selecting one such item would show its details. Therefore I would turn one of the grid columns on both views into links and add handlers for CellContentClick event. But how do I access the WorkItem from the view? From the above diagrams I see that for this I should create a Controller. For now it would simply forward my calls to the InventoryWorkItem.

public class InventoryController : Controller

{

public new InventoryWorkItem WorkItem

{

get { return base.WorkItem as InventoryWorkItem; }

}

public void ShowProduct(string productId)

{

this.WorkItem.ShowProduct(productId);

}

public void ShowItemDetails(string itemId)

{

this.WorkItem.ShowItemDetails(itemId);

}

}

Now I only need to create instance of this Controller for each view. We can do it quite easily with the power of dependency injection:

private InventoryController _inventoryController;

 

[CreateNew]

public InventoryController InventoryController

{

get { return _inventoryController; }

set { _inventoryController = value; }

}

The CreateNew attribute instructs the ObjectBuilder to instantiate and initialize the InventoryController when the SmartPart is created. How convenient.

One last thing is to actually create and Run the InventoryWork item. I would do this whenever user selects one of the categories from the default page or the navigation bar. And now I realize that I also need a root WorkItem to maintain the main page and other WorkItems. I create a ShellWorkItem and change the declaration of ShellApplication class. Now I can also move the code that loads the default page from application's AfterShellCreated to ShellWorkItem's OnRunStarted method. Finally, here is the code to run the InventoryWorkItem when user selects a category:

public void ShowCategory(string categoryId)

{

InventoryWorkItem inventory = this.WorkItems.AddNew<InventoryWorkItem>("inventory");

inventory.Run();

inventory.ShowCategory(categoryId);

}

Ok. Now I will try to implement remaining views using what I've learned already. I won't be boring you with details until I start to use some new elements.

Posted on Monday, January 9, 2006 6:40 AM Development , Smart Client | Back to top


Comments on this post: Understanding Composite UI Application Block, Part III

# re: Understanding Composite UI Application Block, Part III
Requesting Gravatar...
I'm trying get a better idea of the purpose of the controller. It seems to me that the controller and the workitem have overlapping responsibilities. The documentation of CAB does not go into great detail of the controller. From what I understand the WorkItem is the manifestation of the Use Case and according to the documentation the Controller executes Business Logic. Using the controller as a pass-thru layer seems kind of pointless. If the WorkItem and Controller are separate then there must have reasons. What was the orginal intention of the controller? Any insight into this would help.

Thanks.
Phil
Left by Phil James on Mar 03, 2006 1:36 PM

# re: Understanding Composite UI Application Block, Part III
Requesting Gravatar...
Phil,
As you know Controller is part of the MVC pattern and is role there is to translate user interface gestures from the View to operations on the Model. Now, CAB takes this pattern to another level allowing to.. er... to COMPOSE these MVC blocks into one unit to fullfill some use case. And it has WorkItems in order to orchestrate these elements.

Another thing is that you don't have to use Controllers at all. You can just place your logic in your SmartParts and it will work as well. However it is good practice to take as much as possible logic from the GUI elements for example to help with testing.
But it's up to you to decide if you need it or not.

Please read my next post where I have another take on that matter.
Left by Szymon on Mar 03, 2006 6:56 PM

# re: Understanding Composite UI Application Block, Part III
Requesting Gravatar...
Hi and thanks in advance.
What if you have several views that must call the same controller. What's the best way to share information between the views and the controller?. Think of a Wizard where each view must keep some information that must be passed to the controller when the last view fires a Save All (via a button).

Left by FJ on Apr 25, 2006 10:21 PM

# re: Understanding Composite UI Application Block, Part III
Requesting Gravatar...
How would this work when you have a hierarchical model and view. For example a treeview?
Left by Simon Cropp on May 25, 2006 5:07 AM

# re: Understanding Composite UI Application Block, Part III
Requesting Gravatar...
There is a good article which explains these same concepts in further detail at:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/SCSFOverviewOfCompositeUIAppBlock.asp
Left by Matt Lynch on Oct 17, 2006 3:27 PM

# re: Understanding Composite UI Application Block, Part III
Requesting Gravatar...
I am new to CAB and is reading your blog with interest. I have couple of questions:

1) I downloaded your sample app (pet_shop)and noticed that I am missing a reference to SampleVisualizations. Where can I get it.

2) In one of your blogs, you indicated that I needed to download petshop. Should I use 3.2 or 4.0 ? Do I need to change anything in your sample code ?


Thanks
Left by Beginner on Nov 02, 2006 5:59 PM

# re: Understanding Composite UI Application Block, Part III
Requesting Gravatar...
You can get SampleVisualizations from CAB Workspace: http://www.gotdotnet.com/codegallery/releases/viewuploads.aspx?id=22f72167-af95-44ce-a6ca-f2eafbf2653c
or you can comment this line in config to disable it.

My sample currently works on PetShop 3.2. I had plans to upgrade to 4.0 but didn't finish it so far.
Left by Szymon on Nov 02, 2006 6:46 PM

# re: Understanding Composite UI Application Block, Part III
Requesting Gravatar...
Thanks the info. I will download 3.2 and try to understand the concepts of CAB.

I appreciate your time to share your experience in CAB.

I probably will have more questions. :-)


Thanks
Left by Beginner on Nov 02, 2006 7:48 PM

# re: Understanding Composite UI Application Block, Part III
Requesting Gravatar...
Hi Szymon,

I compiled and ran the app and encountered a problem. I tried to debug in VS 2005 and I believe that it is somewhere in DecryptDBConnectionString in FromBase64String. I tried to stepped into the code but it couldn't load the symbol. I tried to specify in
tool->options->debugging->Symbols
and add the following:
c:\SmartPetShop\Src\Utility\bin\Debug\PetShop.Utility.pdb

but it still say no symbols loaded in module windows.
Am I missing something ? It looks like it was loading from my C:\WINDOWS\assembly.


Thanks
Left by Beginner on Nov 03, 2006 11:52 PM

# re: Understanding Composite UI Application Block, Part III
Requesting Gravatar...
Hi Szymon,

I figuered out how to load the symbols. BTW, how do I find out the dependency of pershop.utility ? I couldn't remove petshop.utility because of some dependency ?


Thanks
Left by beginner on Nov 04, 2006 12:21 AM

# re: Understanding Composite UI Application Block, Part III
Requesting Gravatar...
Can you explain the purpose of SmartPartInfoProvider in DefaultPage and ProductView. It seems that you have class member decalred and new but never use it.
Left by Beginner on Nov 07, 2006 9:22 PM

# re: Understanding Composite UI Application Block, Part III
Requesting Gravatar...
This property is part of the interface and is generated automatically when you add SmartPartInfo component in designer. There is also bit of code you need to add on your own. Of course alternatively you can provide the SmartPartInfo manually when you construct the SmartPart and add it to the Workspace.
Left by Szymon on Nov 07, 2006 9:27 PM

# re: Understanding Composite UI Application Block, Part III
Requesting Gravatar...
I think there are some problems here:

The diagrams are a bit misleading. A user doesn't interact with a view. The user reads a view and interacts with a controller. A model is not just data. A model is an object model, data and methods, that represents business logic. The purpose of MVC is to separate these so that the business logic could be manipulated with any number of UIs.

My problem with the UI Application Block is that it doesn't seem to encourage such separation.

Mark Seeman shows and example of his attempt to do so in "EasyUI Testing..." which said,

"The Controller is not your business logic layer, but rather it is a thin adapter over the business logic layer which basically intercepts calls from the user interface in order to implement abstraction and state management...."

and then had to "hack" the UI elements to make the unit tests work.

In my mind, this was a demonstration of what seems to be wrong with UI Application Block's MVC.

I should be able to unit test the model code w/o having to hack any UI elements at all.

- Charlie
Left by Charles Rundles on Jan 17, 2007 7:09 PM

# CAB isn't so easy to learn...
Requesting Gravatar...
After spending a few hours trying to figure out the responsibilities of all the elements of CAB, I found
Left by Guy Burstein's Blog on Mar 09, 2007 5:14 PM

Your comment:
 (will show your gravatar)


Copyright © Szymon Kobalczyk | Powered by: GeeksWithBlogs.net