以前書いた記事、ちゃんとできないパターンがあったので、アップデートしました。
以前の記事
■ 何を変えたか
自分自身もプラグイン側からはリフレクションで動作させるようにしました。
■ リポジトリとライブラリ
■ コード
自分のインスタンスを object でプラグイン側に入れて、プラグイン側でリフレクションでアプリ側で作られたインスタンスのメソッドを実行する感じです。
using RkSoftware.RKPlugin.DependencyInjection.Internals; using System; using System.Collections.Generic; using System.Text; namespace RkSoftware.RKPlugin.DependencyInjection; public class PluginServiceCollection { object? Services { get; init; } static object? GetService(object? obj) => obj?.GetType()?.GetProperty(nameof(Services))?.GetValue(obj); internal PluginServiceCollection(object? services) { this.Services = services; } object? AddScoped<TService>(Func<IServiceProvider, TService> implementationFactory) where TService : class => PluginServiceCollectionService.AddScoped(Services, implementationFactory); public static object? AddScoped<TService>(object? services, Func<IServiceProvider, TService> implementationFactory) where TService : class { var type = services!.GetType(); var methodInfo = type.GetMethod("AddScoped", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var method = methodInfo?.MakeGenericMethod(typeof(TService)); return method?.Invoke(services, [implementationFactory]); } object? AddHttpClient<TClient, TImplementation>(Func<HttpClient, TImplementation> factory) where TClient : class where TImplementation : class, TClient => PluginHttpClientFactoryServiceCollection.AddHttpClient<TClient, TImplementation>(Services, factory); public static object? AddHttpClient<TClient, TImplementation>(object? services, Func<HttpClient, TImplementation> factory) where TClient : class where TImplementation : class, TClient { var type = services!.GetType(); var methodInfo = type.GetMethod("AddHttpClient", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var method = methodInfo?.MakeGenericMethod(typeof(TClient), typeof(TImplementation)); return method?.Invoke(services, [factory]); } }
使っているところ(プラグイン側)
public class Class1 { public static string ConfigureServices(object services) { var r01 = PluginServiceCollection.AddHttpClient<ITest, Test>(services, F01)?.ToString(); var r02 = PluginServiceCollection.AddScoped(services, F02)?.ToString(); return string.Join(", ", r02, r02); }
使っているところ(アプリ側)
var pluginPath = Path.Combine(Assembly.GetEntryAssembly()?.Location!, "../../../../../TestPlugin/bin/Debug/net10.0"); var plugins = PluginLoadContext.LoadExtensions(pluginPath); foreach (var plugin in plugins) foreach (var assembly in plugin.Assemblies) foreach (var type in assembly.GetTypes()) { var method = type.GetMethod("ConfigureServices"); if (method != null) { var result = PluginLoadContext.Invoke(services, method, null, null); Debug.Write(result); } }