大佬教程收集整理的这篇文章主要介绍了在.NET Core中使用简单的插件化机制,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
<h2 id="前言">前言
插件化,其实也并不是什么新东西了,像nopCommerce等开源项目都有类似的机制,而且功能比较完善和齐全。
相信大家都对接过不少支付方式,支付宝、微信以及各大银行或第三方的支付公司。
我们可以把支付相关的操作抽象出来,无非就是支付,异步回调,退款,查询等几个重要的操作。
这个时候我们可以将各种支付方式都做为一个插件,这些插件都实现上面的操作,这样我们整合一个入口,去加载相应的插件即可。
这个入口常规情况就是MVC或者是WEB API。
下面来实现一个简单的例子。
首先建立一个公共的插件抽象类,简单起见,里面就包含一个无参的抽象方法Handle,这个方法就像上面提到的支付,退款等操作。
每一个新的插件都必须要继承这个抽象类并且实现这个抽象方法!
public abstract class BasePluginsservice { public abstract String Handle(); }
假设现在有两个插件AA和BB,我们会把AA和BB各建一个类库。
其中,AA的就只是返回了AA相关的字符串。
public class Pluginsservice : Common.basePluginsservice { public override String Handle() { return "Plugins.AA"; } }
BB的也同样只是返回了BB相关的字符串。
public class Pluginsservice : Common.basePluginsservice { public override String Handle() { return "Plugins.bB"; } }
接下来,主要还是我们的入口,Web项目的处理。
在入口处的处理主要是利用反射去确实要调用那个插件里面的Handle方法。
下面是获取相应插件实例的方法。
private async Task@H_450_46@ GetPlugin(String typE) { String cacheKey = $"plugin:{typE}"; //先尝试从缓存中取 if (_cache.TryGetValue(cacheKey,out Common.basePluginsservice servicE)) { return service; } else { var baseDirectory = Directory.GetCurrentDirectory(); var dll = $"Plugins.{typE}.dll"; //Plugins的完整路径 var path = Path.Combine(baseDirectory,_options.PluginsPath,dll); try { //预防无法更新dll byte[] bytes = await System.IO.File.ReadAllBytesAsync(path); var assembly = Assembly.Load(bytes); //创建实例 var obj = (Common.basePluginsservicE)assembly.CreateInstance($"Plugins.{typE}.Pluginsservice");if (obj != null) { _cache.Set(cacheKey,obj,datetiR_701_11845@eOffset.Now.AddSeconds(60)); } return obj; } catch (Exception) { return null; } }
}
这里主要有下面两个操作
一、 缓存反射结果
为了避免每次获取插件都去进行反射操作,这里引用了MemoryCache来缓存了反射的结果。
关于缓存,这里需要注意一个问题,缓存的时间!这个对新增加一个插件是没有什么影响,但是对修改一个已经存在的插件就影响比较大了!
缓存时候过长会导致没有办法实时出现修改的效果,可以考虑缓存比较短的时间。
二、 动态替换dll
为了避免出现对一个现存的插件修改之后,无法正常替换的情形,往往提示的是正常使用。需要做一些处理,避免一直占用这个资源!
最后就是Action的操作了。
[httpGet] public async TaskGetAsync(String typE) { if (String.IsNullOrWhiteSpace(typE)) { return "type is empty"; } var plugin = await this.GetPlugin(typE); if (plugin != null) { return plugin.Handle(); } return "default";
}
到这里,基本就完成了。
先来看看项目的大致框架:
title="在.NET Core中使用简单的插件化机制" alt="在.NET Core中使用简单的插件化机制" src="https://cn.js-code.com/res/2019/02-08/23/c5f54ff2a573b407ec9d16647c35840d.png">
我们是将所有的插件放到Plugins这个项目文件中的。Web项目并不直接引用Plugins下面的项目。
运行时是动态加载指定目录里面的dll,然后完成调用的。
下面简单来看看效果:
title="在.NET Core中使用简单的插件化机制" alt="在.NET Core中使用简单的插件化机制" src="https://cn.js-code.com/res/2019/02-08/23/322eb73e4a7b2a391a29f05d16096f1a.gif">
通过修改type达到选择不同插件的效果,然后对某个插件进行修改之后,也能正常替换和生效。
当然,实际中可能并没有那么直接就能拿type,而是是要根据传进来的参数去搜一下数据库,然后才能拿到type。这也完全取决于不同的设计。
插件化机制,可以简单的认为是反射的一个实际应用,这个已经能满足不少常规性的要求了。
但是完整的插件化还有诸多要考量的东西,这个可以参考nop的实现。
它还是有不少好处的,个人认为,最主要的还是隔离了不同的插件,将它们之间相互影响的可能性降低。
最后附上本文的示例Demo:
https://github.com/catcherwong/Demos/tree/master/src/PluginsDemo">PluginsDemo
以上是大佬教程为你收集整理的在.NET Core中使用简单的插件化机制全部内容,希望文章能够帮你解决在.NET Core中使用简单的插件化机制所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。