需求:
有类库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");
}
}