如何在不引用指定类库的情况下调用该类库中的相关方法

需求:

有类库A,和类库B,然后定义了个接口,类库B中实现了,A类库中 如何能够在不引用类库B的情况下 调用B实现的接口

实现方式1:反射和依赖注入

1. 定义接口
首先,在一个独立的类库(例如类库Common)中定义接口IUserFunctions。这样,类库A和类库B都可以引用类库Common,而不相互引用。

// CommonLibrary
namespace CommonLibrary
{
    public interface IUserFunctions
    {
        void SetEnable(string name);
    }
}
2. 实现接口
在类库B中实现接口IUserFunctions。

// LibraryB
using CommonLibrary;

namespace LibraryB
{
    public class UserFunctions : IUserFunctions
    {
        public void SetEnable(string name)
        {
            // 实现具体的逻辑
            Console.WriteLine($"SetEnable called with name: {name}");
        }
    }
}
3. 配置依赖注入
使用一个配置文件或服务注册机制来注册类库B中的实现。可以使用简单的工厂模式或依赖注入容器(如Microsoft.Extensions.DependencyInjection)。

使用配置文件(例如appsettings.json)
{
  "UserFunctionsImplementation": "LibraryB.UserFunctions, LibraryB"
}
4. 在类库A中动态加载实现
在类库A中使用反射和配置文件来加载并调用类库B中的实现。

// LibraryA
using CommonLibrary;
using System;
using System.Configuration;
using System.Reflection;

namespace LibraryA
{
    public static class ServiceLoader
    {
        public static IUserFunctions LoadUserFunctions()
        {
            // 从配置文件中读取实现类的完全限定名
            string implementationTypeName = ConfigurationManager.AppSettings["UserFunctionsImplementation"];
            if (string.IsNullOrEmpty(implementationTypeName))
            {
                throw new InvalidOperationException("UserFunctions implementation not configured.");
            }

            // 动态加载实现类
            Type implementationType = Type.GetType(implementationTypeName);
            if (implementationType == null)
            {
                throw new InvalidOperationException($"Could not load type: {implementationTypeName}");
            }

            return (IUserFunctions)Activator.CreateInstance(implementationType);
        }
    }

    public static class MyService
    {
        public static void Execute(string name)
        {
            // 使用加载的实现
            IUserFunctions userFunctions = ServiceLoader.LoadUserFunctions();
            userFunctions.SetEnable(name);
        }
    }
}
5. 配置并运行程序
确保在程序的配置文件中正确配置实现类的完全限定名,并运行程序。

// Program
using LibraryA;

class Program
{
    static void Main(string[] args)
    {
        // 调用服务方法
        MyService.Execute("exampleName");
    }
}

实现方式二:使用依赖注入容器

定义接口
// CommonLibrary
namespace CommonLibrary
{
    public interface IUserFunctions
    {
        void SetEnable(string name);
    }
}
实现接口
// LibraryB
using CommonLibrary;

namespace LibraryB
{
    public class UserFunctions : IUserFunctions
    {
        public void SetEnable(string name)
        {
            // 实现具体的逻辑
            Console.WriteLine($"SetEnable called with name: {name}");
        }
    }
}
配置依赖注入容器
在类库A中配置依赖注入容器。

// LibraryA
using CommonLibrary;
using Microsoft.Extensions.DependencyInjection;
using System;

namespace LibraryA
{
    public static class ServiceLoader
    {
        public static IServiceProvider ConfigureServices()
        {
            var serviceCollection = new ServiceCollection();

            // 动态加载实现类
            string assemblyName = "LibraryB";
            string typeName = "LibraryB.UserFunctions";
            Type implementationType = Type.GetType($"{typeName}, {assemblyName}");
            if (implementationType == null)
            {
                throw new InvalidOperationException($"Could not load type: {typeName}");
            }

            serviceCollection.AddSingleton(typeof(IUserFunctions), implementationType);

            return serviceCollection.BuildServiceProvider();
        }
    }

    public static class MyService
    {
        public static void Execute(string name, IServiceProvider serviceProvider)
        {
            // 使用依赖注入容器获取实现
            var userFunctions = serviceProvider.GetService<IUserFunctions>();
            userFunctions.SetEnable(name);
        }
    }
}
配置并运行程序
在程序中配置依赖注入容器并运行。

// Program
using LibraryA;
using Microsoft.Extensions.DependencyInjection;

class Program
{
    static void Main(string[] args)
    {
        // 配置依赖注入容器
        var serviceProvider = ServiceLoader.ConfigureServices();

        // 调用服务方法
        MyService.Execute("exampleName", serviceProvider);
    }
}

实现方式三:使用插件机制

插件机制可以让类库A动态加载类库B中的实现,而无需直接引用类库B。

定义接口
// CommonLibrary
namespace CommonLibrary
{
    public interface IUserFunctions
    {
        void SetEnable(string name);
    }
}
实现接口
// LibraryB
using CommonLibrary;

namespace LibraryB
{
    public class UserFunctions : IUserFunctions
    {
        public void SetEnable(string name)
        {
            // 实现具体的逻辑
            Console.WriteLine($"SetEnable called with name: {name}");
        }
    }
}
在类库A中动态加载插件
// LibraryA
using CommonLibrary;
using System;
using System.IO;
using System.Linq;
using System.Reflection;

namespace LibraryA
{
    public static class PluginLoader
    {
        public static IUserFunctions LoadPlugin(string pluginPath)
        {
            var assembly = Assembly.LoadFrom(pluginPath);
            var type = assembly.GetTypes().FirstOrDefault(t => typeof(IUserFunctions).IsAssignableFrom(t) && !t.IsInterface);
            if (type == null)
            {
                throw new InvalidOperationException("No implementation of IUserFunctions found.");
            }

            return (IUserFunctions)Activator.CreateInstance(type);
        }
    }

    public static class MyService
    {
        public static void Execute(string name, IUserFunctions userFunctions)
        {
            userFunctions.SetEnable(name);
        }
    }
}
配置并运行程序
在程序中加载插件并运行。

// Program
using LibraryA;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        // 插件的路径
        string pluginPath = Path.Combine(Directory.GetCurrentDirectory(), "LibraryB.dll");

        // 动态加载插件
        var userFunctions = PluginLoader.LoadPlugin(pluginPath);

        // 调用服务方法
        MyService.Execute("exampleName", userFunctions);
    }
}

实现方式四:使用事件机制

事件机制可以让类库A定义事件,类库B订阅事件并处理。

定义接口和事件
// CommonLibrary
namespace CommonLibrary
{
    public interface IUserFunctions
    {
        void SetEnable(string name);
    }

    public static class UserFunctionsEvents
    {
        public static event Action<string> OnSetEnable;

        public static void RaiseSetEnable(string name)
        {
            OnSetEnable?.Invoke(name);
        }
    }
}
实现接口并订阅事件
// LibraryB
using CommonLibrary;

namespace LibraryB
{
    public class UserFunctions : IUserFunctions
    {
        public UserFunctions()
        {
            UserFunctionsEvents.OnSetEnable += SetEnable;
        }

        public void SetEnable(string name)
        {
            // 实现具体的逻辑
            Console.WriteLine($"SetEnable called with name: {name}");
        }
    }
}
在类库A中触发事件
// LibraryA
using CommonLibrary;

namespace LibraryA
{
    public static class MyService
    {
        public static void Execute(string name)
        {
            UserFunctionsEvents.RaiseSetEnable(name);
        }
    }
}
配置并运行程序
在程序中初始化类库B并运行。

// Program
using CommonLibrary;
using LibraryB;

class Program
{
    static void Main(string[] args)
    {
        // 初始化类库B
        var userFunctions = new UserFunctions();

        // 调用服务方法
        MyService.Execute("exampleName");
    }
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值