Skip to content

Commit fb97ba8

Browse files
authored
Allow configuring default plugin that is returned from DI (weikio#40)
1 parent f9489a6 commit fb97ba8

File tree

5 files changed

+70
-8
lines changed

5 files changed

+70
-8
lines changed
Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System.Collections.Generic;
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using System.Text.Json;
24
using Microsoft.AspNetCore.Mvc;
35
using Weikio.PluginFramework.Samples.Shared;
46
using Weikio.PluginFramework.Abstractions;
@@ -11,19 +13,24 @@ public class CalculatorController : ControllerBase
1113
{
1214
private readonly IEnumerable<IOperator> _operators;
1315
private readonly IEnumerable<Plugin> _plugins;
16+
private readonly IOperator _defaultOperator;
1417

15-
public CalculatorController(IEnumerable<IOperator> operators, IEnumerable<Plugin> plugins, IOperator myOperator)
18+
public CalculatorController(IEnumerable<IOperator> operators, IEnumerable<Plugin> plugins, IOperator defaultOperator)
1619
{
1720
_operators = operators;
1821
_plugins = plugins;
22+
_defaultOperator = defaultOperator;
1923
}
2024

2125
[HttpGet]
2226
public string Get()
2327
{
24-
var pluginsList = string.Join(", ", _plugins);
25-
26-
return pluginsList;
28+
return JsonSerializer.Serialize(new
29+
{
30+
allPlugins = _plugins.Select(p => p.ToString()),
31+
operators = _operators.Select(o => o.GetType().Name),
32+
defaultOperator = _defaultOperator.GetType().Name
33+
}, new JsonSerializerOptions { WriteIndented = true});
2734
}
2835
}
2936
}

samples/WebApp/Startup.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
using Microsoft.Extensions.Hosting;
77
using Weikio.PluginFramework.Samples.Shared;
88
using Weikio.PluginFramework.Abstractions;
9+
using Weikio.PluginFramework.AspNetCore;
910
using Weikio.PluginFramework.Catalogs;
11+
using Weikio.PluginFramework.Samples.SharedPlugins;
1012

1113
namespace WebApp
1214
{
@@ -34,6 +36,18 @@ public void ConfigureServices(IServiceCollection services)
3436
// Alternatively
3537
// services.AddPluginFramework<IOperator>(@"..\Shared\Weikio.PluginFramework.Samples.SharedPlugins\bin\debug\netcoreapp3.1");
3638

39+
// Default plugin type returned can be optionally configured with DefaultType function
40+
//services.AddPluginFramework()
41+
// .AddPluginCatalog(folderPluginCatalog)
42+
// .AddPluginType<IOperator>(configureDefault: option =>
43+
// {
44+
// option.DefaultType = (serviceProvider, implementingTypes) => typeof(MultiplyOperator);
45+
// });
46+
47+
// Alternatively default plugin type can be also configured with Configure and provided with the same DefaultType function
48+
//services.Configure<DefaultPluginOption>(nameof(IOperator), option =>
49+
// option.DefaultType = (serviceProvider, implementingTypes) => typeof(MultiplyOperator));
50+
3751
services.AddControllers();
3852
}
3953

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace Weikio.PluginFramework.AspNetCore
7+
{
8+
public class DefaultPluginOption
9+
{
10+
public Func<IServiceProvider, IEnumerable<Type>, Type> DefaultType { get; set; }
11+
= (serviceProvider, implementingTypes) => implementingTypes.FirstOrDefault();
12+
}
13+
}

src/Weikio.PluginFramework.AspNetCore/ServiceCollectionExtensions.cs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ public static IServiceCollection AddPluginCatalog(this IServiceCollection servic
178178
return services;
179179
}
180180

181-
public static IServiceCollection AddPluginType<T>(this IServiceCollection services, ServiceLifetime serviceLifetime = ServiceLifetime.Transient)
181+
public static IServiceCollection AddPluginType<T>(this IServiceCollection services, ServiceLifetime serviceLifetime = ServiceLifetime.Transient,
182+
Action<DefaultPluginOption> configureDefault = null)
182183
where T : class
183184
{
184185
var serviceDescriptorEnumerable = new ServiceDescriptor(typeof(IEnumerable<T>), sp =>
@@ -191,16 +192,43 @@ public static IServiceCollection AddPluginType<T>(this IServiceCollection servic
191192

192193
var serviceDescriptorSingle = new ServiceDescriptor(typeof(T), sp =>
193194
{
195+
var defaultPluginOption = GetDefaultPluginOptions<T>(configureDefault, sp);
196+
194197
var pluginProvider = sp.GetService<PluginProvider>();
195198
var result = pluginProvider.GetTypes<T>();
196199

197-
return result.FirstOrDefault();
200+
var defaultType = defaultPluginOption.DefaultType(sp, result.Select(r => r.GetType()));
201+
202+
return result.FirstOrDefault(r => r.GetType() == defaultType);
198203
}, serviceLifetime);
199204

200205
services.Add(serviceDescriptorEnumerable);
201206
services.Add(serviceDescriptorSingle);
202207

203208
return services;
204209
}
210+
211+
private static DefaultPluginOption GetDefaultPluginOptions<T>(Action<DefaultPluginOption> configureDefault, IServiceProvider sp) where T : class
212+
{
213+
var defaultPluginOption = new DefaultPluginOption();
214+
215+
// If no configuration is provided though action try to get configuration from named options
216+
if (configureDefault == null)
217+
{
218+
var optionsFromMonitor =
219+
sp.GetService<IOptionsMonitor<DefaultPluginOption>>().Get(typeof(T).Name);
220+
221+
if (optionsFromMonitor != null)
222+
{
223+
defaultPluginOption = optionsFromMonitor;
224+
}
225+
}
226+
else
227+
{
228+
configureDefault(defaultPluginOption);
229+
}
230+
231+
return defaultPluginOption;
232+
}
205233
}
206234
}

src/Weikio.PluginFramework.Configuration/Weikio.PluginFramework.Configuration.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFramework>netcoreapp3.1</TargetFramework>

0 commit comments

Comments
 (0)