Thursday, May 31, 2007

Action Catalog.

Conditionally execute code at run time.

example
An application that shows a view in a workspace only if the current user is associated with a specific role.

The action is the code that shows the view.
The condition is the code that determines the user's role.
Developers register an action catalog as a service.

Endpoint Catalog Application Block

add a <section> node to the <configSections>

<configSections>
<section name="Endpoints" type="Microsoft.Practices.SmartClient.EndpointCatalog.Configuration.EndpointSection, Microsoft.Practices.SmartClient.EndpointCatalog" />
</configSections>



Create the application block configuration section

<Endpoints>
<EndpointItems>
<add Name="WebService1" Address="http://default-host.com/WebService1.asmx" UserName="default-user-name" Password="default-password" Domain="default-domain">
</add>
</EndpointItems>
</Endpoints>


create a new EndpointCatalog and add it to a WorkItem
using Microsoft.Practices.SmartClient.EndpointCatalog;
using System.Net;


// Specify the section name in the configuration file.

IEndpointCatalogFactory catalogFactory = new EndpointCatalogFactory("Endpoints");

IEndpointCatalog catalog = catalogFactory.CreateCatalog();

myWorkItem.Services.Add<IEndpointCatalog>(catalog);
Getting an Endpoint Catalog Instance from a WorkItem


Method 1:
public class MyNewClass
{
private EndpointCatalog catalog;

public MyNewClass([ServiceDependency] EndpointCatalog catalog)
{
this.catalog = catalog;
}
...
}
Method 2:
public class MyNewClass
{
private EndpointCatalog catalog;

[ServiceDependency]
public EndpointCatalog EndpointCatalog
{
get { return this.catalog; }
set { this.catalog = value; }
}
...
}
Method 3:
public class MyNewClass
{
private EndpointCatalog catalog;

public MyNewClass()
{
this.catalog = myWorkItem.Services.Get<EndpointCatalog>();
}
...
}

Listing and Getting Information about Endpoints

To check whether an endpoint exists
String epName = "MyWebServiceEndpoint";
if (catalog.EndpointExists(epName))
{
// Endpoint named MyWebServiceEndpoint does exist in the catalog.
}

To get information about an endpoint
// Get the number of endpoints in the catalog.
int endpointCount = catalog.Count;
// Get the address for an endpoint if it exists.
String epName = "MyWebServiceEndpoint";
String epNetworkName = "MyHost";
if (catalog.AddressExistsForEndpoint(epName, epNetworkName))
{
String epAddress
= catalog.GetAddressForEndpoint(epName, epNetworkName);
// Get the credentials for this endpoint.
NetworkCredential epCredentials
= catalog.GetCredentialForEndpoint(epName, epNetworkName);
String epUsername = epCredentials.UserName;

String epPassword = epCredentials.Password;
String epDomain = epCredentials.Domain;
}

Endpoint Catalog Application Block - Config

<Endpoints>
<EndpointItems>
<add Name="WebService1" Address="http://default-host.com/WebService1.asmx" UserName="default-user-name" Password="default-password" Domain="default-domain">
<NetworkItems>
<add Name="Internet" Address="http://internet-host.com/WebService1.asmx"
UserName="internet-user-name" Password="internet-password" />
<add Name="Work" Address="http://work-host.com/WebService1.asmx"
UserName="work-user-name" Password="work-password" />
</NetworkItems>
</add>
<add Name="WebService2" Address="http://default-host.com/WebService2.asmx" UserName="default-user-name" Password="default-password" Domain="default-domain">
<NetworkItems>
<add Name="Internet" Address="http://internet-host.com/WebService2.asmx"
UserName="internet-user-name" Password="internet-password" />
</NetworkItems>
</add>
</EndpointItems>
</Endpoints>

Disconnected Service Agent Application Block

add references to the following assemblies:
Microsoft.Practices.SmartClient.DisconnectedAgent
Microsoft.Practices.SmartClient.EnterpriseLibrary

Initializing the Request Manager
  1. Invoke any of the two overloads of the static method Initialize.

    // for default database that specified in the Data Access Application Block configuration.
    RequestManager requestManager = DatabaseRequestManagerIntializer.Initialize();

    OR

    RequestManager requestManager = DatabaseRequestManagerIntializer.Initialize("databaseName");


  2. To full control over the objects used to initialize the request manager, manually construct the objects and call the Initialize method

  1. EndpointCatalogFactory catalogFactory = new EndpointCatalogFactory("Endpoints");
    catalog = catalogFactory.CreateCatalog();

    SmartClientDatabase requestQueueDb = new
    SmartClientDatabase(ConfigurationManager.ConnectionStrings["QueueConnectionString"].ConnectionString);

    DatabaseRequestQueue requestQueue = new DatabaseRequestQueue(requestQueueDb, "RequestsQueue");

    SmartClientDatabase deadLetterQueueDb = new SmartClientDatabase(ConfigurationManager.ConnectionStrings["QueueConnectionString"].ConnectionString);

    DatabaseRequestQueue deadLetterQueue = new
    DatabaseRequestQueue(deadLetterQueueDb, "DeadLetterQueue");

    ConnectionMonitorAdapter adapter = new ConnectionMonitorAdapter(ConnectionMonitorFactory.CreateFromConfiguration());

    RequestManager manager = RequestManager.Instance;

    manager.Initialize(requestQueue, deadLetterQueue, adapter, catalog);

Creating a Simple Request
Request req = new Request();
req.MethodName = "DeliveryRouteUpdate";
req.Endpoint = "MyWebServiceHost";
specify the online proxy type for the request. The proxy class is the one that Visual Studio generates when you add a Web reference to your project.
req.OnlineProxyType = typeof(MyWebServiceProxy);
specify the behavior of the request
behavior.ProxyFactoryType = typeof(WebServiceProxyFactory);
other OfflineBehavior properties are Tag, MaxRetries, Stamps

Adding Parameters to a Request
int customerCode = 1234;
string comment = "New value for comment";
req.CallParameters = CallParameters.ToArray(customerCode, comment);
Handling Callbacks for a Request
req.Behavior.ReturnCallback
= new CommandCallback(typeof(MyDisconnectedServiceAgentCallbackClass),
"MyReturnCallbackMethod");

req.Behavior.ExceptionCallback
= new CommandCallback(typeof(MyDisconnectedServiceAgentCallbackClass),
"MyExceptionCallbackMethod");
method that takes references to the Request, an Object array for the parameters (arguments) you submitted to the service, and an Object for any value returned by the Web service.
public void MyReturnCallbackMethod(Request req, Object[] qParams,
Object result)
{
MessageBox.Show("Request succeeded. Return value is: "
+ result.ToString());
}


public OnExceptionAction MyExceptionCallbackMethod(Request req,
Exception ex)
{
MessageBox.Show("Your request failed with error: " + ex.Message);
return OnExceptionAction.Dismiss;
}



Adding a Request to a Queue
requestManager.RequestQueue.Enqueue(req);
Removing a Request from a Queue
requestManager.DeadLetterQueue.Remove(req)
Accessing Requests in a Queue
IRequestQueue theQueue = requestManager.RequestQueue;
// or:
IRequestQueue theQueue = requestManager.DeadLetterQueue;

// Count the number of requests in the queue.
Int32 queueCount = theQueue.GetCount();
// Get a reference to the next request in the queue.
Request nextRequest = theQueue.GetNextRequest();
// Get all the requests in the queue.
IEnumerable>Request> requests = theQueue.GetRequests();
// Get single request iterator by request ID.
Request requestById = theQueue.GetRequest(requestId);
// Get all the requests that have a specified Tag property value.
IEnumerable>Request> requestsByTag = theQueue.GetRequests("SalesOrder");
// Get all the requests that have a specified "stamps" value
// that is greater than or equal to a specified numerical value.
IEnumerable>Request> requestsByPrice = theQueue.GetRequests(5);

To remove a request from the queue, pass a reference to that request to the Remove method of the queue.
theQueue.Remove(req);
Dispatching a Single Request Immediately
requestManager.RequestQueue.Enqueue(req);
requestManager.DispatchRequest(req);

Dispatching All Pending Requests
requestManager.DispatchAllPendingRequests();
Dispatching Specific Pending Requests
requestManager.DispatchPendingRequestsByTag("Sales Order");
Starting and Stopping the Dispatcher Service
if (requestManager.Running)
{
reqManager.StopAutomaticDispatch();

OR

reqManager.StartAutomaticDispatch();
}




Conclustion

RequestManager requestManager = DatabaseRequestManagrerInitializer.Initialize();

Request req = new Request();
req.MethodName = "DeliveryRouteUpdate";
req.EndPoint = "MyWebServiceHost";
req.OnlineProxyType = typeof(MyWebServiceProxy);
behavior.ProxyFactoryType = typeof(WebServiceProxyFactory);

int customerCode =1234;
string comment = "New value for cooment";
req. Callparametars=CallParameters.ToArray(customerCode,Comment);

requestManager.RequestQueue.Enqueue(req);
requestManager.DispatchRequest(req);

Wednesday, May 30, 2007

Connection Monitor Application Block

Configure the Connection Monitor Application Block
add a <section> node to the <configSections>
<configSections>
<section name="ConnectionMonitor" type="Microsoft.Practices.SmartClient.ConnectionMonitor.Configuration.ConnectionSettingsSection, Microsoft.Practices.SmartClient.ConnectionMonitor" />
</configSections>
To use the Connection manager Application Block,
Add configuration information to the application configuration file.
It defines the logical networks and physical network adapters that you want to monitor.
<ConnectionMonitor>
<Networks>
<add Name="Intranet" Address="http://contoso"/>
<add Name="Internet" Address="http://www.microsoft.com"/>
</Networks>
<Connections>
<add Type="WiredConnection" Price="1"/>
</Connections>
</ConnectionMonitor>

Instantiate the ConnectionMonitor service and store it in a WorkItem

Call the static CreateFromConfiguration method of the ConnectionMonitorFactory class.

// Use the default section name "ConnectionMonitor."
ConnectionMonitor sampleMonitor
= ConnectionMonitorFactory.CreateFromConfiguration();

// Instead, you can specify the section name in the configuration file.
String configurationName = "SampleConnectionSection";
ConnectionMonitor sampleMonitor
= ConnectionMonitorFactory.CreateFromConfiguration(configurationName);

Add the ConnectionMonitor instance to the Services collection of your WorkItem
myWorkItem.Services.Add(sampleMonitor);
if (sampleMonitor.Connections.Contains("Internet"))
{
// Check the connection status.
Connection conn = sampleMonitor.Connections["Internet"];
if (!conn.IsConnected)
{
}

Get a reference to the Connection Monitor service from another class

  1. use a [ServiceDependency] attribute on a parameter of the class constructor to accept an injected reference
    public class MyNewClass
    {
    private ConnectionMonitor sampleMonitor;
    public MyNewClass([ServiceDependency] ConnectionMonitor cm)
    {
    this.sampleMonitor = cm;
    }
    ...
    }

  2. Expose a public property for the ConnectionMonitor
    public class MyNewClass
    {
    private ConnectionMonitor sampleMonitor;
    [ServiceDependency]
    public ConnectionMonitor ConnectionMonitor
    {
    get { return this.sampleMonitor; }
    set { this.sampleMonitor = value; }
    }
    ...
    }

  3. Query the Services collection of the WorkItem to obtain a reference to the service
    public class MyNewClass
    {
    private ConnectionMonitor sampleMonitor;
    public MyNewClass();
    {
    this.sampleMonitor = myWorkItem.Services.Get<ConnectionMonitor>();
    }
    ...
    }


Detect and handle changes to networks and connectivity

1. Connect your event handler to the StateChanged event of the Connection or Network
conn.StateChanged += StateChangeHandler;
netwk.StateChanged += StateChangeHandler;
2. Network and the Connection classes both raise a StateChanged event when their state changes.
public void StateChangeHandler(object sender, StateChangedEventArgs e)
{
if (e.IsConnected)
{ MessageBox.Show("Now connected"); }

}

3. The Connection class exposes a method named UpdateStatus that you can call to raise the StateChanged event and obtain information through your event handler on the connectivity status
conn.UpdateStatus();

Creating Connections and Networks.


Create a new connection instance
// Create a new NicConnection instance.
NicConnection conn = new NicConnection("NicConnection", 6);
Use the Add method of the ConnectionCollection class
// Add it to the ConnectionMonitor Connections collection.
sampleMonitor.Connections.Add(conn);
It can also use the other methods of the KeyedCollection and Collection classes to check for the presence of a specific connection
// See if a connection named Internet exists.
if (sampleMonitor.Connections.Contains("Internet"))
{
// Check the connection status.
Connection conn = sampleMonitor.Connections["Internet"];
if (!conn.IsConnected)
{
// Display the price and remove it from the Connections collection.
MessageBox.Show("Removing connection with price "
+ conn.Price.ToString());
sampleMonitor.Connections.Remove(conn);
}
}

Tuesday, May 29, 2007

Stage 4: Creating and Showing the SmartPart

create an interface for the view and the presenter to communicate

Create a Interface named IMyView.cs in the MyModule project and change as .
public interface IMyView
{
event EventHandler Load;
string Message { get; set; }
}
Create a SmartPart user control
  1. add a User Control named MyView.cs
  2. Drag a Label control.
  3. Implement the IMyView interface
    1. add IMyView interface t othe class MyView
      public partial class MyView : UserControl, IMyView
    2. right-click IMyView and click Implement Interface, then click Implement Interface in the fly-out menu.
    3. modify property for Message in Interface.
public string Massage
{
get { return this.label1.Text;}
set { this.label1.Text = value;}
}
    Create the presenter class
    1. Create a class named MyPresenter.cs
    2. add a variable of type IMyView
      public class MyPresenter
      {
      IMyView view;
    3. Create a contructor for the class
      public MyPresenter(IMyView view)
      {
      this.view = view;
      view.Load += new EventHandler(view_Load);
      }
    4. Create a event handler for the Load event
    void view_Load(object sender, EventArgs e)
    {
    view.Message = "Hello World from a Module";
    }
    get a reference to the WorkItem
    1. Open the MyModuleInit.cs add the following after the myCatalogService declaration.
      The variable will contain a reference to the root ShellWorkItem
      private WorkItem parentWorkItem;
      [ServiceDependency]
      public WorkItem ParentWorkItem
      {
      set { parentWorkItem = value; }
      }
    2. Modify the load method.
      public override void Load()
      {
      base.Load();
      MyWorkItem myWorkItem =
      parentWorkItem.WorkItems.AddNew<MyWorkItem>();
      myWorkItem.Run(parentWorkItem.Workspaces["tabWorkspace1"]);
      }

    Create and show the view

    1. In MyWorkItem.cs, add
      using Microsoft.Practices.CompositeUI.SmartParts;
    2. Create a public Run method that accepts as a parameter a reference to the TabWorkspace.
      public void Run(IWorkspace TabWorkspace)
      {
      IMyView view = this.Items.AddNew<MyView>();
      MyPresenter presenter = new MyPresenter(view);
      this.Items.Add(presenter);
      TabWorkspace.Show(view);
      }

    Stage 3: Adding the TabWorkspace

    1. Drag a SplitContainer control onto the form ShellForm.cs .

    2. Right-click the Toolbox, click Items..., and then click Browse.....
      In the \Src\CS\CompositeUI.WinForms\bin\Debug\ subfolder of the folder where you installed the CAB files, select the file Microsoft.Practices.CompositeUI.WinForms.dll.

    3. Drag a TabWorkspace onto the form and drop it onto the left-hand panel of the SplitContainer control.

    Stage 2: Creating and Loading the Module

    1. Add new Class Library project named MyModule to the existing solution
    2. In Properties->Build->Output select \bin\Debug folder of ShellApplication project
    3. Save and reopen then, Properties->Outputpath to ..\ShellApplication\bin\Debug
    4. Add Reference
      Microsoft.Practices.CompositeUI.dll
      Microsoft.Practices.CompositeUI.WinForms.dll
      Microsoft.Practices.ObjectBuilder.dll
    5. Create a class named MyWorkItem.cs derived from WorItem and include namespace
      using Microsoft.Practices.CompositeUI;
      public class MyWorkItem : WorkItem
      {
      }
    6. Add a module Initialiser

      1. add class named MyModuleInit.cs derived from ModuleInit and include namespaces

        using Microsoft.Practices.CompositeUI;
        using Microsoft.Practices.CompositeUI.Services;
        using System.Windows.Forms;

        public class MyModuleInit : ModuleInit
        {
        }

      2. Add the following variable to reference the WorkItemTypeCatalogService so that you can access it to register your WorkItem:

        private IWorkItemTypeCatalogService myCatalogService;
        [ServiceDependency]
        public IWorkItemTypeCatalogService myWorkItemCatalog
        {
        set { myCatalogService = value; }
        }

      3. Override the Load method of the ModuleInit class so that it registers your module's WorkItem.

        public override void Load()
        {
        base.Load();
        myCatalogService.RegisterWorkItem<MyWorkItem>();
        }

      4. instruct the CAB to load the new module in ProfileCatalog.xml.
    <?xml version="1.0" encoding="utf-8" ?>
    <SolutionProfile xmlns="http://schemas.microsoft.com/pag/cab-profile">
    <Modules>
    <ModuleInfo AssemblyFile="MyModule.dll" />
    </Modules>
    </SolutionProfile>


    right-click the file ProfileCatalog.xml and click Properties. Change the Copy To Output Directory property to Copy Always.

    Stage 1: Creating the Shell and the Form

    1. Create a new Windows Forms application named ShellApplication
    2. rename Form1.cs to ShellForm.cs
    3. Add Reference

      Microsoft.Practices.CompositeUI.dll
      Microsoft.Practices.CompositeUI.WinForms.dll
      Microsoft.Practices.ObjectBuilder.dll

    4. create a custom workitem
      1. create a new class named ShellWorkItem.cs
      2. Inherit class from WorkItem and include namespace
        using Microsoft.Practices.CompositeUI;
        public class ShellWorkItem : WorkItem
        {
        }
    5. modification in program.cs
      1. rename Program.cs to ShellApplication.cs
      2. include namespace
        using Microsoft.Practices.CompositeUI.WinForms;
      3. Replace the static class ShellApplication with a public class that inherits from FormShellApplication
        public class ShellApplication :
        FormShellApplication<shellworkitem,shellform>
        {
        }
      4. [STAThread]
        static void Main()
        {
        new ShellApplication().Run();
        }

    Basic Commands...

    Creating a shell.
    public class MyApplication : FormShellApplication<WorkItem, MyShellForm>
    {
    }
    [STAThread]
    public static void Main()
    {
    new MyApplication.Run();
    }

    override the AfterShellCreated method
    protected override void AfterShellCreated()
    {
    base.AfterShellCreated();
    ... your start-up code here ...
    }

    display a SmartPart in a Workspace
    Form1 mainForm = new Form1();
    CustomerSmartPart sp = myWorkItem.Items.AddNew<CustomerSmartPart>();
    mainForm.deckWorkspace1.Show(sp);

    WorkItems.

    create a workitem
    1. create a class inherit from Microsoft.Practices.CompositeUI.WorkItem.
    2. override the OnRunStarted method. In this method, add code to perform an initialization required and to display the appropriate view.
    protected override void OnRunStarted()
    {
    base.OnRunStarted();
    SummaryView view = this.Items.AddNew<SummaryView>();
    workspace.Show(view);
    }

    Invoke a WorkItem
    myWorkItem.Run();


    Inject state into child SmartParts in a child WorkItem

    steps1: In the parent WorkItem, set the state so that adding a child WorkItem to the container injects the state into it
    public void ShowCustomerDetails(Customer custmr)
    {
    // set state for injection into child WorkItem
    State["Customer"] = custmr;
    ChildWorkItem myChild = this.WorkItems.AddNew<ChildWorkItem>();
    myChild.Run();
    }
    steps2: In the child WorkItem, use the State attribute to indicate that a parent WorkItem should inject the property into the child WorkItem.
    // in child WorkItem
    [State("Customer")]
    public Customer TheCustomer
    {
    get { return (Customer)State["Customer"]; }
    set { State["Customer"] = value; }
    }

    UIElements.
    RootWorkItem.UIExtensionSites.RegisterSite("MainMenu", Shell.MainMenuStrip);
    ToolStripMenuItem item = null;
    item = new ToolStripMenuItem("Name");
    MyWorkItem.UIExtensionSites["MainMenu"].Add(item);

    Commands.
    [CommandHandler("ShowName")]
    public void ShowName(object sender, EventArgs e)
    {
    MessageBox.Show("My name is Joe");
    }

    associate a Command with a UIElement
    MyWorkItem.Commands["ShowName"].AddInvoker(item, "Click");


    Services.

    add a service by specifying it in the shell application configuration file
    <?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>
    <!-- Other services -->
    <add serviceType="MyApp.Services.IMyService, MyApp"
    instanceType="MyApp.Services.MyService, MyApp"/>
    </services>
    </CompositeUI>
    </configuration>


    to add a service programmatically

    1. to use an existing service instance already created.
    RootWorkItem.Services.Add<CustomerService>(myServiceInstance);

    2. to create a new instance of a service
    RootWorkItem.Services.AddNew<CustomerService>();


    Register a class as a service using attribute.
    [Service(typeof(IMyService))]
    public class MyService : IMyService
    {
    }
    Services that do not provide different implementations may not implement an interface
    [Service]
    public class MyService
    {
    }

    declare a class to be registered as a lazy-loaded service.
    [Service(typeof(IMyService), AddOnDemand=true)]
    public class MyService : IMyService
    {
    }

    Module.

    steps1 : Create a module
    steps2 : Create a module initializer
    steps3 : add dependencies to the module
    steps4 : load a module

    Create a module
    1. create a new class library or Windows control library project
    2. add reference to Microsoft.Practices.CompositeUI and Microsoft.Practices.ObjectBuilder
    3. add a module attribute to identify this as a module.
    4. [assembly: Microsoft.Practices.CompositeUI.Module("mainMod")] in AssemblyInfo.cs

    Create a module Initializer
    1. create a new public class
    2. inherit from Microsoft.Practices.CompositeUI.ModuleInit class.
    3. you can override the AddServices method
    4. you can override the Load method
    add dependencies
    put following in either in the ModuleInit or AssemblyInfo.cs
    [assembly: Microsoft.Practices.CompositeUI.ModuleDependency(
    "TheModuleYouDependOn")]
    load a module
    <?xml version="1.0" encoding="utf-8" ?>
    <SolutionProfile xmlns="http://schemas.microsoft.com/pag/cab-profile">
    <Modules>
    <ModuleInfo AssemblyFile="Mod1.dll"/>
    <ModuleInfo AssemblyFile="Mod2.dll"/>
    </Modules>
    </SolutionProfile>

    creating reference to services

    programmatically
    IMyService myServ = (IMyService)myWorkItem.Services.Get(typeof(IMyService));

    // or using generics
    IMyService myServ = myWorkItem.Services.Get<IMyService>();
    declaratively
    private IMyService service;

    [ServiceDependency]
    public IMyService MyService
    {
    set { service = value; }
    }


    creating Custom Services
    steps1: add a new interface to an appropriate module.
    steps2: add members that the interface will define.
    steps3: add a new class to the module or the shell.
    steps4: inherit from the interface and add required functionality to the members.
    steps5: add the attribute like following
    [Service(Type=typeof(IMyService))]
    public class MyService : IMyService

    SmartParts.

    steps1: add a user control to project
    steps2: add a reference to the Microsoft.Practices.CompositeUI.SmartParts
    steps3: add the attribute as following
    [SmartPart]
    public partial class MySmartPart : UserControl

    display a SmartPart in a Workspace
    public class MyWorkItem : WorkItem
    {
    protected override void OnRunStarted()
    {
    base.OnRunStarted();
    CustomerSmartPart csp = this.SmartParts.AddNew<CustomerSmartPart>();
    Workspaces["tabbedArea"].Show(csp);
    }
    }
    implement the MVC pattern
    protected override void OnRunStarted()
    {
    base.OnRunStarted();
    SampleView view = this.Items.AddNew<SampleView>();
    workspace.Show(view);
    }
    Publishing Events
    [EventPublication("event://UpdatesAvailable", PublicationScope.Global)]
    public event SomeEventHandler UpdatesAvailable;

    Subscribing to Events
    [EventSubscription("event://UpdatesAvailable")]
    public void NewUpdates(object sender, SomeEventArgs numUpdates)
    {
    MessageBox.Show(numUpdates.ToString(), "Updates available");
    }

    run an event on a background thread
    [EventSubscription("event://UpdatesAvailable",
    Thread=ThreadOption.Background)]

    Monday, May 28, 2007

    Basic Commands

    UI Elements.
    RootWorkItem.UIExtensionSites.RegisterSite(“FileMenu”, Shell.MainMenuStrip);


    ToolStripMenuItem printItem = new ToolStripMenuItem("Print");
    RootWorkItem.UIExtensionSites[“FileMenu”].Add(printItem);
    WorkItems.
    adding services to a workitem. ie creates an instance
    WorkItem.Services.AddNew<CustomerFinderService, ICustomerFinderService>();
    creates an instance of the OfficerView class
    WorkItem.SmartParts.AddNew<OfficerView>();
    get another component in a workitem
    ICustomerFinderService customerFinderServcie =
    WorkItem.Services.Get<ICustomerFinderService>();

    EVents.
    publishing
    [EventPublication("topic://UpdatesAvailable", PublicationScope.Global)]
    public event EventHandler<DataEventArgs<UpdateData>> UpdatesAvailable;
    // or
    [EventPublication("topic://UpdatesAvailable", PublicationScope.Global)]
    public event EventHandler UpdatesAvailable;
    subscription
    [EventSubscription("topic://UpdatesAvailable")]
    public void SomethingHappened(object sender, DataEventArgs<UpdateData> e)
    { ... }

    Module.
    Module Dependencies
    [assembly: ModuleDependency("BranchSystems.Module")]
    Loading Modules- default file is ProfileCatalog.xml
    <?xml version="1.0" encoding="utf-8" ?>
    <SolutionProfile xmlns="http://schemas.microsoft.com/pag/cab-profile" >
    <Modules>
    <ModuleInfo
    AssemblyFile="GlobalBank.AppraiserWorkbench.AppraiserWorkbenchModule.dll" /></Modules></SolutionProfile>
    services.
    Registering a service
    [Service(typeof(IMyService))]
    public class MyService : IMyService
    {
    }

    Locating a Service.
    private IMyService service;

    [ServiceDependency]
    public IMyService MyService
    {
    set { service = value; }
    }


    Thursday, May 24, 2007

    Object Builder.

    create objects and perform dependency injection.
    It manages the processes performed on objects during construction and disposal.

    attributes - [CreateNew] and [ServiceDependency]
    CreateNew - This attribute tells the dependency injection system to always create a new one of whatever it is you need.
    Dependency - This is a general-purpose attribute with four optional parameters: Name, NotPresentBehavior, Createype, SearchMode
    methods - BuildUp and TearDown.

    BuildUp(locator, type, id, instance, policies[] );
    BuildUp(locator, id, instance, policies[] );

    Creating New Objects.
    [CreateNew]
    public NewTransferViewPresenter Presenter
    {
    get { return _presenter; }
    set
    {
    _presenter = value;
    _presenter.View = this;
    }
    }
    The CreateNew attribute instructs ObjectBuilder to instantiate and initialize an instance of a NewTransferViewPresenter when the NewTransferView is created.
    When the property is set, the View property of the presenter is used to connect this implementation of the INewTransferView interface to the presenter.

    Locating a Service.

    You can add the ServiceDependency attribute to a property.
    The property specifies the type of service or interface you require.
    When this attribute is present, ObjectBuilder locates an instance of the service and passes back a reference to it.
    To locate the service, ObjectBuilder first looks in the current WorkItem. If the service is not found, ObjectBuilder then looks at the services in the parent WorkItem.
    private IAccountServices _accountServices;
    [ServiceDependency]
    public IAccountServices AccountServices
    {
    set { _accountServices = value; }

    }

    Frequently, the ServiceDependency attribute is used for the arguments in a constructor. This means that ObjectBuilder will instantiate the required services when it creates the dependent object.
    public class ElectronicFundsTransferController
    {
    private IAccountServices _accountServices;
    public ElectronicFundsTransferController( [ServiceDependency] IAccountServices accountServices )

    {
    _accountServices = accountServices;
    }
    ...
    }

    Registering a Service.
    To programmatically register a service, call the Add method or AddNew method of the Services collection of the WorkItem within which you want to use the service.


    moduleWorkItem.Services.AddNew<AccountServices, IAccountServices>();


    Registering a Constructor.
    A class can contain more than one constructor. ObjectBuilder first looks for any constructor decorated with the [InjectionConstructor] attribute.
    public class CustomersListViewPresenter
    {


    private CustomersController _controller;

    [InjectionConstructor]

    public CustomersListViewPresenter ( [ServiceDependency] CustomersController controller )

    {
    _controller = controller;
    }
    ...
    }

    Tuesday, May 22, 2007

    The Disconnected Service Agent Application Block

    Provides management features for executing Web services from occasionally connected smart client applications.
    Application can maintain a queue of Web service requests when offline (disconnected) and then replay them when a connection to the server application becomes available.

    RequestManager
    class manages the request queues and uses the services of the RequestDispatcher class to dispatch these requests. stores the queues of pending and failed requests in a SQL Server 2005 Compact Edition database. It takes the messages from the queue and dispatches them when the application is online. Requests remain in the database until successful submission to the remote server or until the request expires.

    Request
    class is the store for a Web service request, including the arguments or parameters required by the Web service method.

    ConnectionMonitorAdapter
    class provides information about the connection used by the request, such as the price and network details, and it raises events when status of the connection changes.

    EndpointCatalog
    class that contains the endpoints to use for the request. Requests to a remote service require details of the endpoint, such as the network type, credentials, and URL.

    OfflineBehavior

    class exposes properties that provide information about the request, such as the date and time it was queued. You also use this class to specify features of the request, such as the expiration, maximum number of retries, the number of "stamps", and the Tag value.

    Creating Connections and Networks

    To create a new connection instance, call the constructor of the appropriate concrete class and specify the name and the price for this connection.
    // Create a new NicConnection instance.
    NicConnection conn = new NicConnection("NicConnection", 6);
    Use the Add method of the ConnectionCollection class
    // Add it to the ConnectionMonitor Connections collection.
    sampleMonitor.Connections.Add(conn);

    You can also use the other methods of the KeyedCollection and Collection classes (from which the ConnectionCollection class inherits) to check for the presence of a specific connection, get a reference to it, and remove it from the ConnectionCollection.

    // See if a connection named Internet exists.
    if (sampleMonitor.Connections.Contains("Internet"))
    {
    // Check the connection status.
    Connection conn = sampleMonitor.Connections["Internet"];
    if (!conn.IsConnected)
    {
    // Display the price and remove it from the Connections collection.
    MessageBox.Show("Removing connection with price "
    + conn.Price.ToString());
    sampleMonitor.Connections.Remove(conn);
    }
    }
    The same principles apply to the Network and NetworkCollection classes. You create a new Network instance by specifying the name in a call to the constructor.
    Network network = new Network("Intranet", "http://intranet");
    Then you add it to the NetworkCollection using the Add method.
    sampleMonitor.Networks.Add(network);
    You also use the same methods and properties of the underlying KeyedCollection and Collection classes to manipulate the collection of Network instances.
    // See if a network named Internet exists.
    if (sampleMonitor.Networks.Contains("Intranet"))
    {
    // Check connection status.
    Network netwk = sampleMonitor.Networks["Intranet"];
    if (!netwk.Connected)
    {
    // Remove the network from the Networks collection.
    sampleMonitor.Networks.Remove(netwk);
    }
    }

    Monday, May 21, 2007

    Handling Connectivity Change Events

    detect and handle changes to networks and connectivity

    The Network and the Connection classes both raise a StateChanged event when their state changes. Create a handler for this event that accepts an instance of the StateChangedEventArgs class, which exposes the IsConnected property

    public void StateChangeHandler(object sender, StateChangedEventArgs e)
    {
    if (e.IsConnected)
    {
    MessageBox.Show("Now connected");
    }
    else
    {
    MessageBox.Show("Now disconnected");
    }
    }

    Connect your event handler to the StateChanged event of the Connection or Network you want to monitor.
    conn.StateChanged += StateChangeHandler;
    netwk.StateChanged += StateChangeHandler;
    The Connection class exposes a method named UpdateStatus that you can call to raise the StateChanged event and obtain information through your event handler on the connectivity status.
    conn.UpdateStatus();

    Listing the Configured Networks

    You can obtain a list of the configured networks from the Networks property of the ConnectionMonitor.
    NetworkCollection netList = sampleMonitor.Networks;
    The NetworkCollection class inherits from the generic collection class KeyedCollection, and implements the IEnumerable interface.
    StringBuilder builder = new StringBuilder();
    foreach (Network netwk in netList)
    {
    builder.Append(String.Format("Name: {0}, Connected: {1}",
    netwk.Name, netwk.Connected.ToString()));
    builder.Append("\n");
    }
    To obtain a list of the connected networks only, use the ActiveNetworks property of the NetworkCollection class.
    ReadOnlyCollection<network> activeNetworks = sampleMonitor.Networks.ActiveNetworks;

    Get a list of the connections configured in an application

    <Connections>
    <add Type="WiredConnection" Price="1" />
    <add Type="WirelessConnection" Price="2" />
    </Connections>
    You can obtain a list of the configured connections from the Connections property of the ConnectionMonitor.
    ConnectionCollection connList = sampleMonitor.Connections;
    The ConnectionCollection class inherits from the generic collection class KeyedCollection and implements the IEnumerable interface.

    StringBuilder builder = new StringBuilder();
    foreach (Connection conn in connList)
    {
    builder.Append(String.Format("Type: {0}, Price: {1}, "
    + "IsConnected: {2}",
    conn.ConnectionTypeName,
    conn.Price.ToString(),
    conn.IsConnected.ToString()));
    builder.Append("\n");
    }

    Referencing the Connection Monitor Service

    Get a reference to the Connection Monitor service from another class

    If you have stored an instance of the ConnectionMonitor class in your WorkItem, you can reference it from any other class within the scope of that WorkItem. You can use a [ServiceDependency] attribute on a parameter of the class constructor to accept an injected reference and store it in a class-level variable.
    public class MyNewClass
    {
    private ConnectionMonitor sampleMonitor;

    public MyNewClass([ServiceDependency] ConnectionMonitor cm)
    {
    this.sampleMonitor = cm;
    }
    ...
    }
    Alternatively, you can expose a public property for the ConnectionMonitor and have ObjectBuilder set it to the ConnectionMonitor instance in the WorkItem.
    public class MyNewClass
    {
    private ConnectionMonitor sampleMonitor;

    [ServiceDependency]
    public ConnectionMonitor ConnectionMonitor
    {
    get { return this.sampleMonitor; }
    set { this.sampleMonitor = value; }
    }
    ...
    }
    Another approach is to directly query the Services collection of the WorkItem to obtain a reference to the service you want.
    public class MyNewClass
    {
    private ConnectionMonitor sampleMonitor;

    public MyNewClass();
    {
    this.sampleMonitor = myWorkItem.Services.Get();
    }
    ...
    }

    Creating a Connection Monitor Instance

    Instantiate the ConnectionMonitor service and store it in a WorkItem

    Call the static CreateFromConfiguration method of the ConnectionMonitorFactory class. You can specify the name of the section in the application's configuration file that contains the definitions of the connections and networks configured for the application, or you can omit this parameter to use the default section name "ConnectionMonitor."

    // Use the default section name "ConnectionMonitor."
    ConnectionMonitor sampleMonitor
    = ConnectionMonitorFactory.CreateFromConfiguration();

    // Instead, you can specify the section name in the configuration file.
    String configurationName = "SampleConnectionSection";
    ConnectionMonitor sampleMonitor
    = ConnectionMonitorFactory.CreateFromConfiguration(configurationName);
    If you are building a Composite UI Application Block application, you can add the ConnectionMonitor instance to the Services collection of your WorkItem so that it is available by using ObjectBuilder injection techniques.

    myWorkItem.Services.Add(sampleMonitor);


    Configuring the Connection Monitor Application Block

    This configuration information defines the logical networks and physical network adapters that you want to monitor
    <ConnectionMonitor>
    <Networks>
    <add Name="Intranet" Address="http://contoso"/>
    <add Name="Internet" Address="http://www.microsoft.com"/>
    </Networks>
    <Connections>
    <add Type="WiredConnection" Price="1"/>
    </Connections>
    </ConnectionMonitor>
    Following values can use for the Type attribute
    • NicConnection. The application block uses the NicConnection class to monitor any network interface connection—for example, an Ethernet card or wireless adapter. This class provides the capability to detect if the application has a connection to a network.
    • WiredConnection. The application block uses the WiredConnection class to monitor connectivity to Ethernet adapters.
    • WirelessConnection. The application block uses the WirelessConnection class to monitor connectivity to wireless network adapters.
    • DesktopConnection. The application block uses the DesktopConnection class to monitor connectivity to local services (you can manually set the connection state of this class).
    Configure the Connection Monitor Application Block
    Define a configuration section for the application block in the application configuration file. To do this, add a <section> node to the <configSections> node of your App.config file
    <configSections>
    <section name="ConnectionMonitor" type="Microsoft.Practices.SmartClient.ConnectionMonitor.Configuration.ConnectionSettingsSection, Microsoft.Practices.SmartClient.ConnectionMonitor" />
    </configSections>
    Create the application block configuration section and define your logical networks. Configure each logical network inside a node using an element.
    <ConnectionMonitor>
    <Networks>
    <add Name="Intranet" Address="http://intranet"/>
    <add Name="Internet" Address="http://www.microsoft.com"/>
    </Networks>
    </ConnectionMonitor>
    If you want to monitor physical network adapters, add the configuration information for the network adapters inside a <connections> element.
    <ConnectionMonitor>
    <Connections>
    <add Type="WiredConnection" Price="1"/>
    <add Type="WirelessConnection" Price="2"/>
    </Connections>
    </ConnectionMonitor>
    Optionally, specify the type name of the network status strategy to use to monitor the connection status of the logical network.
    <ConnectionMonitor>
    <Networks StrategyType="ConnectionModule.CustomNetworkStatusStrategy, ConnectionModule">
    <add Name="Intranet" Address="http://intranet"/>
    <add Name="Internet" Address="http://www.microsoft.com"/>
    </Networks>
    </ConnectionMonitor>

    Network Monitoring

    The ConnectionMonitor class exposes a NetworkCollection instance through its Networks property. The NetworkCollection class inherits from KeyedCollection, exposing a generic list of Network instances keyed by name. This allows you to enumerate the available networks in your application code.


    The Network Class

    The Network class represents a logical network and exposes the network name and address. It also exposes a Connected property, which your code can use to check for connectivity to a specific network. You can use the StateChanged event to detect changes to the status of the network connection.

    Connection Monitoring

    The Connection abstract base class represents a physical network adapter in the local computer. The application block includes concrete implementations for the following connection types:
    1. NicConnection. This represents any network interface connection—for example, an Ethernet card or wireless adapter. This class provides the capability to detect if the application has a connection to a network.
      The application block also contains two classes that derive from NicConnection.
      1. WiredConnection. This represents a wired connection.
      2. WirelessConnection. This represents a wireless connection
    2. DesktopConnection. This represents a local connection. You can use a desktop connection to programmatically updannte its status (connected or discoected).


    Introduction to the Connection Monitor Application Block

    Use the Connection Monitor Application Block to detect changes in connectivity to networks.
    A logical network is defined by the developer and represents a set of remote resources (for example, Web services).
    With the Connection Monitor Application Block, a logical network is a collection of network addresses for a set of resources required by an application.

    The following are examples of logical networks:

    • The internet
    • A corporate or home network
    • A virtual private network (VPN)
    Physical network adapters include wired and wireless adapters

    Contents

    1. Introducing the Smart Client Software Factory
      • Exploring the Smart Client Software Factory
      • Scenarios and Benefits
      • Software Factory Capabilities
      • Composite Smart Client Applications
      • Software Factories
      • Glossary of Terms
    2. Inspecting the Software Factory Assets
      • Application Blocks
        • ObjectBuilder
          • Design of ObjectBuilder
          • Working with ObjectBuilder
        • Composite UI Application Block
          • Introduction to the Composite UI Application Block
            • Scenarios and Design Goals
          • Design of the Composite UI Application Block
            • Overall Design Goals
              • Design for Modularity
              • Design for Productivity
              • Design for Extensibility
            • Design of Subsystems
              • Design of the Application Shell
              • Design of the Workitem
              • Design of Workspaces
              • Design of UIElementAdapters
              • Design of Commands
              • Design of the Injection Model
              • Design of the Services
                • Design of the Module Enumerator Service
                • Design of the Event Broker Service
                • Design of the Module Loader Service
                • Design of the Authentication Service
                • Design of the State Persistence Service
              • Application Initialization Sequence
            • Threat Model
          • Developing Applications Using the Composite UI Application Block
            • Creating a Shell
            • Adding Service
            • Creating a Module
            • Getting References to Services
            • Creating Custom Services
            • Creating showing SmartParts
            • Developing with the MVC Pattern
            • Publishing and subscribing to Events
            • Working with WorkItems
            • Showing UIElements
            • Registering Commands
            • Using the visualizer
            • Writing Custom Visualizations
          • Extending the Composite UI Application Block
            • Building Custom Workspaces
            • Building Custom UIElementAdapters
            • Changing the Initialization Services
          • Deployment and Operations
            • Deploying the Composite UI Application Block
            • Using ClickOnce with Composite UI Application Block
          • Walkthrough: Designing and building CAB applications
            • Application Requirements and Design
            • Developing the Architecture
            • Implementing the Appilcation
              • Stage 1: Creating the Shell and the Form
              • Stage 2: Creating and Loading the Module
              • Stage 3: Adding the TabWorkspaces
              • Stage 4: Creating and Showing the SmartPart
            • Composite UI Application Block Extensions for WPF
        • The Connection Monitor Application Block
          • Introduction to Connection Monitor Application Block
          • Design of the Connection Monitor Application Block
          • Working with the Connection Monitor Application Block
            • Configuring the Connection Monitor Application Block
            • Creating a Connection Monitor instance
            • Referencing the Connection Monitor Application Service
            • Listing the Configured Connections
            • listing the Configured Networks
            • Handling Connectivity Change Events
            • Creating Connections and Networks
          • Extending the Connection Monitor Application Block

        • The Disconnected Service Agent Application Block
          • Design of the Disconnected Service Agent Application Block
          • Working with the Disconnected Service Agent Application Block
            • Initializing the Request Manager
            • Creating a simple request
            • Adding Parameters to a Request
            • Handling Callbacks for a Request
            • Adding a requests to a Queue
            • Removing a Request from a Queue
            • Accessing Requests in a Queue
            • Dispatching a Single Request Immediately
            • Dispatching All Pending Requests
            • Dispatching Specific Pending Requests
            • Starting anf Stopping the Dispatcher Service
          • Web Service Idempotency and WS-Addressing
          • Extending the Disconnected Service Agent Application Block
        • The Endpoint Catalog Application Block
          • Design of the Endpoint Catalog Application Block
          • Working with Endpoint Catalog Application Block
            • Configuring the Endpoint Catalog Application Block
            • Creating an Endpoint Catalog Class Instance
            • Getting an Endpoint Catalog Instance from a WorkItem
            • Listing and Getting Information about Endpoints
          • Extending Endpoint Catalog Application Block
      • Guidance Automation
        • Registering the Smart Client Software Developement Package
        • Using the Smart Client Software Developement Guidance Package
          • Create Smart Client Application Next Steps
          • Add Bussiness Module Next steps
          • Add Foundational Module Next Steps
          • Add View(with presenter) Recipe Next Steps
          • Add WPF-View (with presenter) Recipe Next Steps
          • Add Disconnected Service agent Receipe Next Steps
          • Update Disconnected Service Agent Recipe Next Steps
          • Add Event Publication Recipe Next Steps
          • Add Event Subscription Recipe Next Steps
      • Patterns for Smart Client Applications
        • Model-View-Presenter(MVP)
        • Container Hierarchy
        • View Navigation
        • Workspace Hierarchy
        • UI Threading
        • Module Plug-in
        • Action Catalog
        • Service Locator
        • WorkItem Identity Publication
      • Quick Starts
        • Composite UI Application Block Quickstarts
          • EventBroker QuickStart
          • ModuleLoader QuickStart
          • SmrtPart QuickStart
          • Commands QuickStart
          • Bank Teller QuickStart
        • Offline Application Blocks QuickStarts
          • Connection Monitor QuickStart
          • Endpoint Catelog QuickStart
          • Disconnected Service Agent QuickStart
        • Windows Presentation Foundation Integration QuickStart
      • Reference implementations
        • Global Bank Scenario
        • Appraiser Workbench
          • Running the Reference Implementations
          • Requirements
          • Application Features
          • Architectural Views
            • User Experience View
            • Logical view
            • Implementation View
            • Control flow View
            • Deployment View
        • Bank Branch Cleint
          • Running the Reference Implementation
          • Use cases
          • Application Features
          • Architectural Views
            • User Experience View
            • Logical view
            • Implementation View
            • Control flow View
            • Deployment View

    3. Development Activities
      • How to : Create Smart Client Solutions
      • How to : Create Business Module
      • How to : Create a Foundational Module
      • How to : Add a View with a Presenter
      • How to : Add a WPF-View with a Presenter
      • How to : Create Disconnected Service Agent
      • How to : Consume a Disconnected Service Agent
      • How to : Update a Disconnected Service Agent
      • How to : Enable a Solution to use WPF Extenstions
      • How to : Translate Between Business Entities and Service Entities
      • How to : Map Business Entities into User Interface Elements
      • How to : Publish Events
      • How to : Communicate Between Views
      • How to : Use the Action Catalog
      • Other Considerations
        • Versioning considerations
        • Securing Data
    4. Deploying Smart Client Applications with ClickOnce
      • ClickOnce Publishing Process
      • ClockOnce Deployment Architecture
      • Deploying for multiple Groups
      • Handling High Deployment Server Load
      • Implementing a Custom ClickOnce Server File Repository
      • Deployment Activities
        • How to: Publish an Initial Version of an Application
        • How to: Deploy an Initial Version of an Application
        • How to: Publish an Updated Version
        • How to: Deploy an Updated Version
        • How to: Move an Application to a Different Server
        • How to: Add On-Demand Programmatic Update
        • How to: Publish Different Versions for Different Groups
        • How to: Restrict Access Based on User Role
        • How to: Apply Updates at a Future Time
        • How to: Share Application Files Across Versions
        • How to: Implement a Custom ClickOnce Deployment Server File Repository
    5. Customizing the Smart Client Software Factory
      1. Extending the Application Blocks
      2. Modifying the Guidance Package
      3. Modifying the Documentation

    Stage 4: Creating and Showing the SmartPart

    In the final stage, you create within the module the SmartPart that provides the view part of the Model-View-Presenter pattern. You also add a presenter for this view to the module. Then you create the connection between the module and the form in the main application to display the SmartPart in the TabWorkspace.

    1. Create an interface for the view and the presenter to communicate
      • In MyModule project, add a new Interface named IMyView.cs.
        • Add the public keyword to the interface statement.
        • declare the two members of this interface as an event named Load and a string property named Message
          public interface IMyView
          {
          event EventHandler Load;
          string Message { get; set; }
          }
    2. create a SmartPart User control
      • In MyModule project, add a User Control named MyView.cs
      • drag a Label control.
    3. implement the IMyView interface
      • In User Control MyView.cs,
        Add the IMyView interface to the class declaration
        public partial class MyView : UserControl, IMyView
      • Right-click IMyView and click Implement Interface, then click Implement Interface in the fly-out menu.
      • Replace the two throw statements that Visual Studio generates with two statements that get and set the value of the Message property
        public string Message
        { get
        { return this.label1.Text; }
        set
        { this.label1.Text = value; }
        }
    4. create the presenter class
      • add a class named MyPresenter.cs
      • make the class public
      • add a variable of type IMyView
        public class MyPresenter
        {
        IMyView view;
      • Create a constructor for the class
        public MyPresenter(IMyView view)
        {
        this.view = view;
        view.Load += new EventHandler(view_Load);
        }
      • e. Create an event handler for the Load event.
        void view_Load(object sender, EventArgs e)
        {
        view.Message = "Hello World from a Module";
        }
    5. get a reference to the WorkItem
      • In MyModuleInit.cs add the variable after myCatalogService variable declaration private WorkItem parentWorkItem
      • add a public property to the class.
        [ServiceDependency]
        public WorkItem ParentWorkItem
        {
        set { parentWorkItem = value; }
        }
      • Modify the Load method that you added during Stage 2.
        public override void Load()
        {
        base.Load();
        MyWorkItem myWorkItem = parentWorkItem.WorkItems.AddNew <
        MyWorkItem &gt (); myWorkItem.Run(parentWorkItem.Workspaces["tabWorkspace1"]);
        }
    6. create and show the view
      • In MyWorkItem.cs,
        using Microsoft.Practices.CompositeUI.SmartParts;
        Create a public Run method that accepts as a parameter a reference to the TabWorkspace.
        public void Run(IWorkspace TabWorkspace()
        {
        }
      • Add statements to the Run method that create a new instance of the MyView MyView view = this.Items.AddNew < MyView &gt();
        MyPresenter presenter = new MyPresenter(view);
      • Add statements to the Run method that add the new presenter to the current WorkItem, and call the Show method of the TabWorkspace to display the view this.Items.Add(presenter);
        TabWorkspace.Show(view);








    Stage 3: Adding the TabWorkspace

    1. Open the file ShellForm.cs
    2. drag a SplitContainer control onto the form.
    3. Right-click the Toolbox, click "Items..." and "Browse..."
    4. select the file Microsoft.Practices.CompositeUI.WinForms.dll.
    5. Drag a TabWorkspace onto the left-hand panel of the SplitContainer.
    6. Set Dock property to Fill.

    Stage 2: Creating and Loading the Module

    1. Add a Class Library project named MyModule in the solution ShellApplication.sln
    2. Project's outputpath should be \ShellApplication\bin\Debug\
    3. In Add Reference Select these three DLLs:
      Microsoft.Practices.CompositeUI.dll
      Microsoft.Practices.CompositeUI.WinForms.dll
      Microsoft.Practices.ObjectBuilder.dll
    4. Add a new class named MyWorkItem.cs
      using Microsoft.Practices.CompositeUI;
      inherits from WorkItem as below
      public class MyWorkItem : WorkItem
      {}
    5. Add a class named MymoduleInit.cs
      using Microsoft.Practices.CompositeUI;
      using Microsoft.Practices.CompositeUI.Services;
      using System.Windows.Forms;
      • inherit from ModuleInit as shown here
        public class MyModuleInit : ModuleInit
      • Add the following variable to reference the WorkItemTypeCatalogService
        private IWorkItemTypeCatalogService myCatalogService;
      • Add the following public property to the class that sets the value of the myCatalogService variable.
        [ServiceDependency]
        public IWorkItemTypeCatalogService myWorkItemCatalog
        {
        set { myCatalogService = value; }
        }
      • Override the Load method of the ModuleInit class
        public override void Load()
        {
        base.Load();
        myCatalogService.RegisterWorkItem <MyWorkItem>();
        }
    6. instruct the CAB to load the new module
      In the ShellApplication project, open the NewItem dialog box and select XML File. Name it ProfileCatalog.xml.
      < ?xml version="1.0" encoding="utf-8" ? &gt
      < SolutionProfile xmlns="http://schemas.microsoft.com/pag/cab-profile" %gt
      &lt Modules >
      &lt ModuleInfo AssemblyFile="MyModule.dll" />
      &lt/Modules>
      &lt/SolutionProfile>
    7. Save and Run the application

    Sunday, May 20, 2007

    Stage 1: Creating the Shell and the Form

    1. create a new application named ShellApplication.sln
    2. In Add Reference Select these three DLLs:
      Microsoft.Practices.CompositeUI.dll
      Microsoft.Practices.CompositeUI.WinForms.dll
      Microsoft.Practices.ObjectBuilder.dll
    3. Create a form named ShellForm.cs
    4. Create a WorkItem
      • Create a class named ShellWorkItem.cs
        using Microsoft.Practices.CompositeUI
      • ShellWorkItem class inherits from WorkItem as shown
        public class ShellWorkItem : WorkItem
        {}
    5. rename the file Program.cs to ShellApplication.cs and open it.
      using Microsoft.Practices.CompositeUI.WinForms;
      • Replace the static class ShellApplication with a public class that inherits from FormShellApplication as below
        public class ShellApplication : FormShellApplication < shellworkitem, ShellForm>
      • Change the static Main method as follows
        [STAThread]
        static void Main()
        {
        new ShellApplication().Run();
        }
    6. Save and Run the application

    Hierachies in Smart Cient Apllications

    Application shell
    • WorkSpaces
    • UI Extension Sites
    • Commands
    • Services

    WorkItems
    • SmartParts
    • controllers
    • services
    • UIElements
    • other components

    Workspaces
    • Window
    • Mdi
    • Tab
    • Deck
    • Zone
    UIElement
    • menus
    • toolbars
    • status bars
    • progress bars
    • sidebars
    • action panes
    • notification tray
    smartparts



    Modules can include:
    • SmartParts
    • support services
    • business logic
    • configuration information

    Application blocks
    • Composite UI application block
    • Object Builder
    • Connection Manager Application Block
    • End Point Catalog Application Block
    • Disconnected Service Agent Application Block

    Saturday, May 19, 2007

    Publishing Events

    You can publish events using the EventPublication attribute on an event declaration. This attribute uses two parameters: the event name and the event scope.

    The event name is a string that identifies the event, for example, event://UpdatesAvailable. The URI syntax convention is recommended to allow for organized and hierarchical naming. For example, event://UpdatesAvailable/New and event://UpdatesAvailable/Deleted.

    Use the PublicationScope enumeration to define the event scope as global, available only to this WorkItem and its descendents, or local to this WorkItem.


    To publish an event that is available in all WorkItem instances

    1. Create the event definition as shown in the following code.
      public event SomeEventHandler UpdatesAvailable;
    2. Add the EventPublication attribute to the definition using the PublicationScope.Global parameter as shown in the following code.
      [EventPublication("event://UpdatesAvailable", PublicationScope.Global)]
      public event SomeEventHandler UpdatesAvailable;


    To publish a event available only to the local and descendant WorkItems

    1. Create the event definition as shown in the following code.
      public event SomeEventHandler UpdatesAvailable;
    2. Add the EventPublication attribute to the definition using the PublicationScope.Descendants parameter as shown in the following code.
      [EventPublication("event://UpdatesAvailable",
      PublicationScope.Descendants)]
      public event SomeEventHandler UpdatesAvailable;

    To publish an event that is available only to the local WorkItem

    1. Create the event definition as shown in the following code.
      public event SomeEventHandler UpdatesAvailable;
    2. Add the EventPublication attribute to the definition using the PublicationScope.WorkItem parameter as shown in the following code.

      [EventPublication("event://UpdatesAvailable", PublicationScope.WorkItem)]
      public event SomeEventHandler UpdatesAvailable;


    Publishing and Subscribing to Events

    Events allow communication between components in WorkItems.

    SmartParts (or other classes) within that WorkItem can then raise the event or subscribe to the published event.

    There are two ways of registering publications or subscriptions for an event:

    • Using Attributes: You can use specific attributes as described in the example below to declare .NET events as event publications that will propagate via the event broker system. You then declare methods decorated with the EventSubscription attribute to receive these events in your classes. This is the simplest way of working with events, and provides the same flexibility as the normal programmatic approach—but requires less code. For the attributes to be processed, you must create or add the class instance to the WorkItem.
    • Programatically: You write code to get an instance of the EventTopic you want to publish or subscribe to via the EventTopics collection of a WorkItem instance, and then call its methods to register and unregister publishers and subscribers. This gives flexibility in the placing of event registration and unregistration for publications and subscriptions, but is not required for most common cases. You can also fire topics programmatically in this way, without registering a publisher.

    Developing with the MVC Pattern

    MVC is a fundamental design pattern for the separation of user interface logic from business logic. The pattern separates the modeling of the application domain, the presentation of the application, and the actions based on user input into three distinct objects:

    View - Forms, SmartParts, and user controls play the role of a view
    Controllers - classes implement controllers
    Model - state and other data takes the form of the model.


    To build a controller class

    1. Create a new class in your application and modify the class declaration to inherit from Microsoft.Practices.CompositeUI.Controller.
    2. Implement your own methods to control the view.
    3. If you require data to be stored in the WorkItem shared state, use the State property of the base class, or the State attribute, as shown in the following code.

      [State("Customer")]
      public Customer customer
      {
      get { return (Customer)State["Customer"]; }
      set { State["Customer"] = value; }
      }

    To build a view class

    1. Create a form, SmartPart, or user control to display information to the user.
    2. Create a class to manage the data displayed in the view. For example, you can create a Customer object that has fields such as firstName and lastName. It is also common to use the DataSet for simpler applications. You can use the State attribute to keep data in a common place within the class.
    3. Add the [CreateNew] attribute to inject an instance of the dependent class through a property, as shown in the following code.
      private MyControllerClass myController;
      [CreateNew]
      public MyControllerClass Controller
      {
      set { myController = value; }
      }

    To implement the MVC pattern

    1. Create a WorkItemas shown in the following code.
      public class MyWorkItem : WorkItem
      {
      }
    2. Override the OnRunStarted Method of the WorkItem to create an instance of the view, as shown in the following code. This automatically creates or retrieves the corresponding controller instance.
      protected override void OnRunStarted()
      {
      base.OnRunStarted();
      SampleView view = this.Items.AddNew();
      workspace.Show(view);
      }


    Creating and Showing SmartParts

    There are two scenarios for using SmartParts in a CAB application:

    • The SmartPart required for a given location on a form is known at design time.
    • The SmartPart is created and displayed dynamically at runtime, typically in response to user interaction.
    If you know the location at design time, you can drag and drop the SmartPart into a suitable Workspace to achieve the required layout of the form contents. For example, you can use a TabWorkspace or a ZoneWorkspace.

    To create a SmartPart

    1. Add a user control to your project.
    2. Add a reference to the Microsoft.Practices.CompositeUI.SmartParts namespace.
    3. Design the control to provide the appropriate appearance and functionality.
    4. Add the SmartPart attribute to the control class as shown in the following code.

    [SmartPart]
    public partial class MySmartPart : UserControl

    To display a SmartPart dynamically at runtime, you can either allow a Workspace control to manage the positioning and dimensions of the SmartPart or you can explicitly designate an area in a form where the SmartPart will appear at runtime by using a SmartPartPlaceHolder control.



    To display a SmartPart in a SmartPartPlaceholder

    1. Create an instance of the SmartPart user control using the AddNew method of the SmartParts or the Items collection of the WorkItem. You pass a string to the AddNew method to assign a name to the SmartPart. At runtime, the SmartPart is automatically loaded into the SmartPartPlaceHolder that specifies the SmartPart name for its SmartPartName property.
      CustomerSmartPart csp;
      csp = myWorkItem.SmartParts.AddNew("CustomerSP");


    To display a SmartPart in a Workspace

    1. Create an instance of the SmartPart user control with the AddNew method of the SmartParts collection of the WorkItem.
    2. Call the Show method of the Workspace in which you want to show the SmartPart.
      public class MyWorkItem : WorkItem
      {
      protected override void OnRunStarted()
      {
      base.OnRunStarted();
      CustomerSmartPart csp = this.SmartParts.AddNew();
      Workspaces["tabbedArea"].Show(csp);
      }
      }
    If you want to specify advanced preferences for how the control will appear, you can create a SmartPartInfo instance of the type that is appropriate for the workspace you are using.

    Creating Custom Services

    You can create a service by adding a class to a module or the shell and applying the Service attribute to the class definition.

    To create a service

    1. Add a new interface to an appropriate module.
    2. Add members that the interface will define.
    3. Add a new class to the module or the shell.
    4. Inherit from the interface and add the required functionality to the members.
    5. Add the Service attribute to the class definition as shown in the following code.

      [Service(Type=typeof(IMyService))]
      public class MyService : IMyService
    The Service attribute triggers the creation of the service when a module is loaded. Service registration occurs using the type specified in the Type property. You can also add services to a WorkItem programmatically

    Getting References to Services

    The term service describes a component that implements some infrastructure-related functionality that other components in the application may need to use; for example, services providing authorization, logging, or hardware communication functionality.

    References to services are obtainable either programmatically or declaratively.


    I. To obtain a reference to a service programmatically

    1. Call the Get method of the Services collection of the WorkItem, passing in the type of service as shown in the following code.
    IMyService myServ = (IMyService)myWorkItem.Services.Get(typeof(IMyService));

    // or using generics
    IMyService myServ = myWorkItem.Services.Get();
    II. To obtain a reference to a service declaratively
    1. Add the ServiceDependency attribute to a property in your class that that is of the type of service or interface you require, as shown in the following code.

      private IMyService service;

      [ServiceDependency]
      public IMyService MyService
      {
      set { service = value; }
      }



    Creating a Module

    Modules are distinct deployment units of a CAB Application.
    A module is a .NET assembly that has attributes, and contains classes that the CAB can find and use.
    Dependency affects the loading sequence.

    To create a module

    1. Create a new class library project or Windows control library project.
    2. Add a reference to Microsoft.Practices.CompositeUI and Microsoft.Practices.ObjectBuilder
    3. Add a ModuleAttribute to the project so that other modules can identify your module.

      Add the following line to the AssemblyInfo.cs file.

      [assembly: Microsoft.Practices.CompositeUI.Module("mainMod")]

    To create a module initializer

    1. Create a new public class in the library project.
    2. Modify the class to inherit from the Microsoft.Practices.CompositeUI.ModuleInit class.
    3. If you want to add services programmatically to the module, override the AddServices method of the ModuleInit class.
    4. If you want to display the user-interface or perform custom logic on startup, override the Load method of the ModuleInit class.

    To add dependencies to the module

    1. Either in the ModuleInit class or in the AssemblyInfo file, add module dependencies as shown in the following code.
      [assembly: Microsoft.Practices.CompositeUI.ModuleDependency("TheModuleYouDependOn")]

    To load modules when the application starts, you must use a catalog file to list the modules to load. The default name for this file is ProfileCatalog.xml.

    To load a module

    1. Add a new XML file to the main project named ProfileCatalog.xml.
    2. Edit the contents of ProfileCatalog.xml to list the appropriate modules to load as shown in the following code.