在上篇文章《System.ComponentModel.Component入门》中,介绍了.NET本身的解决方案,既然.NET已经有了解决方案,为什么要自己实现呢?先看看使用.NET的方式写的代码:
1、通过GetService获取的组件,无法自动加入新的容器;
在.NET中,GetService方法是由Site定义的(实际实现是容器实现的),且不包含加入新容器的参数,所以新创建的组件只能笨拙的加入容器(第3行)。
2、商业组件内部代码耦合了Container实现;
在第1行,只能自己实例化一个容器,不管是耦合Container还是耦合自己的容器,都是违反了注射依赖的初衷。
3、难以理解
正如上一篇文章中的回复所说的,“我还是不懂”,是的,.NET的站点和容器的设计的确让人难以理解。
基于上面的问题,我设计了一个新的接口定义:
/// <summary>
/// 注射依赖的服务组件。
/// </summary>
public interface IService {
/// <summary>
/// 返回/设置当前服务组件的上下文。
/// </summary>
/// <remarks>
/// 不需要服务自己处理此属性,组件在初始化后,将有上层服务自动初始化。
/// 请参见:<see cref="IServiceContainer.GetService<T>"/>
/// </remarks>
IServiceContext Context { get;set;}
}

/// <summary>
/// 服务的上下文,通过他,可以获取新的容器。
/// </summary>
public interface IServiceContext {
IServiceContainer CreateContainer();
}

/// <summary>
/// 容器对象,通过他创建的服务将自动初始化 Context属性,并在容器释放后自动释放。
/// </summary>
public interface IServiceContainer : IServiceFactory, IDisposable { }

/// <summary>
/// 服务工厂接口
/// </summary>
public interface IServiceFactory {
T GetService<T>();
}
使用实例:
1、在类的定义中,继承自ServiceBase,他是IService的基础实现,当然你可以自己实现IService,实现非常简单;
2、当你需要使用别的服务时,通过Context创建新的容器,并在新的容器中创建服务,这样新的服务就自动加入新的容器,并自动初始化了Context属性。
1
using (IContainer container = new Container()) {
2
IOrderService orderService = GetService(typeof(IOrderService)) as IOrderService;
3
container.Add(orderService);
4
}

2

3

4

1、通过GetService获取的组件,无法自动加入新的容器;
在.NET中,GetService方法是由Site定义的(实际实现是容器实现的),且不包含加入新容器的参数,所以新创建的组件只能笨拙的加入容器(第3行)。
2、商业组件内部代码耦合了Container实现;
在第1行,只能自己实例化一个容器,不管是耦合Container还是耦合自己的容器,都是违反了注射依赖的初衷。
3、难以理解
正如上一篇文章中的回复所说的,“我还是不懂”,是的,.NET的站点和容器的设计的确让人难以理解。
基于上面的问题,我设计了一个新的接口定义:
































使用实例:
1
public class DataService : ServiceBase, IDataService {
2
3
public void UpdateDB() {
4
using (IServiceContainer container = Context.CreateContainer()) {
5
ILogService log = container.GetService<ILogService>();
6
log.WriteLog();
7
}
8
}
9
}

2

3

4

5

6

7

8

9

2、当你需要使用别的服务时,通过Context创建新的容器,并在新的容器中创建服务,这样新的服务就自动加入新的容器,并自动初始化了Context属性。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构