-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #33 from MrDave1999/feat/issue-32
feat: Add support for dependency injection via constructor
- Loading branch information
Showing
15 changed files
with
337 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Example.Contracts; | ||
|
||
public interface ITestService | ||
{ | ||
string Execute(); | ||
} |
10 changes: 10 additions & 0 deletions
10
samples/HostApplications/WebApi/Controllers/ServiceController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace Example.HostWebApi.Controllers; | ||
|
||
[ApiController] | ||
[Route("[controller]")] | ||
public class ServiceController | ||
{ | ||
[HttpGet] | ||
public ActionResult<string> Get(IEnumerable<ITestService> services) | ||
=> services.First().Execute(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
samples/Plugins/DependencyInjectionPlugin/Example.DependencyInjectionPlugin.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<OutDir>$(WebApiProjectDir)</OutDir> | ||
<OutputType>Library</OutputType> | ||
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile> | ||
</PropertyGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
global using Example.Contracts; | ||
global using CPlugin.Net; | ||
global using Example.DependencyInjectionPlugin; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
[assembly: Plugin(typeof(TestService))] | ||
|
||
namespace Example.DependencyInjectionPlugin; | ||
|
||
public class TestService : ITestService | ||
{ | ||
private readonly ILogger<TestService> _logger; | ||
private readonly IConfiguration _configuration; | ||
|
||
public TestService( | ||
ILogger<TestService> logger, | ||
IConfiguration configuration) | ||
{ | ||
_logger = logger; | ||
_configuration = configuration; | ||
} | ||
|
||
public string Execute() | ||
{ | ||
_logger.LogInformation("TestService"); | ||
return _configuration["ServiceName"]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using Microsoft.Extensions.DependencyInjection; | ||
using System.Reflection; | ||
|
||
namespace CPlugin.Net; | ||
|
||
/// <summary> | ||
/// Extension methods for adding services to an <see cref="IServiceCollection"/>. | ||
/// </summary> | ||
public static class CPluginServiceCollectionExtensions | ||
{ | ||
/// <summary> | ||
/// Adds the subtypes that implement the contract specified by <typeparamref name="TSupertype"/> | ||
/// to the service collection, using the assemblies loaded by <see cref="PluginLoader"/>. | ||
/// </summary> | ||
/// <typeparam name="TSupertype"> | ||
/// The type of contract (base type) shared between the host application and the plugins. | ||
/// </typeparam> | ||
/// <param name="services"> | ||
/// The <see cref="IServiceCollection"/> to add the service to. | ||
/// </param> | ||
/// <param name="serviceLifetime"> | ||
/// Specifies the lifetime of the services to be added to the service collection. | ||
/// </param> | ||
/// <remarks> | ||
/// This method uses the <see cref="PluginAttribute"/> type to add the implementations of the contract | ||
/// to the service collection, so plugins must use it. | ||
/// </remarks> | ||
/// <returns> | ||
/// A reference to this instance after the operation has completed. | ||
/// </returns> | ||
public static IServiceCollection AddSubtypesOf<TSupertype>( | ||
this IServiceCollection services, | ||
ServiceLifetime serviceLifetime) where TSupertype : class | ||
=> services.AddSubtypesOf<TSupertype>(PluginLoader.Assemblies, serviceLifetime); | ||
|
||
// This method is only to be used for testing. | ||
// This way you don't have to depend on the plugin loader when testing. | ||
internal static IServiceCollection AddSubtypesOf<TSupertype>( | ||
this IServiceCollection services, | ||
IEnumerable<Assembly> assemblies, | ||
ServiceLifetime serviceLifetime) where TSupertype : class | ||
{ | ||
if (assemblies is null) | ||
throw new ArgumentNullException(nameof(assemblies)); | ||
|
||
foreach (Assembly assembly in assemblies) | ||
{ | ||
var pluginAttributes = assembly.GetCustomAttributes<PluginAttribute>(); | ||
foreach (PluginAttribute pluginAttribute in pluginAttributes) | ||
{ | ||
Type implementationType = pluginAttribute.PluginType; | ||
if (typeof(TSupertype).IsAssignableFrom(implementationType)) | ||
{ | ||
services.AddService( | ||
serviceType: typeof(TSupertype), | ||
implementationType, | ||
serviceLifetime); | ||
} | ||
} | ||
} | ||
|
||
return services; | ||
} | ||
|
||
private static IServiceCollection AddService( | ||
this IServiceCollection services, | ||
Type serviceType, | ||
Type implementationType, | ||
ServiceLifetime serviceLifetime) => serviceLifetime switch | ||
{ | ||
ServiceLifetime.Singleton => services.AddSingleton(serviceType, implementationType), | ||
ServiceLifetime.Transient => services.AddTransient(serviceType, implementationType), | ||
ServiceLifetime.Scoped => services.AddScoped(serviceType, implementationType), | ||
_ => throw new NotSupportedException($"Lifetime '{serviceLifetime}' is not supported.") | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.