///*************************************************************************/
///*
///* 文件名 :ModuleLoader.cs
///* 程序说明 : 模块加载器
///* 原创作者 :孙中吕
///*
///* Copyright 2006-2021 C/S框架网 www.csframework.com
///*
///**************************************************************************/
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
namespace CSFrameworkV5.Core
{
#region 模块加载器
///
/// 模块加载器基类
///
public class ModuleLoaderBase
{
///
/// 模块文件名(DLL文件)
///
protected string _ModuleFileName;
///
/// 如果加载了模块,返回该模块的主窗体对象.
///
protected IModuleBase _ModuleMainForm;
///
/// 模块所在的程序集
///
protected Assembly _ModuleAssembly;
///
/// 模块所在的程序集
///
public Assembly ModuleAssembly => _ModuleAssembly;
///
/// 返回当前模块的名称,从AssemblyModuleEntry自定义特性内获取信息。
///
public string GetCurrentModuleName(Assembly asm)
{
return GetModuleEntry(asm).ModuleName;
}
///
/// 模块主窗体
///
public IModuleBase ModuleMainForm => _ModuleMainForm;
///
/// 加载模块的菜单(支持一个模块内有多个顶级菜单)
///
/// 程序主窗体的菜单
public virtual void LoadMenu(MenuStrip moduleMenus)
{
var moduleMenu = _ModuleMainForm.GetModuleMenu(); //当前模块的菜单
if (moduleMenu == null || moduleMenu.Items.Count == 0) return;
if (_ModuleMainForm != null)
while (moduleMenu.Items.Count > 0) //加载所有顶级菜单
{
var startIndex = moduleMenus.Items.Count == 0
? 0
: moduleMenus.Items.Count;
moduleMenus.Items.Insert(startIndex, moduleMenu.Items[0]);
}
}
///
/// 加载模块主窗体
///
/// 模块信息
///
public virtual bool LoadModule(ModuleInfo moduleinfo)
{
_ModuleMainForm = null;
_ModuleFileName = moduleinfo.ModuleFile;
_ModuleAssembly = moduleinfo.ModuleAssembly;
//获取模块主窗体的命名空间
var entry = GetModuleEntryNameSpace(_ModuleAssembly);
if (string.Empty == entry) return false;
var form = (Form)_ModuleAssembly.CreateInstance(entry);
if (form is IModuleBase) _ModuleMainForm = (IModuleBase)form;
return _ModuleMainForm != null;
}
///
/// 枚举主程序所在目录下所有DLL文件,获取业务模块列表并转换为ModuleInfo集合.
///
/// 查找的文件扩展名
///
public virtual IList GetModuleList(string searchPattern)
{
IList list = new List();
try
{
var files = new string[] { }; //模块文件(*.dll)
var root = Application.StartupPath;
if (Directory.Exists(root))
files = Directory.GetFiles(root, searchPattern);
//for test
//File.WriteAllText(@"c:\cstest.txt", root + " " + searchPattern);
//枚举所有文件
foreach (var mod in files)
{
Assembly asm = null;
try
{
//加载.Net Framework DLL文件
asm = Assembly.LoadFile(mod);
}
catch
{
continue;
}
var id = GetModuleID(asm);
var name = GetCurrentModuleName(asm);
if (id != 0)
{
var m = new ModuleInfo(asm, id, name, mod);
list.Add(m);
}
}
SortModule(list); //模块排序.
return list;
}
catch (Exception ex)
{
return list;
}
}
///
/// 模块排序
///
///
public virtual void SortModule(IList list)
{
int i = 0, j = 1;
ModuleInfo temp;
var done = false;
while (j < list.Count && !done)
{
done = true;
for (i = 0; i < list.Count - j; i++)
if ((list[i] as ModuleInfo).ModuleID >
(list[i + 1] as ModuleInfo).ModuleID)
{
done = false;
temp = list[i];
list[i] = list[i + 1];
list[i + 1] = temp;
}
}
}
///
/// 将数据库获取的模块列表转换为ModuleInfo集合.
///
/// 数据库获取的模块列表
///
public virtual IList GetModuleList(DataTable fileList)
{
IList moduleList = new List();
try
{
var file = ""; //模块文件(*.dll)
var rs =
fileList.Select(" IsVisible='Y' ", " SortID ASC"); //模块可用和排序
foreach (var R in rs)
{
//检查文件是否存在
file = Application.StartupPath + "\\" +
R["FileName"].ToStringEx();
if (!File.Exists(file)) continue;
Assembly asm = null;
try
{
asm = Assembly.LoadFile(file);
}
catch
{
continue;
}
var id = GetModuleID(asm);
var name = GetCurrentModuleName(asm);
if (id != 0)
{
var m = new ModuleInfo(asm, id, name, file);
moduleList.Add(m);
}
}
return moduleList;
}
catch (Exception ex)
{
return moduleList;
}
}
///
/// 获取程序集的自定义特性。
///
///
public AssemblyModuleEntry GetModuleEntry()
{
return GetModuleEntry(_ModuleAssembly);
}
///
/// 通过检查Assembly定义的特性AssemblyModuleEntry,判断加载的文件是否业务模块文件。
/// 程序目录有不同类别的DLL文件,若没有定义AssemblyModuleEntry特性即不是业务模块。
///
public bool IsModuleFile(string moduleFile)
{
try
{
var asm = Assembly.LoadFile(moduleFile);
return GetModuleID(asm) != 0;
}
catch
{
return false;
}
}
///
/// 每个业务模块的主窗体定义一个TabPage与Panel, 将模块主窗体的Panel组件嵌套在主窗体的TabPage内。
///
public virtual void LoadGUI(object mainTabControl)
{
}
#region 类公共静态方法
///
/// 查找子菜单,深度搜索
///
public static ToolStripMenuItem GetMenuItem(ToolStrip mainMenu,
string menuName)
{
var items = mainMenu.Items.Find(menuName, true);
if (items.Length > 0 && items[0] is ToolStripMenuItem)
return (ToolStripMenuItem)items[0];
else
return null;
}
///
/// 获取程序集自定义特性。是否用户自定义模块由AssemblyModuleEntry特性确定。
///
public static AssemblyModuleEntry GetModuleEntry(Assembly asm)
{
var temp = new AssemblyModuleEntry(0, "", "");
if (asm == null) return temp;
var list =
asm.GetCustomAttributes(typeof(AssemblyModuleEntry), false);
if (list.Length > 0)
return (AssemblyModuleEntry)list[0];
else
return temp;
}
///
/// 获取模块主窗体名字空间
///
public static string GetModuleEntryNameSpace(Assembly asm)
{
return GetModuleEntry(asm).ModuleEntryNameSpace;
}
///
/// 获取模块编号
///
public static int GetModuleID(Assembly asm)
{
return GetModuleEntry(asm).ModuleID;
}
#endregion
///
/// 判断当前用户是否有该模块的权限
///
/// 用户权限数据
///
public bool CanAccessModule(DataTable userRights)
{
//管理员例外
if (Loginer.CurrentUser.IsAdmin()) return true;
var mainMenu = _ModuleMainForm.GetModuleMenu();
var rows = userRights.Select(string.Format("MenuName='{0}'",
mainMenu.Items[0].Name));
return rows != null && rows.Length > 0;
}
///
/// 程序集对象引用置空,优化GC回收内存
///
public void ClearAssemble()
{
_ModuleAssembly = null;
_ModuleMainForm = null;
}
}
#endregion
}