受欢迎的博客标签

Plug-in architecture in ASP.NET Core

Published

Plugins can have dependencies. For example, a plugin to do payment via Stripe depends on Stripe SDK. With normal ASP.NET Core application it is not a problem, but with this plug-in architecture, it is the big challenge

First, in order to make sure that it is safe to remove a plugin, avoiding DLL hell problem, we put all the dependencies of a plugin and the plugin itself into a separate folder. When a plugin is no longer need, we can simply delete its folder. Checkout the article Modular Web Application with ASP.NET Core to see how we archive this. You can think a module is a plugin.

Second, because we want to offer installing plugins at runtime, plugins cannot be added as a project reference to the main application, so they aren’t loaded natively by the .NET Core runtime. We have to manually load them along with their dependencies.

In .NET Core dependencies are managed by adding package references, a referenced package then can depend on other packages and so on. They are all nuget packages. These nuget packages are not stored in our solution but in a global packageFolders. In Windows, it is C:\Users<username>.nuget\packages. During the complication assemblies of referenced packages are not copied to the output folder, they are tracked in the deps.json instead.

There is a flag property called ‘CopyLocalLockFileAssemblies’ in the project file (.csproj), when you turn it on, it will copy all the dependencies of the project during the compile time, including all the System, Microsoft.AspNetCore assemblies and they are too much.

So how to include only assemblies we need for a plugin? I have found 3 workarounds to archive this.

The first workaround: turn CopyLocalLockFileAssemblies on and write a custom MSBuild task to delete redundant assemblies such as System.* or Microsoft.AspNetCore.* assemblies. The downside of this workaround is that it is hard to track the list of assemblies need to delete, and the build time is slow.

The second workaround: make some treats in the project file (.csproj) to copy some particular assemblies we need. For example, the case of Stripe. In the project file, in the PropertyGroup section we add a property to store the Stripe version

https://codetherapist.com/blog/netcore3-plugin-system/