实例介绍
在.NET Core生态中,动态加载和执行代码作为应用程序的扩展功能是一个常见需求。这篇文章将介绍一个专门为.NET Core设计的库,它不仅支持.NET Core 2,而且在.NET Core 3及以上版本中提供了更佳的体验。该库允许对程序集隔离和类型共享进行细粒度控制。
从2018年开始,随着.NET Core 3的发布,微软官方也加入了改进程序集加载的标准库API。如果你对标准库API感兴趣,可以参考docs.microsoft.com上的“创建一个带插件的.NET Core应用程序”教程。而本文介绍的库提供了一些额外的特性,如跨加载上下文边界统一类型的API、热重载以及对.NET Core 2的支持。
要开始使用这个库,首先需要安装McMaster.NETCore.Plugins NuGet包。然后,你可以通过PluginLoader.CreateFromAssemblyFile方法来加载插件。
PluginLoader.CreateFromAssemblyFile( assemblyFile: "./plugins/MyPlugin/MyPlugin1.dll", sharedTypes: new [] { typeof(IPlugin), typeof(IServiceCollection), typeof(ILogger) }, isUnloadable: true)这里,assemblyFile参数指定插件的主.dll文件路径,sharedTypes参数列出了加载器应确保统一的类型列表,isUnloadable参数(仅.NET Core 3 支持)允许将来某个时刻从内存中卸载此插件。
在实际应用中,使用插件至少需要两个项目:(1)加载插件的'宿主'应用程序和(2)插件本身,通常还会使用第三个项目,即(3)定义插件和宿主之间交互的契约项目。更多详细的示例用法,可以参考samples/目录下的示例项目。
此外,本库还支持MVC和Razor页面的插件加载,通过McMaster.NETCore.Plugins.Mvc包可以实现。整个过程非常简单,只需在Startup.ConfigureServices方法中链式调用.AddPluginFromAssemblyFile()方法即可。
最后,关于反射的使用和默认加载上下文的覆盖,本文也提供了详细的指导和示例,帮助开发者更好地理解和运用这个库。
【实例截图】
文件清单
└── DotNetCorePlugins-26d9e0017825400fa2ef86631dc29e99298a02c8
├── build.ps1
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Directory.Build.props
├── docs
│ ├── design-doc.md
│ └── what-are-shared-types.md
├── DotNetCorePlugins.sln
├── LICENSE.txt
├── README.md
├── samples
│ ├── aspnetcore
│ │ ├── Abstractions
│ │ │ ├── Abstractions.csproj
│ │ │ ├── IPlugin.cs
│ │ │ └── IPluginLink.cs
│ │ ├── aspnetcore.sln
│ │ ├── MainWebApp
│ │ │ ├── MainWebApp.csproj
│ │ │ ├── Pages
│ │ │ │ ├── Index.cshtml
│ │ │ │ └── Index.cshtml.cs
│ │ │ ├── Program.cs
│ │ │ ├── Properties
│ │ │ │ └── launchSettings.json
│ │ │ └── Startup.cs
│ │ ├── README.md
│ │ ├── WebAppPlugin1
│ │ │ ├── WebAppPlugin1.csproj
│ │ │ └── WebPlugin1.cs
│ │ └── WebAppPlugin2
│ │ ├── WebAppPlugin2.csproj
│ │ └── WebPlugin2.cs
│ ├── aspnetcore-mvc
│ │ ├── aspnetcore-mvc.sln
│ │ ├── MvcApp
│ │ │ ├── Controllers
│ │ │ │ └── HomeController.cs
│ │ │ ├── MvcApp.csproj
│ │ │ ├── Program.cs
│ │ │ ├── Startup.cs
│ │ │ └── Views
│ │ │ ├── Home
│ │ │ │ └── Index.cshtml
│ │ │ └── _ViewImports.cshtml
│ │ ├── MvcAppPlugin1
│ │ │ ├── MvcAppPlugin1.csproj
│ │ │ ├── MyPluginController.cs
│ │ │ └── Views
│ │ │ └── MyPlugin
│ │ │ └── Index.cshtml
│ │ └── README.md
│ ├── dependency-injection
│ │ ├── DI.HostApp
│ │ │ ├── DI.HostApp.csproj
│ │ │ └── Program.cs
│ │ ├── DI.SharedAbstractions
│ │ │ ├── DI.SharedAbstractions.csproj
│ │ │ ├── Fruit.cs
│ │ │ ├── IFruitConsumer.cs
│ │ │ ├── IFruitProducer.cs
│ │ │ └── IPluginFactory.cs
│ │ ├── MyPlugin1
│ │ │ ├── MyFruitProducer.cs
│ │ │ ├── MyPlugin1.csproj
│ │ │ └── PluginConfiguration.cs
│ │ ├── MyPlugin2
│ │ │ ├── MyFruitConsumer.cs
│ │ │ ├── MyPlugin2.csproj
│ │ │ └── PluginConfiguration.cs
│ │ └── README.md
│ ├── dynamic-implementation
│ │ ├── Contracts
│ │ │ ├── Contracts.csproj
│ │ │ ├── Fruit.cs
│ │ │ ├── IFruitService.cs
│ │ │ ├── IMixerService.cs
│ │ │ └── IPluginFactory.cs
│ │ ├── DynamicImplementation.sln
│ │ ├── Host
│ │ │ ├── Host.csproj
│ │ │ └── Program.cs
│ │ ├── Mixer
│ │ │ ├── Mixer.csproj
│ │ │ ├── MixerPlugin.cs
│ │ │ ├── MixerService.cs
│ │ │ └── StandardFruiteService.cs
│ │ ├── README.md
│ │ └── ServiceImplementation
│ │ ├── OverrideFruiteService.cs
│ │ ├── OverridePlugin.cs
│ │ └── ServiceImplementation.csproj
│ ├── hello-world
│ │ ├── hello-world.sln
│ │ ├── HostApp
│ │ │ ├── HostApp.csproj
│ │ │ └── Program.cs
│ │ ├── MyPlugin
│ │ │ ├── MyPlugin1.cs
│ │ │ └── MyPlugin.csproj
│ │ ├── PluginContract
│ │ │ ├── IPlugin.cs
│ │ │ └── PluginContract.csproj
│ │ └── README.md
│ └── hot-reload
│ ├── HotReloadApp
│ │ ├── HotReloadApp.csproj
│ │ └── Program.cs
│ ├── hot-reload.sln
│ ├── README.md
│ ├── run.ps1
│ ├── run.sh
│ └── TimestampedPlugin
│ ├── InfoDisplayer.cs
│ └── TimestampedPlugin.csproj
├── src
│ ├── common.psm1
│ ├── Directory.Build.targets
│ ├── Plugins
│ │ ├── Internal
│ │ │ ├── Debouncer.cs
│ │ │ ├── PlatformInformation.cs
│ │ │ ├── RuntimeConfig.cs
│ │ │ └── RuntimeOptions.cs
│ │ ├── LibraryModel
│ │ │ ├── ManagedLibrary.cs
│ │ │ └── NativeLibrary.cs
│ │ ├── Loader
│ │ │ ├── AssemblyLoadContextBuilder.cs
│ │ │ ├── DependencyContextExtensions.cs
│ │ │ ├── ManagedLoadContext.cs
│ │ │ └── RuntimeConfigExtensions.cs
│ │ ├── McMaster.NETCore.Plugins.csproj
│ │ ├── PluginConfig.cs
│ │ ├── PluginLoader.cs
│ │ ├── PluginReloadedEventHandler.cs
│ │ ├── Properties
│ │ │ └── AssemblyInfo.cs
│ │ ├── PublicAPI.Shipped.txt
│ │ ├── PublicAPI.Unshipped.txt
│ │ └── releasenotes.props
│ ├── Plugins.Mvc
│ │ ├── McMaster.NETCore.Plugins.Mvc.csproj
│ │ ├── MvcPluginExtensions.cs
│ │ ├── PublicAPI.Shipped.txt
│ │ ├── PublicAPI.Unshipped.txt
│ │ └── releasenotes.props
│ └── StrongName.snk
└── test
├── Plugins.Tests
│ ├── BasicAssemblyLoaderTests.cs
│ ├── DebouncerTests.cs
│ ├── ManageLoadContextTests.cs
│ ├── McMaster.NETCore.Plugins.Tests.csproj
│ ├── PrivateDependencyTests.cs
│ ├── ShadowCopyTests.cs
│ ├── SharedTypesTests.cs
│ ├── TestProjectRefs.targets
│ └── Utilities
│ ├── TestProjectReferenceAttribute.cs
│ └── TestResources.cs
└── TestProjects
├── Banana
│ ├── Banana.cs
│ └── Banana.csproj
├── Directory.Build.props
├── DrawingApp
│ ├── DrawingApp.csproj
│ └── Finder.cs
├── JsonNet10
│ ├── Class1.cs
│ └── JsonNet10.csproj
├── JsonNet11
│ ├── Class1.cs
│ └── JsonNet11.csproj
├── JsonNet9
│ ├── Class1.cs
│ └── JsonNet9.csproj
├── NativeDependency
│ ├── NativeDependency.csproj
│ └── NativeDependencyLoader.cs
├── NetCoreApp2App
│ ├── NetCoreApp2App.csproj
│ └── Program.cs
├── NetStandardClassLib
│ ├── Class1.cs
│ └── NetStandardClassLib.csproj
├── Pl爐ano
│ ├── Pl爐ano.cs
│ ├── Pl爐ano.csproj
│ ├── Strings.Designer.cs
│ ├── Strings.es.Designer.cs
│ ├── Strings.es.resx
│ └── Strings.resx
├── PowerShellPlugin
│ ├── PowerShellPlugin.csproj
│ └── Program.cs
├── ReferencedLibv1
│ ├── Class1.cs
│ ├── IFruit.cs
│ └── ReferencedLibv1.csproj
├── ReferencedLibv2
│ ├── Class1.cs
│ └── ReferencedLibv2.csproj
├── SharedAbstraction.v1
│ ├── SharedAbstraction.v1.csproj
│ └── SharedType.cs
├── SharedAbstraction.v2
│ └── SharedAbstraction.v2.csproj
├── SqlClientApp
│ ├── Program.cs
│ └── SqlClientApp.csproj
├── Strawberry
│ ├── Strawberry.cs
│ └── Strawberry.csproj
├── TransitiveDep.v1
│ ├── TransitiveDep.v1.csproj
│ └── TransitiveSharedType.cs
├── TransitiveDep.v2
│ └── TransitiveDep.v2.csproj
├── TransitivePlugin
│ ├── PluginConfig.cs
│ └── TransitivePlugin.csproj
├── WithOurPluginsPluginA
│ ├── Class1.cs
│ └── WithOurPluginsPluginA.csproj
├── WithOurPluginsPluginB
│ ├── Class1.cs
│ └── WithOurPluginsPluginB.csproj
├── WithOurPluginsPluginContract
│ ├── ISayHello.cs
│ └── WithOurPluginsPluginContract.csproj
├── WithOwnPlugins
│ ├── WithOwnPlugins.cs
│ └── WithOwnPlugins.csproj
├── WithOwnPluginsContract
│ ├── IWithOwnPlugins.cs
│ └── WithOwnPluginsContract.csproj
└── XunitSample
├── Class1.cs
└── XunitSample.csproj
71 directories, 171 files
标签:
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论