IOC是Inversion of Control(控制反转,也叫依赖注入)的缩写,基本思想就是把类的依赖从类内部转化到外部以减少依赖。下面就来举一个实际的例子演示典型的依赖注入。
首先创建一个类库项目OperationProvider,然后在项目中添加一个类OperationProvider.cs。

Code
using System;
using System.Collections.Generic;
using System.Text;
namespace OperationProvider
{
public class Add
{
public int DoOperation(int a, int b)
{
return a + b;
}
}
public class Minus
{
public int DoOperation(int a, int b)
{
return a - b;
}
}
}
这两个类很简单,提供了两种操作:加法和减法,并返回计算结果。
再添加一个类库项目Calc,然后在项目中添加一个类Calc.cs。

Code
using System;
using OperationProvider;
namespace Calc
{
public class OutputResult
{
private Add _oper;
public Add Oper
{
get { return _oper; }
set { _oper = value; }
}
public void CalcResult(int a, int b)
{
if (Oper == null)
{
Console.WriteLine("没有初始化操作");
}
else
{
Console.WriteLine(string.Format("计算结果为:{0}",Oper.DoOperation(a,b)));
}
}
}
}
这个类调用OperationProvider.cs中的操作进行计算(因此需要添加OperationProvider类库项目的引用),然后以一定的格式返回计算结果。
最后,添加一个控制台程序TestConsole来执行计算操作。

Code
using System;
namespace TestConsole
{
class Program
{
static void Main(string[] args)
{
OperationProvider.Add oper = new OperationProvider.Add();
Calc.OutputResult rst = new Calc.OutputResult();
rst.Oper = oper;
rst.CalcResult(1, 2);
Console.ReadLine();
}
}
}
这个控制台程序起了一个装配的作用。为Output类的Oper属性赋值(OperationProvider命名空间的一个类的实例)。这样一来整个系统的依赖关系如下图(TestConsole要添加对OperationProvider和Calc的引用,Calc要添加对OperationProvider的引用)。这样一来整个系统的依赖关系如图:

主程序和两个项目有依赖,类库之间也有依赖。我们可以使用基于接口的编程来化解其中的一些依赖。创建一个类库项目Interface,然后为之创建一个类Interface.cs,如下:

Code
using System;
using System.Collections.Generic;
using Calc;
namespace Interface
{
public interface IOperation
{
int DoOperation(int a, int b);
}
public interface ICalc
{
IOperation oper { get;set;}
void CalcResult(int a, int b);
}
}
删除Calc项目对OperationProvider项目的引用,添加对Interface的引用,然后修改Calc.cs如下:

Code
using System;
using Interface;
namespace Calc
{
public class OutputResult:ICalc
{
private IOperation _oper;
public IOperation Oper
{
get { return _oper; }
set { _oper= value; }
}
public void CalcResult(int a, int b)
{
if (Oper == null)
{
Console.WriteLine("没有初始化操作");
}
else Console.WriteLine(string.Format("计算结果为:{0}",Oper.DoOperation(a,b)));
}
}
}
在这里,OutputResult类不再依赖一个操作类,而是依赖于一个接口(所有的操作都遵循这个接口)。因此,OperationProvider项目也需要添加Interface项目的引用,并修改Operation.cs 如下:

Code
using System;
using System.Collections.Generic;
using System.Text;
using Interface;
namespace OperationProvider
{
public class Add:IOperation
{
public int DoOperation(int a, int b)
{
return a + b;
}
}
public class Minus:IOperation
{
public int DoOperation(int a, int b)
{
return a - b;
}
}
}
最后,为TestConsole控制台项目添加Interface项目的引用,重新编译整个解决方案。现在整个系统的依赖关系如图:

虽然使用了接口,但是似乎只消除了部分的依赖,对于控制台程序对其他类库的依赖并没有消除。出现这样情况的原因就是OperationProvider和Calc类库都是事先引用,并且在程序中组装的。如果能动态加载和组装他们,那么就可以彻底消除这层依赖。下面,就来介绍如何使用Spring.Net框架来消除这个依赖。
使用Spring.Net进行依赖注入
修改TestConsole控制台项目,使用了IOC后我们只需要添加Interface项目的引用和Spring.Core程序集(用于IOC)以及System.Configuration程序集(用于加载配置)的引用。
修改Program.cs如下:

Code
using System;
using Interface;
using Spring.Context;
using System.Configuration;
namespace TestConsole
{
class Program
{
static void Main(string[] args)
{
IApplicationContext ac = ConfigurationManager.GetSection("sprint/context") as IApplicationContext;
ICalc calc = ac["calc"] as ICalc;
calc.CalcResult(1, 2);
}
}
}
通过Sprint.Net,我们只需要依赖接口调用方法即可。Spring.Net可以通过配置文件完成动态加载程序集和组装,配置文件。
源代码下载
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述