一起谈.NET技术,.NET动态调用DLL的方法

简介:   很多软件都是可插拔的,最知名的便是微软的Windows操作系统。你可以在Windows操作系统上安装QQ,也可卸掉QQ,这便是可插拔。这里不谈Windows的实现,因为太过复杂。本文就谈谈管理软件的可插拔的实现。

  很多软件都是可插拔的,最知名的便是微软的Windows操作系统。你可以在Windows操作系统上安装QQ,也可卸掉QQ,这便是可插拔。这里不谈Windows的实现,因为太过复杂。本文就谈谈管理软件的可插拔的实现。相对Windows操作系统,QQ就是它的一个插件。所以可以简单的将开发可插拔的软件分为两个部分。一个是主应用程序的开发,一个是插件的开发。

  比Windows小的,常见的可插拔的软件是MSN。MSN主应用程序由MS开发,还存在一些MSN插件开发商,国内好像也有不少,这些插件开发商通过在插件中植入广告获取利润。MS不可能提高源代码给这些开发商,那么MSN的主应用程序和MSN的插件是如何衔接起来的呢。我想应该是MS提供了一些接口和方法供开发商使用,估计有个api之类的东西,所以开发可插拔的应用系统分为三个部分。

  1、主应用程序的开发

  2、公用接口的开发

  3、插件的开发

  了解了这些以后,下面通过一个实例来说明。这个实例的原则是可扩展性强,能向下兼用。

  业务需求是:老系统每当逢年过节的时候,会通过邮件给用户发送一些祝福的邮件。现在流行手机和MSN(QQ没有借口)之后,客户希望系统能通过手机短信和MSN的消息给用户送去祝福。现在我们需要开发手机短信和MSN留言两个插件,然后将它们安装到系统中去。

  实现:

  为了简单起见,这里使用控制台应用程序,如果你有兴趣,可以修改成asp.net或者Windows Form的。

  定义两个接口:

public interface IPluginHost
{
void AddMenuItem(string name, MenuItemClickedHandler clickHandler);
void RegisterComponent<T>(T component) where T : class;
void MailNotice(string messaage);
}
public delegate void MenuItemClickedHandler(string name);

  这个接口是主应用程序继承的,现在只有MailNotice功能, AddMenuItem是供插件调用的方法,创建一个菜单。RegisterComponent是插件向主应用程序提供一些方法。

public interface IPlugin
{
void Initialize(IPluginHost pluginHost);
void DoSomething();
}

  上面是插件的接口。

  在主应用程序中有一个加载插件的地方。这里的插件是dll,所以我通过反射去加载这些dll。

public void LoadPlugin()
{
foreach (string fileName in Directory.GetFiles(Directory.GetCurrentDirectory() + "\\" + "Plugins", "*.dll"))
{
Assembly assembly = Assembly.LoadFile(fileName);
foreach (Type pluginType in assembly.GetTypes())
{
if (!pluginType.IsPublic || pluginType.IsAbstract || pluginType.IsInterface)
continue;
Type concreteType = pluginType.GetInterface(typeof(IPlugin).FullName, true);

if (concreteType != null)
{
IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType);
plugin.Initialize(this);
pluginList.Add(plugin);
break;
}
}
}
}

  主应用程序执行的代码如下:

void Start()
{
//邮件发送祝福
MailNotice("中秋快乐");
//加载插件
LoadPlugin();
//运行插件
if (pluginList.Count > 0)
{
foreach (IPlugin plugin in pluginList)
{
plugin.DoSomething();
}
}

Console.ReadLine();
}

  运行结果如下:

hhqqqq

  开发两个插件,都继承IPlugin。

  手机短信通知插件:

public class PluginA : IPlugin
{

public void Initialize(IPluginHost pluginHost)
{
IPluginHost myApplication = (IPluginHost)pluginHost;
myApplication.AddMenuItem("Click me", OnClick);

}
private void OnClick(string name)
{
Console.WriteLine("Omg! You clicked me!");
}

public void DoSomething()
{
Console.WriteLine("手机短信通知:中秋快乐");
}

}

  MSN通知插件:

public class PluginB : IPlugin
{

public void Initialize(IPluginHost pluginHost)
{
IPluginHost myApplication = (IPluginHost)pluginHost;
myApplication.AddMenuItem("Click me", OnClick);

}
private void OnClick(string name)
{
Console.WriteLine("Omg! You clicked me!");
}

public void DoSomething()
{
Console.WriteLine("MSN信息通知:中秋快乐");
}

}

  插件的目录如下图:

kkkyyy

  运行效果:

kkk444

  扩展性和兼容性:

  如果我想在主应用程序中添加一个ShowMessageBox方法。而且这个方法供插件调用。考虑到版本的兼容性,公开的接口是不能修改的。比如:将主应用程序的接口修改成:

public interface IPluginHost
{
void AddMenuItem(string name, MenuItemClickedHandler clickHandler);
void RegisterComponent<T>(T component) where T : class;
T GetComponent<T>() where T : class;
void MailNotice(string messaage);
void ShowMessageBox(string message);
}

  那么如何实现呢,很简单,使用依赖注入的方式。添加下面接口:

public interface IMessageBoxHost
{
void ShowMessageBox(string message);
}

  通过主应用程序的构造函数,将MessageBoxHost对下岗注入到主应用程序,在通过插件的构造函数,将其注入插件之中。

  主应用程序的构造函数:

public Program(IMessageBoxHost messageBoxHostInstance)
{
this.messageBoxHostInstance = messageBoxHostInstance;
}

  插件构造函数:

public PluginA(IMessageBoxHost messageBoxHost)
{
this.messageBoxHost = messageBoxHost;
}

  修改实例化插件的代码:

IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType, new object[] { messageBoxHostInstance });

  这样我们对版本兼容有了保障。

  总结:本文闲谈了可插拔应用程序的开发原理,文章的后面提供了插件和应用程序之间版本兼容的一种方案。有讨论才有进步,欢迎各位留言。

  参考:A Flexible Plugin System    A more extensible way to build plugin system

目录
相关文章
|
4天前
|
开发框架 算法 .NET
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
|
4天前
|
开发框架 Cloud Native .NET
C#/.NET/.NET Core技术前沿周刊 | 第 16 期(2024年12.01-12.08)
C#/.NET/.NET Core技术前沿周刊 | 第 16 期(2024年12.01-12.08)
|
2月前
|
开发框架 安全 .NET
在数字化时代,.NET 技术凭借跨平台兼容性、丰富的开发工具和框架、高效的性能及强大的安全稳定性,成为软件开发的重要支柱
在数字化时代,.NET 技术凭借跨平台兼容性、丰富的开发工具和框架、高效的性能及强大的安全稳定性,成为软件开发的重要支柱。它不仅加速了应用开发进程,提升了开发质量和可靠性,还促进了创新和业务发展,培养了专业人才和技术社区,为软件开发和数字化转型做出了重要贡献。
31 5
|
2月前
|
传感器 人工智能 供应链
.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。
本文深入探讨了.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。通过企业级应用、Web应用及移动应用的创新案例,展示了.NET在各领域的广泛应用和巨大潜力。展望未来,.NET将与新兴技术深度融合,拓展跨平台开发,推动云原生应用发展,持续创新。
46 4
|
2月前
|
机器学习/深度学习 人工智能 Cloud Native
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台。本文深入解析 .NET 的核心优势,探讨其在企业级应用、Web 开发及移动应用等领域的应用案例,并展望未来在人工智能、云原生等方面的发展趋势。
45 3
|
2月前
|
敏捷开发 缓存 中间件
.NET技术的高效开发模式,涵盖面向对象编程、良好架构设计及高效代码编写与管理三大关键要素
本文深入探讨了.NET技术的高效开发模式,涵盖面向对象编程、良好架构设计及高效代码编写与管理三大关键要素,并通过企业级应用和Web应用开发的实践案例,展示了如何在实际项目中应用这些模式,旨在为开发者提供有益的参考和指导。
39 3
|
2月前
|
开发框架 安全 Java
.NET技术的独特魅力与优势,涵盖高效的开发体验、强大的性能表现、高度的可扩展性及丰富的生态系统等方面,展示了其在软件开发领域的核心竞争力
本文深入探讨了.NET技术的独特魅力与优势,涵盖高效的开发体验、强大的性能表现、高度的可扩展性及丰富的生态系统等方面,展示了其在软件开发领域的核心竞争力。.NET不仅支持跨平台开发,具备出色的安全性和稳定性,还能与多种技术无缝集成,为企业级应用提供全面支持。
36 3
|
4天前
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
|
4月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
51 7
|
4月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
85 0