从依赖倒置原则到IOC控制反转实现 从手写工厂+配置文件+反射到DI依赖注入实现 手写IOC容器,递归完成构造函数注入

依赖倒置原则(DIP)是面向对象设计(OOD)中的一个重要原则,它提倡:

  1. 高级模块不应该依赖于低级模块,两者都应该依赖于抽象。
  2. 抽象不应该依赖于细节,细节应该依赖于抽象。

这个原则有助于减少类之间的耦合度,使得系统更加灵活、可扩展。

控制反转(IoC)是实现依赖倒置原则的一种技术,它将原本由代码直接操控的对象的调用权交给第三方(比如一个容器)来控制,以解耦代码。IoC的一个常见实现方式是依赖注入(DI),它通常有三种注入方式:构造函数注入、属性注入和方法注入。

在C#中,我们可以通过反射机制,配置文件和工厂模式来手动实现一个简单的IoC容器,以支持构造函数注入。下面是一个简单的示例:

  1. 定义一个接口和它的实现类:
csharp 复制代码
csharp
public interface IService  
{  
    void DoWork();  
}  
  
public class Service : IService  
{  
    private readonly IDependency _dependency;  
  
    public Service(IDependency dependency)  
    {  
        _dependency = dependency;  
    }  
  
    public void DoWork()  
    {  
        _dependency.Help();  
    }  
}  
  
public interface IDependency  
{  
    void Help();  
}  
  
public class Dependency : IDependency  
{  
    public void Help()  
    {  
        Console.WriteLine("Helping...");  
    }  
}
  1. 创建一个简单的配置文件(比如使用XML),用于定义接口和实现类的映射关系:
xml 复制代码
xml
<configuration>  
  <appSettings>  
    <add key="IService" value="YourNamespace.Service, YourAssembly" />  
    <add key="IDependency" value="YourNamespace.Dependency, YourAssembly" />  
  </appSettings>  
</configuration>
  1. 创建一个工厂类,用于读取配置文件并使用反射来创建实例:
csharp 复制代码
csharp
public static class SimpleIoCContainer  
{  
    public static T Resolve<T>()  
    {  
        string typeName = ConfigurationManager.AppSettings[typeof(T).FullName];  
        if (string.IsNullOrEmpty(typeName))  
            throw new InvalidOperationException($"No type registered for {typeof(T).FullName}");  
  
        string[] typeParts = typeName.Split(',');  
        string assemblyName = typeParts[1].Trim();  
        string className = typeParts[0].Trim();  
  
        Type type = Type.GetType($"{className},{assemblyName}");  
        if (type == null)  
            throw new InvalidOperationException($"Type {className} not found in assembly {assemblyName}");  
  
        ConstructorInfo constructor = type.GetConstructors()[0]; // Assuming there is a parameterless constructor or a constructor with resolvable dependencies.  
        ParameterInfo[] parameters = constructor.GetParameters();  
        object[] parameterInstances = new object[parameters.Length];  
  
        for (int i = 0; i < parameters.Length; i++)  
        {  
            parameterInstances[i] = Resolve(parameters[i].ParameterType); // Recursively resolve dependencies.  
        }  
  
        return (T)constructor.Invoke(parameterInstances);  
    }  
  
    // Note: The above code assumes all dependencies can be resolved recursively.   
    // In a real-world scenario, you would need to handle cases where there are circular dependencies or unregistered types.  
    // Additionally, the code does not cache resolved instances, which could lead to performance issues in larger applications.  
    // A fully-fledged IoC container like Autofac, Ninject, or Microsoft.Extensions.DependencyInjection would handle these cases more elegantly.  
}

注意 :上面的SimpleIoCContainer实现非常简化,并且存在几个问题:

  • 它没有处理循环依赖的情况。
  • 它没有缓存已解析的实例,这可能导致性能问题。
  • 它假设配置文件中总是存在正确的映射,并且构造函数参数总是可以解析的。在实际应用中,这些情况都需要更加健壮的处理。
  • 它没有考虑到生命周期管理(如单例、每次请求、每次调用等)。
  • 它使用ConfigurationManager.AppSettings来读取配置,这在.NET Core和.NET 5+中不是推荐的做法;应使用Microsoft.Extensions.Configuration代替。
  • 没有错误处理机制来处理例如类型未找到或构造函数调用失败等异常情况。在实际应用中,应添加适当的错误处理逻辑。

在实际项目中,建议使用成熟的IoC容器库(如Autofac、Ninject、Unity或Microsoft.Extensions.DependencyInjection),因为它们提供了更多的功能、更好的性能和更少的潜在问题。上面的示例仅用于教学目的,以演示IoC容器和依赖注入的基本概念

相关推荐
张人玉8 小时前
基于 C# WinForms + .NET 8 + SQLite + TCP Socket 的多连接通讯调试工具——TCP通讯助手(TcpAssistant)
tcp/ip·sqlite·c#·.net
mldong16 小时前
C# 开发者也有自己的轻量工作流引擎了:NuGet 装包,5 分钟跑通一条审批流
后端·c#·.net
风云1 天前
MiniLog 1.0 GA 发布:零分配、零依赖的 .NET 高性能日志框架
开源·c#·.net·日志·高性能·minilog
慧都小妮子1 天前
C# 工程图纸数字化入库实战:Aspose.Imaging 自动抠图、多页 TIFF 合卷与坏页容错
图像处理·c#·.net·aspose·tiff·归档·文档管理
A_nanda1 天前
C# 调用 .NET(Core)Web 服务混用:常见问题与 .NET 6~10 正确写法
c#·.net
rockey6272 天前
C#脚本引擎之AScript与Z.Expressions.Eval对比
c#·.net·script·expression·动态脚本
geovindu2 天前
CSharp: Wordcloud
开发语言·后端·c#·.net·.netcore·词云
geovindu2 天前
CSharp: Command Pattern
开发语言·后端·c#·.net·.netcore·命令模式·行为模式
谈资一本本2 天前
电脑全能修复大师 Gilisoft Total Repair,智能检测修复系统、应用、游戏问题!DLL、DirectX、.NET运行库损坏修复+缺失自动补齐!
游戏·电脑·.net
公子小六3 天前
基于.NET的Windows窗体编程之WinForms滑块与上下控件
windows·microsoft·c#·.net·winforms