首页 > 代码库 > LCLFramework框架之Plugin模式
LCLFramework框架之Plugin模式
Plugin模式在示例中的实际目的小结一下
- Plugin模式是架构模式,在设计架构时,才有参考价值;
- Plugin模式主要是实现单一职责的封装,和扩展应用程序;
Plugin与扩展的区别
插件稍不同于扩展(extension),插件通常依赖于主应用程序的接口,有一个它们可以运行的确定的界限。扩展则通常有更少的限制,也可以提供它们自己的接口。相同的是,它们通常都用来减少主应用程序的大小、提供一些可选的功能。
这里不得不提到Mozilla Firefox 和相关软件。它们使用一个叫做Add-on的名词,Add-on又被细分为插件、主题(theme)、搜索引擎(search engine)和扩展。在以后的文章中将会提到Mozilla插件和古老的NPAPI的渊源,以及firefox中插件和扩展的区别。
LCLFramework框架之Plugin设计
LCLFramework框架之Plugin模式主要是参考http://www.cnblogs.com/zgynhqf/p/3356692.html框架来的。
LCLFramework框架之Plugin模式设计代码
/// <summary>
/// 插件定义。
/// </summary>
public interface IPlugin
{
/// <summary>
/// 插件的启动级别
/// </summary>
int SetupLevel { get; }
/// <summary>
/// 插件的初始化方法。
/// 框架会在启动时根据启动级别顺序调用本方法。
///
/// 方法有两个职责:
/// 1.依赖注入。
/// 2.注册 app 生命周期中事件,进行特定的初始化工作。
/// </summary>
/// <param name="app">应用程序对象。</param>
void Initialize(IApp app);
}
public abstract class LCLPlugin : IPlugin
{
/// <summary>
/// 插件的启动级别。
/// </summary>
protected virtual int SetupLevel
{
get { return ReuseLevel.Main; }
}
/// <summary>
/// 插件的初始化方法。
/// 框架会在启动时根据启动级别顺序调用本方法。
/// 方法有两个职责:
/// 1.依赖注入。
/// 2.注册 app 生命周期中事件,进行特定的初始化工作。
/// </summary>
/// <param name="app">应用程序对象。</param>
public abstract void Initialize(IApp app);
int IPlugin.SetupLevel
{
get { return this.SetupLevel; }
}
}
/// <summary>
/// 表示某一个插件程序集
/// </summary>
[DebuggerDisplay("{Assembly.FullName}")]
public class PluginAssembly
{
public static readonly IPlugin EmptyPlugin = new _EmptyPlugin();
public PluginAssembly(Assembly assembly, IPlugin instance)
{
this.Instance = instance;
this.Assembly = assembly;
}
/// <summary>
/// 程序集当中的插件对象。
/// 如果插件中没有定义,则此属性为 null。
/// </summary>
public IPlugin Instance { get; private set; }
/// <summary>
/// 程序集本身
/// </summary>
public Assembly Assembly { get; private set; }
private class _EmptyPlugin : LCLPlugin
{
protected override int SetupLevel
{
get { return PluginSetupLevel.System; }
}
public override void Initialize(IApp app)
{
//TODO:组件初始化
var plugins = LEnvironment.GetAllPlugins();
foreach (var plugin in plugins)
{
DomainServiceLocator.TryAddAssemblyService(plugin.Assembly);
}
}
}
}
/// <summary>
/// 插件环境
/// PluginEnvironment
/// </summary>
public partial class LEnvironment
{
private const string DomainPluginFolder = "Library";
#region 启动 Plugins
private static bool _initialized;
private static void CheckUnInit()
{
if (_initialized) throw new NotSupportedException("框架已经初始化完成!");
}
internal static void NotifyIntialized()
{
_initialized = true;
}
/// <summary>
/// 启动所有的 插件
/// </summary>
/// <param name="app"></param>
internal static void StartupPlugins()
{
CheckUnInit();
var libraries = GetAllPlugins();
foreach (var pluginAssembly in libraries)
{
//调用 ILibrary
var library = pluginAssembly.Instance as LCLPlugin;
if (library != null) library.Initialize(_appCore);
}
}
#endregion
#region 获取所有 Plugins
private static IEnumerable<PluginAssembly> _libraries;
/// <summary>
/// 获取当前环境被初始化的所有插件。
/// </summary>
/// <returns></returns>
public static IEnumerable<PluginAssembly> GetAllPlugins()
{
return GetDomainPlugins().Union(GetUIPlugins()).OrderBy(a => a.Instance.SetupLevel);
}
public static Assembly[] GetAllPluginAssemblys()
{
var plugAssembly = GetAllPlugins().ToArray();
Assembly[] list = new Assembly[plugAssembly.Count()];
for (int i = 0; i < plugAssembly.Count(); i++)
{
list[i] = plugAssembly[i].Assembly;
}
return list;
}
/// <summary>
/// 找到当前程序所有可运行的领域实体插件。
/// </summary>
/// <returns></returns>
public static IEnumerable<PluginAssembly> GetDomainPlugins()
{
if (_libraries == null)
{
var assemblies = EnumerateAllDomainAssemblies().Union(PluginTable.Libraries).ToArray();
_libraries = LoadPlugins(assemblies);
PluginTable.Libraries.Lock();
}
return _libraries;
}
private static IEnumerable<Assembly> EnumerateAllDomainAssemblies()
{
yield return LoadLCLAssembly("LCL");
foreach (var file in EnumerateAllDomainPluginFiles())
{
yield return Assembly.LoadFrom(file);
}
}
private static IEnumerable<string> EnumerateAllDomainPluginFiles()
{
//查找Library目录下的所有程序集
string libraryPath = MapDllPath(DomainPluginFolder + "\\");
if (Directory.Exists(libraryPath))
{
foreach (var dll in Directory.GetFiles(libraryPath, "*.dll"))
{
yield return dll;
}
}
}
private static Assembly LoadLCLAssembly(string name)
{
var aName = typeof(LEnvironment).Assembly.GetName();
aName.Name = name;
return Assembly.Load(aName);
}
/// <summary>
/// 找到当前程序所有可运行的界面插件程序集。
/// </summary>
/// <returns></returns>
public static IEnumerable<PluginAssembly> GetUIPlugins()
{
return Enumerable.Empty<PluginAssembly>();
}
private static List<PluginAssembly> LoadPlugins(IEnumerable<Assembly> assemblies)
{
return assemblies.Select(assembly =>
{
var pluginType = assembly.GetTypes().FirstOrDefault(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
IPlugin pluginInstance = PluginAssembly.EmptyPlugin;
if (pluginType != null)
{
pluginInstance = Activator.CreateInstance(pluginType) as IPlugin;
}
return new PluginAssembly(assembly, pluginInstance);
})
//这里按照产品 721 进行排序。
.OrderBy(a => a.Instance.SetupLevel)
.ToList();
}
#endregion
#region RootType
private static List<Type> _allRootTypes;
/// <summary>
/// 遍历系统中存在的所有聚合根类型
/// </summary>
/// <returns></returns>
internal static IList<Type> GetAllRootTypes()
{
if (_allRootTypes == null)
{
var result = new List<Type>();
foreach (var plugin in GetAllPlugins())
{
foreach (var type in plugin.Assembly.GetTypes())
{
if (IsRootType(type)) result.Add(type);
}
}
_allRootTypes = result;
}
return _allRootTypes;
}
internal static bool IsRootType(Type entityType)
{
if (entityType.BaseType == typeof(DomainEntity))
return true;
else
return false;
}
#endregion
}
/// <summary>
/// 使用代码添加的插件程序集。
/// 只是以插件机制加载,但本质上是必需的,并非插件。
/// </summary>
public class PluginTable : Collection<Assembly>
{
private static PluginTable _domainLibraries = new PluginTable();
/// <summary>
/// 已经添加的实体插件程序集。
/// </summary>
public static PluginTable Libraries
{
get { return _domainLibraries; }
}
/// <summary>
/// 直接添加一个插件对应的程序集引用。
/// </summary>
/// <typeparam name="TPlugin"></typeparam>
public void AddPlugin<TPlugin>()
where TPlugin : IPlugin
{
this.Add(typeof(TPlugin).Assembly);
}
private bool _locked;
protected override void ClearItems()
{
this.EnsureWritable();
base.ClearItems();
}
protected override void RemoveItem(int index)
{
this.EnsureWritable();
base.RemoveItem(index);
}
protected override void InsertItem(int index, Assembly item)
{
if (!this.Contains(item))
{
this.EnsureWritable();
base.InsertItem(index, item);
}
}
protected override void SetItem(int index, Assembly item)
{
if (!this.Contains(item))
{
this.EnsureWritable();
base.SetItem(index, item);
}
}
internal void Lock()
{
this._locked = true;
}
private void EnsureWritable()
{
if (this._locked) throw new InvalidOperationException("集合不可再变更。");
}
}
/// <summary>
/// 产品的 “721” 重用级别
/// </summary>
public static class ReuseLevel
{
/// <summary>
/// 主版本(7)
/// </summary>
public const int Main = 100;
/// <summary>
/// 部分版本(2)
/// </summary>
public const int Part = 200;
/// <summary>
/// 客户化版本(1)
/// </summary>
public const int Customized = 300;
}
/// <summary>
/// LCL 中的其它插件启动级别。
/// </summary>
public static class PluginSetupLevel
{
/// <summary>
/// LCL 系统级别的重用级别,一般不要使用。
/// </summary>
public const int System = -1;
}
LCLFramework框架之Plugin开发
LCLFramework框架之Plugin模式