Skip to content

TÀI LIỆU HƯỚNG DẪN CÁC BƯỚC XÂY DỰNG & RELEASE 1 MODULE

ninhdd edited this page Aug 9, 2024 · 1 revision

Xây dựng module: Tạo mới project và chọn loại là Class Library

Thư mục lưu các module là thư mục tên Plugins trong source code các phần mềm

Đặt tên cho project module theo quy tắc đặt tên như sau: Tiền tố + .Desktop.Plugins. + Tên mô tả module

Trong đó

  • Tiền tố: Là mã viết tắt của phần mềm chứa module, mã có 3 ký tự
  • Tên mô tả module: đặt tên ngắn gọn, chưa từ khóa dễ nhận biết bám theo chức năng của module

Vd: Đặt tên module là HIS.Desktop.Plugins.HisMachine: dùng cho phần mềm HIS lên tiền tố là HIS, nghiệp vụ xử lý của module là quản lý danh mục “máy”: hiển thị danh sách, thêm, sửa, xóa, khóa nên sẽ đặt tên là HisMachine

1

Add reference các thư viện cần thiết

2

Khai báo bắt buộc trong project:

Thêm dòng khai báo vào file AssemblyInfo.cs

3

Tạo class HisMachineProcessor khai báo tên module và các thuộc tính khác

Trong đó:

  • “HIS.Desktop.Plugins.HisMachine”: Tên module
  • Module.MODULE_TYPE_ID_FORM: kiểu hiển thị module dạng hiển thị popup.

Có 3 kiểu hiển thị module tùy vào yêu cầu mà chọn loại hiển thị cho phù hợp:

  • MODULE_TYPE_ID__COMBO -> module hiển thị tùy chọn
  • MODULE_TYPE_ID__FORM -> module hiển thị dạng popup form
  • MODULE_TYPE_ID__UC -> module hiển thị dạng tab

4

Hàm Run trong class HisMachineProcessor là hàm đặc biệt, bắt buộc phải có, là hàm nhận dữ liệu bên ngoài truyền vào và khởi tạo giao diện trả về cho chỗ sử dụng

public object Run(object[] args)
        {
            object result = null;
            try
            {
                Inventec.Desktop.Common.Modules.Module moduleData = null;
                //args là tham số chứa các đối tượng bên ngoài truyền vào                
                if (args != null && args.Count() > 0)
                {
                //Đoạn xử lý phân tích mảng đối tượng truyền vào để lấy ra dữ liệu cần
                     for (int i = 0; i < args.Count(); i++)
                     {
                          //Kiểm tra nếu đối tượng truyền vào có kiểu phù hợp thì lấy giá trị ra để sử dụng
                          if (args[i] is Inventec.Desktop.Common.Modules.Module)
                          {
                                moduleData = (Inventec.Desktop.Common.Modules.Module)args[i];
                          }
                     }
                }
                //Khởi tạo đối tượng giao diện form và trả về giao diện cho chỗ gọi sử dụng
                result = new frmHisMachine(moduleData);
            }
            catch (Exception ex)
            {
                Inventec.Common.Logging.LogSystem.Error(ex);
                result = null;
            }
            return result;
        }

Sử dụng kế thừa class base và apply các tính năng base hỗ trợ sẵn cho module từ class base

Khai báo kế thừa class base:

Với các module mà giao diện chính là Form cần kế thừa từ class base: HIS.Desktop.Utility.FormBase

Vd:

public partial class frmChooseRoom : HIS.Desktop.Utility.FormBase {
public frmChooseRoom(Inventec.Desktop.Common.Modules.Module module)
            : base(module)

Với các module mà giao diện chính là UserControl cần kế thừa từ class base HIS.Desktop.Utility.UserControlBase

Vd:

public partial class UCRegister : UserControlBase {
public UCRegister(Inventec.Desktop.Common.Modules.Module module)
            : base(module)

Apply tính năng tùy chỉnh nút (Ctrl Shift S) (tiêu đề & shortcut):

Với các module mà giao diện chính là UserControl đã kế thừa từ class base thì mặc định đã apply tính năng không cần sửa gì

Với các module mà giao diện chính là Form đã kế thừa từ class base cần sửa bổ sung dòng code sau:

this.AddBarManager(this.barManager1);

Trong đó AddBarManager là hàm có sẵn xong class base, còn barManager1 là đối tượng BarManager trong form chứa các shortcut đang sử dụng

Apply tính năng ẩn nút (Ctrl Shift H), tính năng mở cấu hình cho từng chức năng Ctrl Shift C, tính năng tìm theo hotkey,…:

Chỉ cần kế thừa từ class base

Tích hợp các tính năng nâng cao – tiện ích bổ sung khác

Tích hợp code phần lưu trạng thái các check (“In”, “Ký”, “In file đã ký”,…) tại máy local:

Khai báo các biến:
       bool isNotLoadWhileChangeControlStateInFirst;
       HIS.Desktop.Library.CacheClient.ControlStateWorker controlStateWorker;
       List<HIS.Desktop.Library.CacheClient.ControlStateRDO> currentControlStateRDO;
string moduleLink = "HIS.Desktop.Plugins.AssignService";

Hàm gọi lúc load form để khởi tạo biến đói tượng truy xuất thư viện HIS.Desktop.Library.CacheClient.ControlStateWorker, và gán lại trạng thái các nút của lần gẫn nhất:

void InitControlState()
        {
            try
            {
                isNotLoadWhileChangeControlStateInFirst = true;
                this.controlStateWorker = new HIS.Desktop.Library.CacheClient.ControlStateWorker();
                this.currentControlStateRDO = controlStateWorker.GetData(moduleLink);
                if (this.currentControlStateRDO != null && this.currentControlStateRDO.Count > 0)
                {
                    foreach (var item in this.currentControlStateRDO)
                    {
                        if (item.KEY == ControlStateConstan.chkPrint)
                        {
                            chkPrint.Checked = item.VALUE == "1";
                        }
                        else if (item.KEY == ControlStateConstan.chkSign)
                        {
                            chkSign.Checked = item.VALUE == "1";
                        }
                        else if (item.KEY == ControlStateConstan.chkPrintDocumentSigned)
                        {
                            chkPrintDocumentSigned.Checked = item.VALUE == "1";
                        }
                    }
                }
                isNotLoadWhileChangeControlStateInFirst = false;
            }
            catch (Exception ex)
            {
                Inventec.Common.Logging.LogSystem.Warn(ex);
            }
        }

Các check cần them sự kiện CheckedChanged để xử lý việc thay đổi trạng thái các check & lưu lại vào local

private void chkPrint_CheckedChanged(object sender, EventArgs e)
        {
            try
            {
                if (isNotLoadWhileChangeControlStateInFirst)
                {
                    return;
                } 
                WaitingManager.Show();
                HIS.Desktop.Library.CacheClient.ControlStateRDO csAddOrUpdate = (this.currentControlStateRDO != null && this.currentControlStateRDO.Count > 0) ? this.currentControlStateRDO.Where(o => o.KEY == ControlStateConstan.chkPrint && o.MODULE_LINK == moduleLink).FirstOrDefault() : null;
                Inventec.Common.Logging.LogSystem.Debug(Inventec.Common.Logging.LogUtil.TraceData(Inventec.Common.Logging.LogUtil.GetMemberName(() => csAddOrUpdate), csAddOrUpdate));
                if (csAddOrUpdate != null)
                {
                    csAddOrUpdate.VALUE = (chkPrint.Checked ? "1" : "");
                }
                else
                {
                    csAddOrUpdate = new HIS.Desktop.Library.CacheClient.ControlStateRDO();
                    csAddOrUpdate.KEY = ControlStateConstan.chkPrint;
                    csAddOrUpdate.VALUE = (chkPrint.Checked ? "1" : "");
                    csAddOrUpdate.MODULE_LINK = moduleLink;
                    if (this.currentControlStateRDO == null)
                        this.currentControlStateRDO = new List<HIS.Desktop.Library.CacheClient.ControlStateRDO>();
                    this.currentControlStateRDO.Add(csAddOrUpdate);
                }
                this.controlStateWorker.SetData(this.currentControlStateRDO); 
                WaitingManager.Hide();
            }
            catch (Exception ex)
            {
                WaitingManager.Hide();
                Inventec.Common.Logging.LogSystem.Warn(ex);
            }
        }

Class ControlStateConstan khai báo như sau

	internal class ControlStateConstan
    {
        internal const string chkPrint = "chkPrint";
        internal const string chkSign = "chkSign";
        internal const string chkPrintDocumentSigned = "chkPrintDocumentSigned";
    }

Tương tự các nút check khác đều cần có sự kiện này

Release module sau khi đã code xong

Checkout svn test của phần mềm đang phát triển về.

Vd: phần mềm Bệnh viện HIS sẽ có svn test tương ứng là: https:// 14.232.245.104/svn/IMSys/FE/YTE/DESKTOP/TEST

Trong mỗi folder svn TEST của mỗi phần mềm sẽ chia thành 2 folder x64 và x86 cho 2 phiên bản chạy trên win 32bit và win 64bit

Tổ chức các folder chuẩn trong bản release phần mềm sẽ như hình bên dưới

5

Trong đó:

  • Folder Intergrate: chứa các thành phần tích hợp vào phần mềm, độc lập
  • Folder Plugins: chứa các folder con
    • FrdProcessor: chứa các dll của các form động
    • Module: chứa dll của các module
    • MpsProcessor: chứa các dll của các nút in ấn
  • Folder ReferencedAssemblies: chứa các thư viện được sử dụng trong phần mềm & trong các module, form động và các chức năng in ấn

Khi build module để release

  • lấy file dll đã build ra copy vào trong folder Plugins>Module
  • lấy các thư viện sử dụng trong module copy vào folder ReferencedAssemblies nếu thư viện này chưa có trong folder này

Lưu ý:

  • Chỉ copy các file .dll, resources.dll, bỏ qua các file rác như .pdb, .xml để tránh làm rác phần mềm

  • Tuyệt đối tuân thủ quy tắc này để đảm bảo kiến trúc chuẩn của phần mềm

Tham khảo thêm video hướng dẫn trên svn:

https://14.232.245.104/svn/IMSys/DOCUMENT/VIDEO/HuongDanSuDungModuleDesktop.mp4