首页 > 其他分享 >根据字符串动态地注册服务

根据字符串动态地注册服务

时间:2024-08-20 17:17:04浏览次数:6  
标签:void services 注册 字符串 动态 type public 加载

using System;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // 假设我们要注册的类名是 "MyService"
        string serviceName = "MyService";
        RegisterServiceByName(services, serviceName);
    }

    private void RegisterServiceByName(IServiceCollection services, string serviceName)
    {
        // 获取当前执行的程序集
        var assembly = Assembly.GetExecutingAssembly();

        // 查找与给定名称匹配的类型
        var type = assembly.GetTypes().FirstOrDefault(t => t.Name == serviceName);

        if (type != null)
        {
            // 使用接口进行注册,这里假设接口是以 "I" 开头的
            var interfaceType = type.GetInterface("I" + type.Name);
            if (interfaceType != null)
            {
                // 注册服务
                services.AddScoped(interfaceType, type);
            }
            else
            {
                // 如果没有找到接口,可以注册具体类型
                services.AddScoped(type);
            }
        }
        else
        {
            throw new InvalidOperationException($"Service {serviceName} not found.");
        }
    }
}

// 示例服务和接口
public interface IMyService
{
    void DoSomething();
}

public class MyService : IMyService
{
    public void DoSomething()
    {
        Console.WriteLine("Doing something...");
    }
}

方式二

using System;
using Microsoft.Extensions.DependencyInjection;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // 使用完整类名(包括命名空间)注册服务
        RegisterServiceByFullName(services, "YourNamespace.MyService");
    }

    private void RegisterServiceByFullName(IServiceCollection services, string fullClassName)
    {
        // 获取类型
        var type = Type.GetType(fullClassName);

        if (type == null)
        {
            throw new InvalidOperationException($"Service {fullClassName} not found.");
        }

        // 使用接口进行注册,这里假设接口是以 "I" 开头的
        var interfaceType = type.GetInterface("I" + type.Name);
        if (interfaceType != null)
        {
            // 注册服务
            services.AddScoped(interfaceType, type);
        }
        else
        {
            // 如果没有找到接口,可以注册具体类型
            services.AddScoped(type);
        }
    }
}

// 示例服务和接口
namespace YourNamespace
{
    public interface IMyService
    {
        void DoSomething();
    }

    public class MyService : IMyService
    {
        public void DoSomething()
        {
            Console.WriteLine("Doing something...");
        }
    }
}

如果类不在当前执行上下文中,Type.GetType 可能返回 null。在这种情况下,你可能需要提供程序集信息,例如 "YourNamespace.MyService, YourAssemblyName"。

使用 Assembly.Load 或 Assembly.LoadFrom 方法来加载程序集

using System;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // 假设你要加载的程序集名称为 "YourAssemblyName"
        string assemblyName = "YourAssemblyName";
        string className = "YourNamespace.MyService";

        // 加载程序集并注册服务
        RegisterServiceByFullName(services, assemblyName, className);
    }

    private void RegisterServiceByFullName(IServiceCollection services, string assemblyName, string fullClassName)
    {
        // 尝试加载程序集
        Assembly assembly = Assembly.Load(assemblyName);

        if (assembly == null)
        {
            throw new InvalidOperationException($"Assembly {assemblyName} could not be loaded.");
        }

        // 获取类型
        var type = assembly.GetType(fullClassName);

        if (type == null)
        {
            throw new InvalidOperationException($"Service {fullClassName} not found in assembly {assemblyName}.");
        }

        // 使用接口进行注册,这里假设接口是以 "I" 开头的
        var interfaceType = type.GetInterface("I" + type.Name);
        if (interfaceType != null)
        {
            // 注册服务
            services.AddScoped(interfaceType, type);
        }
        else
        {
            // 如果没有找到接口,可以注册具体类型
            services.AddScoped(type);
        }
    }
}

// 示例服务和接口
namespace YourNamespace
{
    public interface IMyService
    {
        void DoSomething();
    }

    public class MyService : IMyService
    {
        public void DoSomething()
        {
            Console.WriteLine("Doing something...");
        }
    }
}

Assembly.Load: 使用 Assembly.Load(assemblyName) 方法加载指定的程序集。assemblyName 是程序集的短名称(不包括 .dll 后缀)。
Assembly.LoadFrom: 如果你有程序集的完整路径,可以使用 Assembly.LoadFrom("path/to/YourAssembly.dll") 方法来加载。
获取类型并注册: 加载程序集后,使用 assembly.GetType(fullClassName) 获取类型信息,并进行依赖注入的注册。

使用场景

动态加载插件: 如果你有外部插件或模块,需要在运行时加载并注册其中的服务,这种方法非常适用。
按需加载: 只有在需要使用某些服务时才加载相关程序集,可以节省资源。

注意事项

程序集依赖: 确保要加载的程序集及其依赖项都在正确的路径上,否则加载可能失败。
性能影响: 动态加载程序集和反射获取类型可能带来一定的性能开销,使用时要考虑是否必要。
版本兼容性: 如果你加载的程序集版本不兼容当前应用程序,可能会导致运行时错误

标签:void,services,注册,字符串,动态,type,public,加载
From: https://www.cnblogs.com/JosenEarth/p/18369864

相关文章

  • Nuxt3【过渡】2024最新版 (含页面过渡、布局过渡、全局过渡、局部过渡、动态过渡、禁用
    全局布局过渡layoutTransitionnuxt.config.ts中exportdefaultdefineNuxtConfig({app:{layoutTransition:{name:'layout',mode:'out-in'}},})app.vue中需添加样式.layout-enter-active,.layout-leave-active{transition:all0.4s;......
  • 动态规划方法论
    动态规划动态规划,英文:DynamicProgramming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的,我在这里举一个典型的动态规划的问题——背包问题:例如......
  • 《深度解读代理模式:静态代理与动态代理的详尽剖析》
    代理模式一、引言在Java开发中,代理模式是一种非常重要的设计模式,它为其他对象提供一种代理,以控制对这个对象的访问,在访问对象和目标对象之间起到中介作用。Java中的代理按照代理类生成时机不同分为静态代理和动态代理,而动态代理又有JDK代理和CGLib代理两种。本文将......
  • 设计模式之cglib动态代理
    什么是动态代理呢?动态代理就是在java进程运行时,通过字节码技术,动态的生成某个类的代理类。在这个代理类中,我们可以做一些额外的操作,一方面仍然保持原有的方法的能力,另外一方面还增强了这些能力。听着是不是AOP有点像,没错,动态代理就是AOP的技术基石。在这之前我曾经写过两篇相关的......
  • Day35 动态规划Part3
    目录任务01背包(KAMA46)DP思路滚动数组思路416.分割等和子集思路任务有n件物品和一个最多能背重量为w的背包。第i件物品的重量是weight[i],得到的价值是value[i]。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。01背包(KAMA46)DP思路dp[i][j]为[0,i]的所有物......
  • 11 根据相应规则判断字符串是否正确
    现有两个机器人M1和M2它们要进行对话,规则如下:M1只会说“Y”,“N”,“2”;M2只会说“y”,“n”,“1”;M1先主动说话;当一个机器人说的不是数字时,它自己必须继续说话,对方不能说话;当一个机器人说出数字时,它自己停止说话,此时对方可以接着说话,也可以不说话从而结束对话;编写程序判定输......
  • 【C语言】基础知识详解(二) 字符串
    一、什么是字符串?在C语言中,字符串是一种特殊的字符数组,用于存储一系列字符。字符串的表示:在C语言中,字符串是由字符组成的数组,并以空字符'\0'结束。空字符用于标识字符串的结束。例如,字符串"hello"在内存中实际上是{'h','e','l','l','o','\0'}。字符串声明:可以使......
  • 字符串相乘
    给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。注意:不能使用任何内置的BigInteger库或直接将输入转换为整数。示例1:输入:num1="2",num2="3"输出:"6"示例 2:输入:num1="123",num2="45......
  • Oracle数据库必学!超实用的9个字符串处理函数
    Oracle查询语句中的单行函数,特别是一些常用的字符串处理函数。1.ConCAT函数作用:将两个字符串连接在一起,生成一个新的字符串。使用方法:concat(字符串1,字符串2)示例:SELECTconcat('Hello,','World')FROMDUAL;结果为:“Hello,World”。2.CHR与ASCII函数CHR函数......
  • pod数据持久化-pv与pvc资源及动态存储StorageClass
    一、pc与pvc的概念在传统的存储卷挂载,比如说nfs,它虽然能够实现我们大多数的生产场景,但是,耦合性比较高;举例:假设,我们要将集群从“阿里云”迁移到我们私有云服务器上,并改变存储卷挂在的类型,就无法实现,必须使用原有的存储卷类型;比如我们阿里云的存储卷是nfs,我们线下服务器的存储卷......