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

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) 获取类型信息,并进行依赖注入的注册。

使用场景

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

注意事项

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

posted @   Josen_Earth  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示