Key Takeaways
- The plugin framework is a NuGet package that allows you to customise and extend a .NET application
- Plugins are loaded at runtime from a catalogue which can be a local source or via NuGet.
- Supports all the current .NET Core based applications, ranging from Blazor to ASP.NET Core and to Console, WPF and Windows Forms.
- Plugin-based software architecture can help in the following scenarios: adding new features to the application after the release, splitting large systems into smaller parts, giving end users and 3rd parties the ability to extend your application.
- Future development plans include tagging plugins to help support multiple different types of plugin in the same application and updating and unloading plugins on the fly.
The plugin framework is a NuGet package that allows you to customise and extend a .NET application at runtime. Code examples are provided for ASP.NET Core, Blazor, Console Apps and WPF & WinForms. The plugin framework package can be installed from NuGet and also supports the delivery of plugins from NuGet.
When you create your application and add support for Plugin Framework, you usually define two things:
1. The specifications for the plugins. In some applications a plugin can add new functionality into the UI. In other apps, plugins are used to distribute logs into multiple different systems. The application defines what kind of extensions it supports.
2. The locations where the application can find the plugins. Many applications use a specific "plugins"-folder to indicate the location where plugins should exist in the hard drive. In some situations plugins are installed in runtime from Nuget. These plugin locations are called catalogs. As a developer you define what catalogs your application uses.
The first stable version of plugin framework (1.0.0) was released earlier this month. InfoQ interviewed the author Mikael Koskinen to tells us more about it.
InfoQ: Mikael, thanks for creating this framework, plugins are an interesting approach to application development, why did you decide to create the plugin framework?
For me personally, plugin based software architectures are close to my heart. I wrote my master's thesis about .NET based plugin architectures about 15 years ago and I'm now doing my doctoral studies around plugins and containers. Things have changed quite much in the last 15 years in the Microsoft world as we have moved from .NET Framework and its AppDomains and CodeDoms to .NET Core, AssemblyLoadContext and Roslyn.
Plugin Framework was created as we wanted to provide the users of our platform a way to add new functionality runtime. At work we're creating an open source and .NET Core based platform called Weik.io for integration, eventing and automation. The original version of Weik.io was a Service Fabric based project and instead of plugins, we were using actors to dynamically modify the application runtime. For Weik.io v2 all the Service Fabric related code was removed and everything was rebuilt as separate .NET Core based projects. Support for plugins and Nuget packages was originally build directly into the new platform but as plugins and plugin based architectures are a generic concept, the decision was made to extract the plugin related code from the platform into its own project. This is how Plugin Framework was born.
Plugin Framework is the first Weik.io project out of the door. Api Framework ("Everything is an Open API"), Event Framework (CloudEvent gateway) and Function Framework (long-running durable tasks) are all nearing their release. All are open source and built on top of .NET Core and can be used independently. The common factor in all of these projects is that we want the developers and the users to be able to add new functionalities runtime and this functionality is provided using Plugin Framework.
InfoQ: What use cases did you have in mind when creating it?
"Developer friendly" and "easy to integrate". Those were the two main guidelines of the first release of Plugin Framework. As Plugin Framework is built on top of .NET Core, it supports all the current .NET Core based applications, ranging from Blazor to ASP.NET Core and to Console, WPF and Windows Forms. But as each of these platforms have their own specialities, we’ve tried to add platform specific extensions to make it easier to start using Plugin Framework.
The goal and concept of Plugin Framework is "Everything is a Plugin in .NET". Plugin Framework currently supports Nuget, Roslyn and delegate based plugins in addition to more regular ones like .NET assemblies and types.
The starting point was that we wanted the users of our platform to be able to add new functionality runtime, through Nuget. We wanted to support a scenario where the user of our integration platform could add new integration (for example SQL Server) runtime, by just installing a Nuget package, without having to restart the service at any point.
InfoQ: What limitations are there for what you could build with the framework? Is it good for all cases?
The main thing currently missing is a coherent story for updating and unloading plugins on the fly. One of the benefits of a well-designed plugin based architecture is that we can build 24/7 applications where features are added, removed and updated on the fly, without ever having to restart the application. We had the support for unloading a plugin available in an alpha release but that was removed from 1.0.0 as it didn't work as transparently as it should.
In addition to the update & unload features, the Nuget support needs some work. The package-specific plugin functionality works OK, but the Nuget feed specific features need to be extended. Currently, we only support finding plugins from a feed using a package's tag but we should add more search parameters like name and publisher.
We've tried to add as many samples as possible, from Blazor applications to WPF and Console apps and the developer story seems to be rather solid in all the supported platforms. But, each platform has its unique characteristics and there's always some room for improvement to make Plugin Framework a better citizen for each supported platform.
InfoQ: What advice do you have for designing the interactions between the application and plugin? Is there anything different from how a conventional programme is written?
Plugins are optional, that's the key thing. The application should start and work without any plugins. The plugins can't work without the application and they are application-specific and not meant to be shared between applications.
The application defines what kind of extensions it supports. Each extension point should accept 0-1 or 0-n plugins. For some applications, a plugin is a type which implements a specific interface. In some applications, a plugin is a type which has a single public method called Run. It's up to the application to define the requirements for the plugins.
InfoQ: What is next for the plugin framework? What are your further development plans?
We received a nice pull request for the Plugin Framework which allows the developer to configure the plugins using a configuration file. That's going to be available in 1.1.0. Additionally, we're working on adding a better story for "plugin tagging" and the goal is to include that one in the 1.1.0 release also. Tagging helps in scenarios where the application supports multiple kinds of plugins.
For the 2.0.0 release, the main thing is a good developer story for updating and unloading plugins on the fly.