以前的好多代码都丢失了,加上最近时间空一些,于是想起整理一下以前的个人半拉子项目,试试让它们重生。自从养成了架构师视觉 搭建框架之后,越来 越看不上以前搭的框架了。先撸个上下文对象加上实现依赖注入。由于还是要依赖.net 4,所以像Autofac这样的就用不了,于是仿照着实现了。

  1. /// <summary>
  2. /// 自定义应用程序上下文对象
  3. /// </summary>
  4. public class AppContextExt : IDisposable
  5. {
  6. /// <summary>
  7. /// app.config读取
  8. /// </summary>
  9. public Configuration AppConfig { get; set; }
  10. /// <summary>
  11. /// 真正的ApplicationContext对象
  12. /// </summary>
  13. public ApplicationContext Application_Context { get; set; }
  14. //服务集合
  15. public static Dictionary<Type, object> Services = new Dictionary<Type, object>();
  16. //服务订阅事件集合
  17. public static Dictionary<Type, IList<Action<object>>> ServiceEvents = new Dictionary<Type, IList<Action<object>>>();
  18. //上下文对象的单例
  19. private static AppContextExt _ServiceContext = null;
  20. private readonly static object lockObj = new object();
  21. /// <summary>
  22. /// 禁止外部进行实例化
  23. /// </summary>
  24. private AppContextExt()
  25. {
  26. }
  27. /// <summary>
  28. /// 获取唯一实例,双锁定防止多线程并发时重复创建实例
  29. /// </summary>
  30. /// <returns></returns>
  31. public static AppContextExt GetInstance()
  32. {
  33. if (_ServiceContext == null)
  34. {
  35. lock (lockObj)
  36. {
  37. if (_ServiceContext == null)
  38. {
  39. _ServiceContext = new AppContextExt();
  40. }
  41. }
  42. }
  43. return _ServiceContext;
  44. }
  45. /// <summary>
  46. /// 注入Service到上下文
  47. /// </summary>
  48. /// <typeparam name="T">接口对象</typeparam>
  49. /// <param name="t">Service对象</param>
  50. /// <param name="servicesChangeEvent">服务实例更新时订阅的消息</param>
  51. public static void RegisterService<T>(T t, Action<object> servicesChangeEvent = null) where T : class
  52. {
  53. if (t == null)
  54. {
  55. throw new Exception(string.Format("未将对象实例化,对象名:{0}.", typeof(T).Name));
  56. }
  57. if (!Services.ContainsKey(typeof(T)))
  58. {
  59. try
  60. {
  61. Services.Add(typeof(T), t);
  62. if (servicesChangeEvent != null)
  63. {
  64. var eventList = new List<Action<object>>();
  65. eventList.Add(servicesChangeEvent);
  66. ServiceEvents.Add(typeof(T), eventList);
  67. }
  68. }
  69. catch (Exception ex)
  70. {
  71. throw ex;
  72. }
  73. }
  74. if (!Services.ContainsKey(typeof(T)))
  75. {
  76. throw new Exception(string.Format("注册Service失败,对象名:{0}.", typeof(T).Name));
  77. }
  78. }
  79. /// <summary>
  80. /// 动态注入dll中的多个服务对象
  81. /// </summary>
  82. /// <param name="serviceRuntime"></param>
  83. public static void RegisterAssemblyServices(string serviceRuntime)
  84. {
  85. if (serviceRuntime.IndexOf(".dll") != -1 && !File.Exists(serviceRuntime))
  86. throw new Exception(string.Format("类库{0}不存在!", serviceRuntime));
  87. try
  88. {
  89. Assembly asb = Assembly.LoadFrom(serviceRuntime);
  90. var serviceList = asb.GetTypes().Where(t => t.GetCustomAttributes(typeof(ExportAttribute), false).Any()).ToList();
  91. if (serviceList != null && serviceList.Count > 0)
  92. {
  93. foreach (var service in serviceList)
  94. {
  95. var ifc = ((ExportAttribute)service.GetCustomAttributes(typeof(ExportAttribute), false).FirstOrDefault()).ContractType;
  96. //使用默认的构造函数实例化
  97. var serviceObject = Activator.CreateInstance(service, null);
  98. if (serviceObject != null)
  99. Services.Add(ifc, serviceObject);
  100. else
  101. throw new Exception(string.Format("实例化对象{0}失败!", service));
  102. }
  103. }
  104. else
  105. {
  106. throw new Exception(string.Format("类库{0}里没有Export的Service!", serviceRuntime));
  107. }
  108. }
  109. catch (Exception ex)
  110. {
  111. throw ex;
  112. }
  113. }
  114. /// <summary>
  115. /// 获取Service的实例
  116. /// </summary>
  117. /// <typeparam name="T">接口对象</typeparam>
  118. /// <returns></returns>
  119. public static T Resolve<T>()
  120. {
  121. if (Services.ContainsKey(typeof(T)))
  122. return (T)Services[typeof(T)];
  123. return default(T);
  124. }
  125. /// <summary>
  126. /// 重置Service对象,实现热更新
  127. /// </summary>
  128. /// <typeparam name="T">接口对象</typeparam>
  129. /// <param name="t">新的服务对象实例</param>
  130. public static void ReLoadService<T>(T t)
  131. {
  132. if (t == null)
  133. {
  134. throw new Exception(string.Format("未将对象实例化,对象名:{0}.", typeof(T).Name));
  135. }
  136. if (Services.ContainsKey(typeof(T)))
  137. {
  138. try
  139. {
  140. Services[typeof(T)] = t;
  141. if (ServiceEvents.ContainsKey(typeof(T)))
  142. {
  143. var eventList = ServiceEvents[typeof(T)];
  144. foreach (var act in eventList)
  145. {
  146. act.Invoke(t);
  147. }
  148. }
  149. }
  150. catch (Exception ex)
  151. {
  152. throw ex;
  153. }
  154. }
  155. else if (!Services.ContainsKey(typeof(T)))
  156. {
  157. throw new Exception(string.Format("Service实例不存在!对象名:{0}.", typeof(T).Name));
  158. }
  159. }
  160. /// <summary>
  161. /// 激活上下文
  162. /// </summary>
  163. public void Start()
  164. {
  165. GetInstance();
  166. }
  167. /// <summary>
  168. /// 激活上下文
  169. /// </summary>
  170. /// <param name="appContext">真正的ApplicationContext对象</param>
  171. public void Start(ApplicationContext appContext)
  172. {
  173. Application_Context = appContext;
  174. GetInstance();
  175. }
  176. /// <summary>
  177. /// 激活上下文
  178. /// </summary>
  179. /// <param name="config">Configuration</param>
  180. public void Start(Configuration config)
  181. {
  182. AppConfig = config;
  183. GetInstance();
  184. }
  185. /// <summary>
  186. /// 激活上下文
  187. /// </summary>
  188. /// <param name="appContext">真正的ApplicationContext对象</param>
  189. /// <param name="config">Configuration</param>
  190. public void Start(ApplicationContext appContext, Configuration config)
  191. {
  192. AppConfig = config;
  193. Application_Context = appContext;
  194. GetInstance();
  195. }
  196. /// <summary>
  197. /// Using支持
  198. /// </summary>
  199. public void Dispose()
  200. {
  201. Services.Clear();
  202. ServiceEvents.Clear();
  203. if (Application_Context != null)
  204. {
  205. Application_Context.ExitThread();
  206. }
  207. }
  208. }

使用:

  1. AppContextExt.GetInstance().Start();
  2. AppContextExt.RegisterAssemblyServices(AppDomain.CurrentDomain.BaseDirectory + "ModuleService.dll");
  1. ILogService svr = AppContextExt.Resolve<ILogService>();
  2. if (svr != null)
  3. svr.LogInfo("OK");

解决方案截图:

C#自定义应用程序上下文对象+IOC自己实现依赖注入的更多相关文章

  1. IoC COntainer Create Javabeans 可以通过读取beans.xml 文件来创建一个应用程序上下文对象 依赖反转

    Spring初学快速入门 - Spring教程™ https://www.yiibai.com/spring/spring-tutorial-for-beginners.html# pom <? ...

  2. Spring IOC - 控制反转(依赖注入) - 入门案例 - 获取对象的方式 - 别名标签

    1. IOC - 控制反转(依赖注入) 所谓的IOC称之为控制反转,简单来说就是将对象的创建的权利及对象的生命周期的管理过程交 由Spring框架来处理,从此在开发过程中不再需要关注对象的创建和生命周 ...

  3. 深入分析MVC中通过IOC实现Controller依赖注入的原理

    这几天利用空闲时间,我将ASP.NET反编译后的源代码并结合园子里几位大侠的写的文章认真的看了一遍,收获颇丰,同时也摘要了一些学习内容,存入了该篇文章:<ASP.NET运行机制图解>,在对 ...

  4. 控制反转(IoC)与依赖注入(DI)

    前言 最近在学习Spring框架,它的核心就是IoC容器.要掌握Spring框架,就必须要理解控制反转的思想以及依赖注入的实现方式.下面,我们将围绕下面几个问题来探讨控制反转与依赖注入的关系以及在Sp ...

  5. 控制反转( IoC)和依赖注入(DI)

    控制反转( IoC)和依赖注入(DI) tags: 容器 依赖注入 IOC DI 控制反转 引言:如果你看过一些框架的源码或者手册,像是laravel或者tp5之类的,应该会提到容器,依赖注入,控制反 ...

  6. springboot成神之——ioc容器(依赖注入)

    springboot成神之--ioc容器(依赖注入) spring的ioc功能 文件目录结构 lang Chinese English GreetingService MyRepository MyC ...

  7. Spring的控制反转(IOC)和依赖注入(DI)具体解释

    Spring的控制反转(IOC)和依赖注入(DI)具体解释 首先介绍下(IOC)控制反转: 所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的.这样控制器就有应 ...

  8. 依赖倒置原则(DIP)、控制反转(IoC)、依赖注入(DI)(C#)

    理解: 依赖倒置原则(DIP)主程序要依赖于抽象接口,不要依赖于具体实现.高层模块不应该依赖底层模块,两个都应该以来抽象.抽象不应该依赖细节,细节应该依赖抽象.(具体看我上一篇贴子) 依赖倒置原则是六 ...

  9. Spring升级案例之IOC介绍和依赖注入

    Spring升级案例之IOC介绍和依赖注入 一.IOC的概念和作用 1.什么是IOC 控制反转(Inversion of Control, IoC)是一种设计思想,在Java中就是将设计好的对象交给容 ...

随机推荐

  1. 痞子衡嵌入式:ARM Cortex-M文件那些事(2)- 链接文件(.icf)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是嵌入式开发里的linker文件. 在前一节课源文件(.c/.h/.s)里,痞子衡给大家系统地介绍了source文件,source文件是嵌入 ...

  2. Smobiler 4.4 更新预告 Part 2(Smobiler能让你在Visual Studio上开发APP)

    Hello Everybody,在Smobiler 4.4中,也为大家带来了新增功能和插件(重点,敲黑板). 新增功能: 1, 企业认证用户可设置路由(即客户端可根据不同的IP地址访问不同的服务器组) ...

  3. wpf 无缝滚动

    很早以前有项目就需要文字无缝滚动的效果但无奈当时技术不到位 人也比较懒惰(大概程序猿都是这个样子吧) 此方法并非只文字无缝其实任何内容都可以 <ScrollViewer Name="s ...

  4. C# 判断用户是否对路径拥有访问权限

    如何获取当前系统用户对文件/文件夹的操作权限? 1.获取安全信息DirectorySecurity DirectorySecurity fileAcl = Directory.GetAccessCon ...

  5. Qt 给控件QLineEdit添加clicked事件方法

    做Qt开发的会知道QLineEdit是默认没有clicked事件的,但是Qt有很好的一套信号/槽机制,而且Qt是基于C++面向对象的思想来设计的,那么我们就很容易通过自己定义一些类,重写QLineEd ...

  6. ElasticSearch-6.2安装head插件

    环境 Windows10企业版X64 JDK-1.8 ElasticSearch-6.2.4 node-v10.1 git客户端 步骤 安装node到K盘.如K:\nodejs. 把NODE_HOME ...

  7. 忘记时间戳的存在——Yii2超实用的自动更新时间戳的Behavior(改进版)

    本文改进了Yii2中内置行为类TimestampBehavior,使得时间戳字段(如created_at,updated_at) 完全自己更新,方便得让你忘记它们的存在. Yii2的内置行为类Time ...

  8. java-自定义数据排序

    导读:由于基本类型的数据都实现了一个共同的接口java.lang.Comparable接口,都实现了该接口下面的compareTo()方法,因此想要利用面向对象实现现实生活中的一些情景再现,比如新闻根 ...

  9. 混用Int与IntPtr导致GetProcAddress始终返回null

      注意NET某些类型在不同平台上的长度 NET中用句柄用得最多的是在DLLIMPORT中,混用int与intptr可能会导致某些API声明在X64平台中表现不正常,如 [DllImport(&quo ...

  10. 怎么打开iPhone的开发者模式

    1.需要连接Xcode 2.打开一个app就有了