自己写一个依赖注入容器Container
2024-10-07 20:42:46
前言:在平时的写代码中为了解耦、方便扩展,经常使用一些DI容器(如:Autofac、Unity),那是特别的好用。
关于它的底层实现代码 大概是这样。
一、使用依赖注入的好处
关于使用依赖注入创建对象的好处网上一找就是一大堆(低耦合、可配置等),这里就不复制粘贴了。
二、使用XML+Assembly实现可配置的Container
namespace com.cqgc.TestSys.Core
{
public class Container
{
private static Container instance;//实例
private static XDocument xml;//UI层的服务实现配置文件实例 public static Container Instance//全局IOC窗口实例,单例模式
{
get
{
if (instance == null)
{
instance = new Container();
}
if (xml == null)
{
//读取UI层的服务实现配置文件
xml = XDocument.Load(AppDomain.CurrentDomain.BaseDirectory + "/Configuration/Service.xml");
}
return instance;
}
} /// <summary>
/// 向外提供创建对象的方法
/// </summary>
/// <typeparam name="T">Service</typeparam>
/// <returns></returns>
public T Resolve<T>()
where T : class
{
return GetComponentInstance<T>(typeof(T).Name);
} /// <summary>
/// 通过XMl中的Service名创建对应的业务逻辑实体
/// </summary>
/// <typeparam name="T">Component</typeparam>
/// <param name="service">Service名字</param>
/// <returns>Component</returns>
public T GetComponentInstance<T>(string service)
where T : class
{
//没找到配置文件
if (xml == null)
{
throw new ArgumentNullException("没找到配置文件"+ nameof(xml));
}
//在UI层的服务实现配置文件根据接口文件名读取实现接口文件的业务逻辑实体
var element = (from p in xml.Root.Elements("element")
where p.Attribute("Id").Value.Equals(service)
select new
{
serviceNamespace = p.Attribute("Service").Value,
classNamespace = p.Attribute("Class").Value
}).FirstOrDefault(); //没找到配置节点
if (string.IsNullOrEmpty(element.classNamespace))
{
throw new Exception("配置文件结点" + service + "出错!");
}
string[] configs = element.classNamespace.Split(','); //XML配置中接口和业务逻辑实体不成对
if (configs.Length != )
{
throw new Exception("配置文件结点" + service + "出错!");
} ProxyGenerator generator = new ProxyGenerator();//代码生成器
T t = (T)Assembly.Load(configs[]).CreateInstance(configs[]);//根据配置文件实例化一个对象 return t;
} //释放资源
public void Dispose()
{
instance = null;
xml = null;
}
}
}
三、XML
<?xml version="1.0" encoding="utf-8" ?>
<root>
<element Id="IUserService" Service="com.cqgc.TestSys.Service.IUserService, com.cqgc.TestSys.Service" Class="com.cqgc.TestSys.Component.UserComponent, com.cqgc.TestSys.Component"></element>
<element Id="ISysUserService" Service="com.cqgc.TestSys.Service.ISysUserService, com.cqgc.TestSys.Service" Class="com.cqgc.TestSys.Component.SysUserComponent, com.cqgc.TestSys.Component"></element>
</root>
四、调用
var _user=Container.Instance.Resolve<ISysUserService>();
最新文章
- Win7网上邻居提示未授予用户在此计算机上的请求登录类型解决办法
- HDU 1394 Minimum Inversion Number(最小逆序数 线段树)
- Java面试题整理
- 1>; Strut2 Mapping to MVC
- Hadoop 学习笔记 (九) hadoop2.2.0 生产环境部署 HDFS HA部署方法
- WndProc Message消息解释
- VCS引起的oracle数据库异常重新启动一例
- Linux下同步工具inotify+rsync使用详解
- SharePoint使用BCS开发你第一个应用程序(一)
- Mybatis——helloWorld级程序
- Apache 代理(Proxy) 转发请求
- C#开发移动应用系列(2.使用WebView搭建WebApp应用)
- 教学服务系统设计之PHP后台设计
- leetcode算法题2: 合并两个二叉树。递归,如何切入并保持清醒?
- jQuery应用操作之---网页选项卡(tabs)
- SOFA 源码分析 — 连接管理器
- 使用 Gradle 构建 Java 项目
- Codeforces 44E - Anfisa the Monkey - [水题]
- Object类(API文档)
- Win7操作系统安装IE10提示“安装前需要更新与安装程序版本”
热门文章
- PHP面向对象----- 类的自动加载
- delphi xe10 文件目录/路径操作 (Andorid、ios)
- jsp-解决自写Servlet老是报错404
- mdk keil 指定变量、函数存储位置,使用 Scatter-Loading Description File, __attribute__((";section“))
- Codeforces 1176A Divide it!
- Apache Solr 远程命令+XXE执行漏洞(CVE-2017-12629)
- 剑指offer——14机器人的运动范围
- 无法启动此程序,因为计算机中丢失api-ms-win-crt-runtime-l1-1-0.dll已解决
- spring boot junit test
- 码云的使用以及pycharm