How to: Create Smart Client Solutions

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies.
This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
To create client business applications using current Microsoft technologies, see patterns & practices' Prism.

The Smart Client Software Factory includes a solution template that you can use as the starting point for your smart client applications. The solution includes recommended practices and techniques. It is the basis for the procedures and automated guidance included with the software factory.

This topic describes how to unfold the Smart Client Application template.

Note

Note: This template targets the .NET Framework 3.5 and ignores the target framework version selected in the New Project dialog box. This means that you cannot create smart client solutions that target older .NET Framework versions with this release of the Smart Client Software Factory.

Prerequisites

The Smart Client Application template requires that you have installed the following (included with the software factory):

  • The Composite UI Application Block
  • The Enterprise Library

Steps

To use the guidance package to create a smart client solution

  1. In Visual Studio, point to New on the File menu, and then click Project.

  2. In the New Project dialog box, expand the Guidance Packages node. Click the Smart Client Software Factory 2010 project type, as illustrated in Figure 1.

    Ff699272.08ffa6f1-a802-4882-a5ea-ad986f660ae8(en-us,PandP.10).png

    Figure 1

    The Smart Client Application solution templates

  3. In the Templates window, click the template named Smart Client Application (C#) or Smart Client Application (Visual Basic).

  4. (Optional) Change the Name and Location of the solution.

    Note

    Note: Visual Studio requires the fully qualified file name of any file in the solution to be fewer than 260 characters. The guidance package creates a Visual Studio solution that contains folders and projects with long names. The more characters in the path of the initial solution location, the more limited you will be in the names of the folders and files you can add to the solution. To avoid exceeding the limit, you should consider avoiding initial solution locations, such as the Visual Studio 2010 subfolder of the My Documents folder.

  5. Click OK. The Smart Client Application template references the CreateSolution recipe. The Guidance Automation Extensions calls the CreateSolution recipe when you unfold the template. The CreateSolution recipe starts a wizard to gather information that it uses to customize the generated source code. Figure 2 shows the first page of the wizard.

    Ff699272.b1d71876-cc25-45f3-bfcc-59d7095cbddd(en-us,PandP.10).png

    Figure 2

    The Create Solution recipe wizard

  6. Enter the location of the Composite UI Application Block, Enterprise Library, and the offline application block assemblies. (The wizard sets the default location to the Lib subfolder of the folder where you installed the software factory.) The names of the required assemblies appear under Required application block assemblies.

  7. Enter the root namespace for your application. This value appears as the first part of every namespace in the generated solution. For example, if you enter MyNamespace, the classes in the Shell project will exist in the namespace MyNamespace.Infrastructure.Shell.

  8. (Optional) Select the Create a separate module to define the layout for the shell check box. If you select this option, the recipe will create a shell with only a DeckWorkspace. It will also create a module project that contains a view and presenter that you can use to define the layout.

  9. (Optional) Select the Allow solution to host WPF SmartParts check box. If you select this option, the recipe will create WPF workspaces in the shell, update the signature of the SmartClientApplication class, and add the references to required assemblies.

  10. Click Finish. The recipe unfolds the Smart Client Solution template.

Outcome

You will have a Visual Studio solution with a Source solution folder. This folder has a solution subfolder named Infrastructure, which contains the following four projects:

  • Infrastructure.Interface. This project contains the event topic names, UI extension site names, command names, and workspace names that are the public interface to the Infrastructure.Module module.
  • Infrastructure.Library. This project contains common components used by a set of smart client applications. For example, it includes the service to retrieve the profile catalog from a Web service.
  • Infrastructure.Module. This project contains elements that are shared across projects in your smart client solution.
  • Shell. This project is the basis of a typical Composite UI Application Block application. It contains the startup form and the root WorkItem.

If you select the option to create a separate module to define the layout for the shell, the solution will have an additional project named Infrastructure.Layout. Figure 3 illustrates the solution structure for a smart client that does not contain a separate layout module.

Ff699272.20298858-a756-4300-a3e5-6e09a3a2b70e(en-us,PandP.10).png

Figure 3

The smart client solution structure

Note

Note: The CreateSolution recipe also creates a Lib folder in the root folder of the solution. When the recipe executes, it copies the required assemblies from the Composite UI Application Block and Enterprise Library to the Lib folder.

Smart Client Solution Review

The smart client solution unfolded by the Smart Client Application template is composed of the following projects:

  • Infrastructure.Interface
  • Infrastructure.Module
  • Infrastructure.Library
  • Shell
  • Infrastructure.Layout (only if you selected the option to create a separate module to define the layout for the Shell)

These projects use Composite User Interface Application Block assemblies and contain foundational elements that you can use to build your smart client application.

Infrastructure.Interface

This project is the interface for infrastructure modules and contains only the elements that have to be exposed to other modules of the application.

It is composed of service interfaces, constant definitions, business entities (only those that are passed between modules), and other shared elements, such as general purpose base classes.

Constant Definitions

Commands, event topics, UI extension sites, and workspaces are identified by unique strings. These unique strings are defined as constants for each of these element types, grouped in different classes located in the Constants folder.

CommandNames Class

The Composite UI Application Block uses commands to easily assign the same executable code to multiple user interface elements. For example, you can have a toolbar button and menu item execute the same code. You do this by executing the same command for both the toolbar button and menu item. Each command has a unique string identifier. The CommandNames class contains definitions for the command identifiers that are global to the application.

The following code is a sample implementation of the CommandNames class.

public class CommandNames
{
  public const string FindCustomer = "FindCustomer";
  public const string EnqueueVisitor = "EnqueueVisitor";
  public const string ServiceCustomer = "ServiceCustomer";
}

EventTopicNames class

The Composite UI Application Block includes an event broker system that lets you publish events that allow communication between components in WorkItems. The event name is a string that identifies the event. The EventTopicNames class contains definitions for the event topic identifiers that are global to the application.

The following code is the initial implementation of the EventTopicNames class created by the CreateSolution recipe. It defines an event topic name, StatusUpdate, which is raised whenever the status panel of the Shell has to be updated.

public class EventTopicNames
{
  /// <summary>
  /// Event raised to tell the shell to update the status panel.
  /// </summary>
  public const string StatusUpdate = "StatusUpdate";
}

UIExtensionSiteNames Class

A Composite UI Application Block UIExtensionSite is a named user interface element that can support child elements. Each UIExtensionSite is identified by a unique string value. This string is used to identify elements when they interact with and add child elements to the site, such as when an element adds a menu item to a menu bar. The UIExtensionSiteNames class contains definitions for the UIExtensionSite identifiers that are global to the application.

The following code is the initial implementation of the UIExtensionSiteNames class created by the CreateSolution recipe. It contains the names for the three UIExtensionSites registered by the shell.

public class UIExtensionSiteNames
{
    /// <summary>
    /// The extension site for the main menu.
    /// </summary>
    public const string MainMenu = "MainMenu";

    /// <summary>
    /// The extension site for the main toolbar.
    /// </summary>
    public const string MainToolbar = "MainToolbar";

    /// <summary>
    /// The extension site for the main status bar.
    /// </summary>
    public const string MainStatus = "MainStatus";
}

WorkspaceNames Class

Workspaces are components that encapsulate a particular visual way of displaying controls and SmartParts. Each Workspace is identified by a unique string value. The WorkspaceNames class contains definitions for the Workspace identifiers that are global to the application.

The following code is the initial implementation of the WorkspaceNames class created by the CreateSolution recipe. If you choose to create a separate layout module for the shell, the LayoutWorkspace definition refers to the main workspace of the ShellForm and the ModalWindows definition refers to the WindowsWorkspace used to show modal dialog boxes. LeftWorkspace and RightWorkspace constants correspond to the DeckWorkspaces defined in the ShellLayoutView view (located in the Infrastructure.Layout project) or in the ShellForm (if you do not have the separate layout module for the shell).

public class WorkspaceNames
{
    public const string LayoutWorkspace = "LayoutWorkspace";
    public const string ModalWindows = "ModalWindows";
    public const string LeftWorkspace = "LeftWorkspace";
    public const string RightWorkspace = "RightWorkspace";
}

Business Entities

The BusinessEntities folder contains business entity classes. These are class definitions for business object instances that are shared by different modules in the smart client application.

For example business entities, see the BusinessEntities folder of the Infrastructure.Interface project in the Bank Branch Client reference implementation.

Service Interfaces

The Services folder contains interfaces for public services (services that WorkItems in other projects can consume).

For an example of this, see the Services folder of the Infrastructure.Interface project of the Bank Branch Client reference implementation.

EventArgs Class

Different event handlers can expect different argument types. The EventArgs class is a generic class that allows you to specify a type-safe argument for use in event publishing and subscription.

public class EventArgs<T> : System.EventArgs
{
  private T _data;

  public EventArgs(T data)
  {
    _data = data;
  }

  public T Data
  {
    get { return _data; }
  }
}

Classes to Partition Business Logic and WorkItem Code

The WorkItemController is an abstract base class that contains a WorkItem. This class contains logic that would otherwise exist in the WorkItem. You can use this class to partition your code between a class that derives from WorkItemController and a WorkItem.

When you use the Add Business Module template to create a new Composite UI Application Block module, a ModuleController class is automatically added to control the WorkItem of the module. This class is a specialization of the WorkItemController class.

For an example of a ModuleController class, see the Composite UI Application Block module in the Bank Branch Client reference implementation.

The IWorkItemController is the interface that WorkItemControllers must implement. It specifies a single method, Run.

/// <summary>
/// Controller used by <see cref="ControlledWorkItem{TController}"/>.
/// </summary>
public interface IWorkItemController
{
  /// <summary>
  /// Called when the controller is ready to run.
  /// </summary>
  void Run();
}

The ControlledWorkItem represents a WorkItem that is managed by another class. The other class is the controller and contains the business logic (the WorkItem provides the container).

/// <summary>
/// Represents a WorkItem that uses a WorkItem controller to perform its
/// business logic.
/// </summary>
/// <typeparam name="TController"></typeparam>
public sealed class ControlledWorkItem<TController> : WorkItem
{
  private TController _controller;

  /// <summary>
  /// Gets the controller.
  /// </summary>
  public TController Controller
  {
    get { return _controller; }
  }

  /// <summary>
  /// See <see cref="M:Microsoft.Practices.ObjectBuilder.IBuilderAware.OnBuiltUp(System.String)"/> for more information.
  /// </summary>
  public override void OnBuiltUp(string id)
  {
    base.OnBuiltUp(id);

    _controller = Items.AddNew<TController>();
  }
}

Presenter Base Class

This class contains code that would otherwise be repeated in every presenter when you use the Model-View-Presenter (MVP) pattern. It includes a reference to a generic view and a reference to the WorkItem it belongs to. It also provides virtual methods to work with the controlled view.

To see examples of classes that derive from the Presenter class, see the presenters in the Views folder of the BranchSystems.Module project in the Bank Branch Client reference implementation.

ActionAttribute

This attribute is used to specify that a segment of code is a business action. Whenever you create an object with ObjectBuilder, a strategy will register each method decorated with this attribute as a business action in the action catalog. For more information, see How to: Use the Action Catalog.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class ActionAttribute : Attribute
{
  private string _actionName;

  public ActionAttribute(string actionName)
  {
    _actionName = actionName;
  }

  public string ActionName
  {
    get { return _actionName; }
    set { _actionName = value; }
  }
}

Infrastructure.Module

This project is a Composite UI Application Block module that acts as a container for the implementation of elements that are shared across projects in your smart client application.

When the CreateSolution recipe is executed, this module is added to the profile catalog. This means that Composite UI Application Block loads the Infrastructure.Module module when the application starts.

When first created, this module is empty. You modify it to include the implementation of elements that different modules of your application will use, such as services. For example, the Infrastructure.Module in the Bank Branch Client reference implementation module adds the impersonation service to the root WorkItem.

public override void AddServices()
{
  base.AddServices();
  _rootWorkItem.Services.AddNew<GenericPrincipalImpersonationService, IImpersonationService>();
  //...
}

Infrastructure.Library

This project contains the implementation of elements that are common to a set of smart client applications.

SmartClientApplication Base Class

This class extends FormShellApplication, which performs all the initial tasks that are required to start the application. These tasks include creating the default root WorkItem, adding the standard set of services, and loading any services and modules that are defined in the profile or configuration of the application.

The SmartClientApplication class adds additional services to the root WorkItem that will be consumed from different projects of your smart client application.

For example, it adds the action catalog service (IActionCatalogService) and the entity translator service (IEntityTranslatorService).

Builder Strategies

The Infrastructure.Library project contains an ObjectBuilder strategy named ActionStrategy. This strategy is used to examine object methods that have the Action attribute, and register them with the action catalog. For more information, see How to: Use the Action Catalog.

Services and User Interface Elements

Services and UI folders contain implementation of services and user interface elements common to a set of smart client applications. It includes the following elements:

  • Action catalog service. You can use the action catalog to control whether a business action is executed. For more information, see How to: Use the Action Catalog.
  • Module loading and enumeration services. These services extend Composite UI Application Block built-in services to provide extra features, such as loading modules depending on user roles and retrieving the profile catalog from a Web service.
  • Entity translator service. This service allows you to translate entities from one type to another, and vice versa. For more information, see How to: Translate Between Business Entities and Service Entities.
  • Workspace locator service. This service searches for SmartParts in a particular WorkItem and returns a reference to the workspace it belongs to.
  • WindowsWorkspace. This is a wrapper for the Composite UI Application Block built-in WindowsWorkspace. It allows you set property values for controls of the modal window.

Shell

This project is the shell for the application. It provides the overall user interface structure and contains the root WorkItem.

The basis of the smart client application is the ShellApplication class, which contains the program entry code to load and run the application. This class extends SmartClientApplication class, which makes it easier to start building an application that will have a startup form.

Startup Form

The ShellForm is the startup form of the application. It contains two workspaces, the LeftWorkspace and the RightWorkspace, as shown in Figure 4. If you define the layout for the shell in a separate module, the ShellForm contains only a DeckWorkspace. Figure 5 illustrates the ShellForm for a solution that contains a separate module that defines the layout.

Ff699272.b8670157-a6bd-47f1-9fbc-977938026ac2(en-us,PandP.10).png

Figure 4

ShellForm for an application without a separate module that defines the layout

Ff699272.14207f9b-4b32-4047-83ea-7ae027e26cec(en-us,PandP.10).png

Figure 5

ShellForm for an application that has a separate module that defines the layout

Module Catalog File

The shell also contains a module catalog file named ProfileCatalog.xml. The Composite UI Application Block provides a service to load modules when the application starts. By default, it uses the XML catalog file to determine which modules to load.

Note

Note: You can modify your smart client solution to retrieve the catalog from other data sources. For example, the Bank Branch Client reference implementation retrieves the module catalog from a Web service.

Infrastructure.Layout

The Infrastructure.Layout project is a module that provides a view that defines the layout of the shell. This project is only created for foundational modules that have the option to create a separate module for a selected layout.

Reference Implementation

The Bank Branch Client reference implementation contains the following business modules:

  • Infrastructure.Module
  • CreditCardAccounts.Module
  • BranchSystems.Module
  • BasicAccounts.Module

The BranchSystems.Layout project in the Bank Branch Client reference implementation is a foundational module.

Next Steps

The following are typical tasks that you perform after you create a smart client solution:

  • Modify the layout. For example, you can add or remove workspaces, define menu items, and publish or subscribe to events.

  • Create business modules. Business modules are distinct deployment units of a Composite UI Application Block application that contain business logic elements. With modules, you can encapsulate a set of concerns of your application and deploy them together. The following could be examples of business modules:

    • A module that contains a specific application feature area, such as reports
    • A module that contains use cases for a specific back-end system, such as loan processing
    • To create a business module, run the Add Business Module recipe on a solution folder or the solution root. For information about how to run the recipe, see How to: Create a Business Module.
  • Create foundation modules. Foundational modules are modules that either provide services to the Shell and other modules, provide a layout, or both. They do not implement a use case or contain a WorkItem.

    To create a foundational module, run the Add Foundational Module recipe on a solution folder or the solution root. For information about how to execute the recipe, see How to: Create a Foundational Module.

  • Create Web References. Web references enable your solution to interact with remote Web services. You can create disconnected service agents to add offline capabilities to your proxies. This is useful for occasionally connected applications.

    For information about how to create a disconnected service agent, see How to: Create a Disconnected Service Agent.