以下の内容はhttps://rksoftware.hatenablog.com/entry/2025/03/30/150000より取得しました。


C# でプラグインに引数をわたす

以前書いた記事、ちゃんとできないパターンがあったので、アップデートしました。

以前の記事

rksoftware.hatenablog.com

■ 何を変えたか

自分自身もプラグイン側からはリフレクションで動作させるようにしました。

■ リポジトリとライブラリ

www.nuget.org

github.com

■ コード

自分のインスタンスを 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);
            }
        }



以上の内容はhttps://rksoftware.hatenablog.com/entry/2025/03/30/150000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14