ANT.NETCore.PluginLoader
2.0.0
See the version list below for details.
dotnet add package ANT.NETCore.PluginLoader --version 2.0.0
NuGet\Install-Package ANT.NETCore.PluginLoader -Version 2.0.0
<PackageReference Include="ANT.NETCore.PluginLoader" Version="2.0.0" />
<PackageVersion Include="ANT.NETCore.PluginLoader" Version="2.0.0" />
<PackageReference Include="ANT.NETCore.PluginLoader" />
paket add ANT.NETCore.PluginLoader --version 2.0.0
#r "nuget: ANT.NETCore.PluginLoader, 2.0.0"
#:package ANT.NETCore.PluginLoader@2.0.0
#addin nuget:?package=ANT.NETCore.PluginLoader&version=2.0.0
#tool nuget:?package=ANT.NETCore.PluginLoader&version=2.0.0
ANT.NETCore.PluginLoader
The purpose of this package is to facilitate using IOC on .NET Core 3.0+ and .NET Framework 4.6+ projects.
The .NET Core implentation uses DotNetCorePlugins by nate McMaster The .NET Framework implementation uses Microsoft Unity
========================================
Project Structure:
Ideally, any project that implements the plugins pattern should at least have a host project, which will reference this package and initiate the DI load, an abstractions project that contains any Interfaces to be shared between the host and the plugins and should be distributed to plugin developers, and n plugin projects that will export implementations for the shared interfaces.
========================================
Plugin Instructions:
- Add a reference to
System.ComponentModel.Compositionor install the NuGet package depending on the framework you're targetting. - Add the
Exportattribute to any classes that you wish to expose to the DI provider.
[Export(typeof(IMyInterface))]
public class MyInterfaceImplementation : IMyInterface
{
}
- Optionally, you might add a
contractNameparam to theExportattribute, this will create named instances and allow you to recall different implementations of the same interface (more on that later).
[Export("Foo", typeof(IMyInterface))]
public class MyInterfaceImplementationFoo : IMyInterface
{
}
[Export("Bar", typeof(IMyInterface))]
public class MyInterfaceImplementationBar : IMyInterface
{
}
- Optionally add the
PartCreationPolicyattribute to specify whether the class to be exported should be instantiated as a Singleton or Transient instance (Shared = Singleton, Nonshared = Transient).
[Export(typeof(IMyInterface))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class MyInterfaceImplementation : IMyInterface
{
}
- If you wish to export an instance of a configuration section (only for .Net Core), you can use the
contractNameparam of the Export attribute to declare it. Just begin the name of the contract with the word Configuration. and then the name of the configuration section. All configuration sections can be instanced using IOptions<> or by their class type.
appSettings.json file:
{
"MyConfigSectionName": {
"StringEntry": "String",
"NumericEntry": 42,
"BooleanEntry": false
}
}
class file:
[Export("Configuration.MyConfigSectionName")]
public class MyConfig
{
StringEntry { get; set; }
NumericEntry { get; set; }
BooleanEntry { get; set; }
}
calling constructor:
public MyConstructor(IOptions<MyConfig> myConfigOpts, MyConfig myConfigInstance)
{
string stringVal = myConfigOpts.Value.StringEntry;
int numericVal = myConfigInstance.NumericEntry;
}
- In order to export ASP.Net Core controllers (.Net Core only), just export your controller type. As long as it inherits from
Microsoft.AspNetCore.Mvc.ControllerorMicrosoft.AspNetCore.Mvc.ControllerBaseit'll be automatically wired into your host application.
using Microsoft.AspNetCore.Mvc;
[Export(typeof(CustomController))]
public class CustomController : Controller
{
}
- That's it for plugin development
========================================
.NET Core 3.0+ Host Instructions:
Example for ASP.Net Core:
- Use the
LoadDinamicallyextension method that's added toIServiceCollectionthe to setup DI, optionally pass you IConfiguration instance if you want to setup configuration classes:
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
// These shared types need to include any interfaces or types that the host and plugins share.
var sharedTypes = new[]
{
typeof(IMyInterface),
typeof(IMyOtherInterface)
};
services
.LoadDinamically(config, sharedTypes);
})
- If you wish to use Mvc and setup controllers developed on Plugins, use the
LoadDinamicallyextension method that's added toIMvcBuilderthe to setup DI, optionally pass you IConfiguration instance if you want to setup configuration classes:
// These shared types need to include any interfaces or types that the host and plugins share.
var sharedTypes = new[]
{
typeof(IMyInterface),
typeof(IMyOtherInterface)
};
services
.AddMvc()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ContractResolver = new DefaultContractResolver())
.LoadDinamically(Configuration, sharedTypes);
Example for Non-host console app:
static void Main(string[] args)
{
IServiceCollection serviceCollection = new ServiceCollection();
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var sharedTypes = new[]
{
typeof(IMyInterface),
typeof(IMyOtherInterface)
};
serviceCollection.LoadDinamically(config, sharedTypes);
var provider = serviceCollection.BuildServiceProvider();
IMyInterface instance = provider.GetService<IMyInterface>();
}
Loading Named Instances:
Sometimes you need to have different implementations of the same interface, for example when you have a Mock-Data-Access plugin vs your Database-Access plugin, in order to achieve it, just add a contractName param to the Export attribute (view part 3 of Plugin Instructions above), and use the IServiceResolver interface exposed on the ANT.NETCore.PluginLoader.Abstractions NuGet package
Note: This is possible to use in Host and Plugins.
private readonly IMyDataAccessService dataAccessService;
public MyController(IOptions<MyAppConfig> config, IServiceResolver<IMyDataAccessService> dataAccessServiceResolver)
{
string dataAccessPluginName = config.Value.DataAcessPlugin; //You can set on your appSettings.Development.json file to use the Mock plugin whereas on the production one use the actual DB connection
this.dataAccessService = dataAccessServiceResolver.GetService(dataAccessPluginName);
}
public List<object> GetFromDB() {
return this.dataAccessService.ReadSomethingFromDB();
}
========================================
.NET Framework 4.6+ Host Instructions:
Example for console app:
IUnityContainer unityContainer = ServiceLoader.LoadDependencies();
IMyInterface instance = unityContainer.Resolve<IMyInterface>();
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 is compatible. netcoreapp3.1 was computed. |
| .NET Framework | net46 is compatible. net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
-
.NETCoreApp 3.0
- ANT.NETCore.PluginLoader.Abstractions (>= 2.0.0)
- McMaster.NETCore.Plugins (>= 1.2.0)
- McMaster.NETCore.Plugins.Mvc (>= 1.2.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 3.1.1)
- Microsoft.Extensions.Configuration.Binder (>= 3.1.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 3.1.1)
- System.ComponentModel.Composition (>= 4.7.0)
-
.NETFramework 4.6
- Unity (>= 5.11.7)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
1.0.0: first release
1.1.0: allow loading MVC controllers
1.2.0: LoadDinamically methods now return the caller instance
2.0.0: Added Readme and IOC support for .Net Framework 4.6+ using Unity