c# - 将依赖项注入(inject)动态加载的 .dll (.net core)

标签 c# .net-core dependency-injection reflection inversion-of-control

类似于How to Inject Dependencies to Dynamically Loaded Assemblies ,我想从动态加载的程序集中将依赖项注入(inject)到类中。 .NET 6.0 DI 容器可以实现吗?如果是这样,如何?如果没有,您是否可以推荐一个轻量级的 IOC 容器? (最好不要向项目添加第二个 IOC 系统。) (注意:最多只能注入(inject) 2-4 个依赖项,因此可以接受带有 if/switch 语句的假注入(inject)系统。)
一项挑战:ILogger<>通常需要一个类型,但加载的 .dll 在编译时不知道动态加载的程序集中的类型,反之亦然。我可以使用非通用 ILogger接口(interface),但我不确定它是否适用于 DI。

编辑: 根据要求扩展示例:

给定:要注入(inject)的所有潜在依赖项都来自 Microsoft.Extensions.Hosting nuget 包。我们最初希望使用的两个是 ILogging<> 和 IConfiguration。

Type desiredClass = <Type found in the dynamically loaded assembly>;
//The below line does not inject dependencies.  I am trying to find out what will.
object classInstace = Activator.CreateInstance(desiredClass); 
MethodInfo selectedMethod = desiredClass.GetMethods
    .Single(m=>m.Name=="Execute" && m.GetParameters().All(p=>p.IsOptional));
//Schedule the method in HangFire
RecurringJob.AddOrUpdate(
    () => selectedMethod!.Invoke(
        ClassInstance,
        Array.Empty<object?>(),
        scheduleForThisTask);

最佳答案

我找到了一种非常丑陋的方法来完成这项工作,非常希望有一种更简洁的方法来完成这项工作。 (请让我错过了一个内置的方法来做到这一点。)

为 IService Provider 创建一个扩展方法 GetInjectedObject:

public static object GetInjectedObject(this IServiceProvider serviceProvider, Type type)
{
    //Dependency injection the ugly way
    //Find the constructor that asks for the most injected parameters
    var constructor = type.GetConstructors().Where(cn =>
            cn.GetParameters().All(par => serviceProvider.GetServices(par.ParameterType).Any()))
        .OrderByDescending(cn => cn.GetParameters().Length).FirstOrDefault();
    if (null == constructor)
        throw new Exception($"Type {type.Name} does not have a constructor without non-injectible parameters.");
    //Get the needed parameters from the IServiceProvider
    var constructorParameters =
        constructor.GetParameters().Select(par => serviceProvider.GetService(par.ParameterType)).ToArray();
    //Create the object with the parameters
    var classInstance = Activator.CreateInstance(type, constructorParameters);
    return classInstance;
}

然后像这样创建对象:

_classInstance = serviceProvider.GetInjectedObject(Class);

关于c# - 将依赖项注入(inject)动态加载的 .dll (.net core),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71650719/

相关文章:

c# - Azure 存储文件强制下载到浏览器

c# - ASP.NET Web API 从模型生成所有参数 - 帮助页面

c# - 使用大的静态变量是个坏主意吗?

c# - 如何使用 .Net Core 创建 PKCS#7 分离签名?

.net-core - 如何在 Blazor Server 应用程序中停止事件传播

java - 提供者可以在不同的实例之间进行选择吗

c# - 对值类型使用通用约束

c# - 如何延迟停止和启动函数应用

java - 谷歌指南 : Provider with parameters

php - Zend_Di(Zend 2.0 beta)和 Zend Framework 1.11