2010-01-17

CAB & SCSF - Part 01: Module loader

-->
Module Loader
Part 1: giới thiệu tính năng module loader của CAB

Chuẩn bị lab về module loader
Mục đích giới thiệu tính năng tìm và load module qua ProfileCatalog.xml

- Bước chuẩn bị, tạo solution Part01A.sln có các project như sau:
Project
Type/Desc
Blue
Form application, có một form là BlueForm back color là màu xanh. Assembly name là Blue, namespace là Blue.
Red
Form application, có một form là RedForm back color màu đỏ. Assembly name là Red, namespace là Red.
Shell
Một form application default. Assembly name là Shell, namespace là Shell.

- Nếu chúng ta đã thực hiện cài đặt Composite UI Application Block thì thư mục mặc định sẽ nằm tại C:\Program Files\Microsoft Composite UI App Block với C là system drive. Chúng ta sẽ thực hiện import các project CAB nằm trong C:\Program Files\Microsoft Composite UI App Block\CSharp\Source\CompositeUI vào solution. Nếu sử dụng Visual Studio 2008 chúng ta cần convert các project này theo thứ tự từ ObjectBuilder trước. Tuy nhiên để đơn giản chỉ cần DLL files, tạo thư mục ThirdParty cùng cấp với thư mục chứa solution Part01A, copy vào đó 3 files sau:
Microsoft.Practices.CompositeUI.dll
Microsoft.Practices.CompositeUI.WinForms.dll
Microsoft.Practices.ObjectBuilder.dll

- Tạo solution folder ThirdParty: thay vì import các project của CAB chúng ta thực hiện import 3 DLL files đã nói ở trên.



Cấu trúc thư mục


- Add reference tới 3 files trong ThirdParty cho các project Red, BlueShell

Các khái niệm:
Module: đơn giản có thể coi là một ‘component’ hay một ‘application’. Là một block of code thông thường là một UI có thể hiển thị trên một window thường nhưng không reference tới một module khác. Có thể tưởng tượng module là project trong .NET solution. Tổng kết là một standalone project trong đó có một composite user interface.

Shell: một host form chứa các composite user interface.

Nội dung của module - Tìm hiểu ModuleInit
- Thêm vào trong mỗi solution một file như sau (BlueModuleInit.cs):
using Microsoft.Practices.CompositeUI;
namespace Blue
{
    public class BlueModuleInit : ModuleInit
    {
        public override void Load()
        {
            base.Load();
            BlueForm form = new BlueForm();

            form.Show();
        }
    }
}

- Chúng ta thấy BlueModuleInit kế thừa từ ModuleInit (from metadata):
using System;

namespace Microsoft.Practices.CompositeUI
{
    public abstract class ModuleInit : IModule
    {
        protected ModuleInit();

        public virtual void AddServices();
        public virtual void Load();
    }
}

- Trong ModuleInit khai báo 2 method là AddServiceLoad. Hiện tại file BlueModuleInit chỉ thực hiện override method Load tạo một BlueForm và thực hiện show form này.

Thực hiện tương tự với Red project.

- Trong Shell project add thêm 1 file xml ProfileCatalog.xml tên nội dung như sau:
xml version="1.0" encoding="utf-8" ?>
<SolutionProfile xmlns="http://schemas.microsoft.com/pag/cab-profile">
  <Modules>
    <ModuleInfo AssemblyFile="Red.exe" />
    <ModuleInfo AssemblyFile="Blue.exe" />
  Modules>
SolutionProfile>

- ProfileCatalog mô tả các module sẽ thực hiện tìm và load khi application của Shell project thi hành.

- Thực hiện modify Program.cs của project Shell. Nội dung như sau:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Microsoft.Practices.CompositeUI.WinForms;
using Microsoft.Practices.CompositeUI;

namespace Shell
{
    public class Program : FormShellApplication<WorkItem, ShellForm>
    {

        ///
        /// The main entry point for the application.
        ///
        [STAThread]
        static void Main()
        {
            new Program().Run();
        }
    }
}

- Thực hiện modify lại theo các bước bỏ modifier static, thêm kế thừa từ FormShellApplication.

Notes: reference ‘static classes [C#]’ trong MSDN
Static classes and class members are used to create data and functions that can be accessed without creating an instance of the class. Static class members can be used to separate data and behavior that is independent of any object identity: the data and functions do not change regardless of what happens to the object. Static classes can be used when there is no data or behavior in the class that depends on object identity.

- FormShellApplication là một abstract class với generics parameterize TWorkItem là một CompositeUI.WorkItemTShell là một Windows Form
using System;

namespace Microsoft.Practices.CompositeUI.WinForms
{
    public abstract class FormShellApplication<TWorkItem, TShell> : WindowsFormsApplication<TWorkItem, TShell>
        where TWorkItem : Microsoft.Practices.CompositeUI.WorkItem, new()
        where TShell : System.Windows.Forms.Form
    {
        protected FormShellApplication();

        protected override void Start();
    }
}

Note: reference ‘generics [C#]’ trong MSDN:
Generics were added to version 2.0 of the C# language and the common language runtime (CLR). Generics introduce to the .NET Framework the concept of type parameters, which make it possible to design classes and methods that defer the specification of one or more types until the class or method is declared and instantiated by client code.

- Thực hiện build và run Shell vẫn không thấy có chuyện gì xảy ra. Vẫn chỉ có một form Shell hiện lên. Lý do: trong ‘\Shell\bin\Debug’ vẫn chưa có file ProfileCatalog.xml. Chỉnh lại property ‘Copy to Output Directory’ của ProfileCatalog thành ‘Copy Always’.


- Thực hiện build và run lại project sẽ xuất hiện exception như sau:



Lý do là không tìm được Red.exe trong ‘\Shell\bin\Debug\Blue.exe was not found.’

Thực hiện chỉnh lại ‘Output Path’ của các project Red và Blue thành ‘..\Shell\bin\Debug\’ để 3 project cùng output folder.




-         Thực hiện rebuild các solution sẽ thấy kết quả là Shell load cả Red và Blue lên. Để thực hiện được điều này mặc định module loader của CAB đã sử dụng thông tin trong ProfileCatalog. Khi thực hiện close shell thì cả Red form và Blue form cũng sẽ close theo.


-         Nếu tách riêng thì từng project vẫn có thể chạy độc lập với nhau. Trong trường hợp mỗi người thực hiện develop trên một project thì kết quả khi chạy shell sẽ là tổng hợp công việc của 3 developers. Tới đây chúng ta có thể hiểu phần nào ý tưởng của CAB.

Trong phần tiếp theo chúng ta sẽ đề cập đến WorkItem. Một khái niệm căn bản trong CAB.

2 comments:

  1. làm ih chang như zak sao nó vẫn không lên nhỉ

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete