core bootstrap plugins - grecosoft/NetFusion GitHub Wiki
The role of a plugin within the bootstrap process is as follows:
- Provides metadata values for required and optional properties used to describe the plugin
- Adds one or more Plugin Modules containing its implementation
- Adds an optional default configuration that can be overridden by the host when bootstrapped
- Adds any other Plugins on which it depends
If a plugin doesn't register any modules, no code specific to the plugin is executed. All plugin bootstrap logic is contained within one or more registered plugin modules.
A plugin is an project/assembly containing a class driving from PluginBase.
This topic will illustrate the properties of a Plugin by discussing the code created from the NetFusion microservice template. The solution generated from the template is based on NetFusion's plugin architecture structured after microservice best practices. Details about the microservice template can be found under the templates section.
The microservice solution created in this topic will be used to illustrate all topics under the NetFusion-Core section. Each bootstrapping and module topic will add example classes to the solution. The completed code added by all topics under the NetFusion-Core section can be found here:
NetFusion-Examples/Examples/Source/Examples.Bootstrapping
Execute the following command to install the NetFusion.Templates NuGet package:
dotnet new install NetFusion.Templates
Then execute the following to generate a microservice solution:
mdkir Examples.Bootstrapping
cd Examples.Bootstrapping
dotnet new netfusion-microservice --port 5009
The following shows the generated solution:
Each project that is a plugin defines a class deriving from the PluginBase as follows:
using Examples.Bootstrapping.App.Plugin.Configs;
using NetFusion.Core.Bootstrap.Plugins;
using Examples.Bootstrapping.App.Plugin.Modules;
namespace Examples.Bootstrapping.App.Plugin;
public class AppPlugin : PluginBase
{
public override string PluginId => "FA2A1F82-471C-44D0-A56C-01A7163D71C2";
public override PluginTypes PluginType => PluginTypes.AppPlugin;
public override string Name => "Application Services Component";
public AppPlugin()
{
AddModule<ServiceModule>();
Description = "Plugin component containing the Microservice's application services.";
}
}
The above class shows a definition of a plugin. A plugin has the following properties:
Property | Description |
---|---|
PluginId | String value that must be unique among all plugins added to the composite-container. This value will be shown in the logs to uniquely identify the associated plugin. The PluginId of the Host Plugin can also be use by other plugins to identity the owning microservice of objects it creates. |
PluginType | Enumerated value used to classify the type of plugin. |
Name | Short name used to identify the plugin. |
Description | Optional description of the plugin. |
SourceUrl | Optional URL to the plugin's source. |
DocUrl | Optional URL to the plugin's documentation. |
A Plug-in can be classified as one of the following types:
- HostPlugin: The assembly representing the application host. Typically a WebApi or Console project. A solution can only have one defined host plugin.
- AppPlugin: One or more assemblies containing application specific logic.
- CorePlugin: One or more assemblies containing reusable infrastructure components.
The type of a plugin determines the scope of components defined within an assembly. Core plugins implement infrastructure components that can be used by other core, application, or host plugins. Core plugins will often be used by multiple microservices whereas application plugins contain components specific to a microservice. Additional differences between application and core plugins will be noted in the Plugin Modules section.
The most common examples of hosts are the WebApi and Console project types. The microservice solution created by the template consists of the following projects:
Project | Description |
---|---|
Examples.Bootstrapping.WebApi | WebApi project containing a plugin definition of type HostPlugin. Contains the API exposed by the microservice. |
Examples.Bootstrapping.Domain | Class library containing a plugin definition of type AppPlugin. Contains classes specific to the domain implemented by the microservice. |
Examples.Bootstrapping.App | Class library containing a plugin definition of type AppPlugin. Contains classes specific to the application required to implement the domain. Often contains command and domain-event handlers, business services, and repository contracts. |
Examples.Bootstrapping.Infra | Class library containing a plugin definition of type AppPlugin. Contains implementation specific classes such as repositories and other classes that are associated with a specific implementation technology. |
Examples.Bootstrapping.Tests | An XUnit test project containing unit-tests for classes contained in the above projects. A test project is not referenced as part of the solution and therefore does not have a plugin definition. |
As shown above, the microservice generated solution does not define any projects classified as CorePlugin types. Typically projects classified as CorePlugin types implement cross-cutting concerns used by many microservices. For example, the NetFusion.Integration.ServiceBus project is a core plugin since it extends the base messaging pipeline and can be used by multiple microserivces for integration.
However, this section will show adding a CorePlugin project to the solution since it will be needed for upcoming topics. The below steps are done from the command line so not specific to any given IDE. However, you can use the IDE of your choice to complete the same.
Add a new project to the solution that will be classified as a CorePlugin:
# Create Project:
cd Examples.Bootstrapping
mkdir ./src/Components/Examples.Bootstrapping.CrossCut
dotnet new classlib -o ./src/Components/Examples.Bootstrapping.CrossCut
# Add Project to Solution:
dotnet sln ./src/Examples.Bootstrapping.sln add ./src/Components/Examples.Bootstrapping.CrossCut/Examples.Bootstrapping.CrossCut.csproj
# Add Reference to WebApi Project:
dotnet add ./src/Examples.Bootstrapping.WebApi reference ./src/Components/Examples.Bootstrapping.CrossCut/Examples.Bootstrapping.CrossCut.csproj
# Add Bootstrap related NetFusion NuGets:
dotnet add ./src/Components/Examples.Bootstrapping.CrossCut/Examples.Bootstrapping.CrossCut.csproj package NetFusion.Core.Bootstrap
Add the following plugin class definition to the following directory: ./src/Components/Examples.Bootstrapping.CrossCut/Plugin
using NetFusion.Core.Bootstrap.Plugins;
namespace Examples.Bootstrapping.CrossCut.Plugin;
public class AppPlugin : PluginBase
{
public override string PluginId => "7332C55B-E64C-430C-8836-488787CAC875";
public override PluginTypes PluginType => PluginTypes.CorePlugin;
public override string Name => "Cross-Cut Component";
public AppPlugin()
{
Description = "Example of a core plugin";
}
}
The plugin must be added to the compose-container when the host is bootstrapped to participate in the bootstrap process. Open the Program.cs file contained within the following location: ./src/Examples.Bootstrapping.WebApi/Program.cs and add the following line of code:
.AddPlugin<CrossCutPlugin>()
// Add Plugins to the Composite-Container:
builder.Services.CompositeContainer(builder.Configuration, new SerilogExtendedLogger())
.AddSettings()
.AddPlugin<CrossCutPlugin>() // <-- Add this line
.AddPlugin<InfraPlugin>()
.AddPlugin<AppPlugin>()
.AddPlugin<DomainPlugin>()
.AddPlugin<WebApiPlugin>()
.Compose();
The above code will be discussed in detail within the next topic.
A specific topic is dedicated to how plugin specific details are logged. However, by default all registered plugins are included within the log when the microservice is started. By default, the microservice generated solution is configured to use Serilog and write logs to Seq. The generated solution contains a Docker Compose file used to run SEQ locally in Docker.
Run SEQ in Docker by executing the following:
cd seq
docker-compose up -d
cd ..
Open the following URL within a browser: http://localhost:8051
Start the microservice within your IDE or by execution the following at the command line:
cd ./src/Examples.Bootstrapping.WebApi
dotnet run
Refresh the Web browser to view the logs written when bootstrapped. The added core plugin will be shown in the log:
Expand the following log entry associated with the Cross-Cut plugin that was just added: "CorePlugin Cross-Cut Component Composed" to view the details of the plugin. Additional logs will be written when modules are added to the plugin as shown in an upcoming topic.
The next topic will show adding modules to a plugin which contains the code executed when the microservice is bootstrapped.