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

    /// <summary>
/// 自定义应用程序上下文对象
/// </summary>
public class AppContextExt : IDisposable
{
/// <summary>
/// app.config读取
/// </summary>
public Configuration AppConfig { get; set; }
/// <summary>
/// 真正的ApplicationContext对象
/// </summary>
public ApplicationContext Application_Context { get; set; }
//服务集合
public static Dictionary<Type, object> Services = new Dictionary<Type, object>();
//服务订阅事件集合
public static Dictionary<Type, IList<Action<object>>> ServiceEvents = new Dictionary<Type, IList<Action<object>>>();
//上下文对象的单例
private static AppContextExt _ServiceContext = null;
private readonly static object lockObj = new object();
/// <summary>
/// 禁止外部进行实例化
/// </summary>
private AppContextExt()
{
}
/// <summary>
/// 获取唯一实例,双锁定防止多线程并发时重复创建实例
/// </summary>
/// <returns></returns>
public static AppContextExt GetInstance()
{
if (_ServiceContext == null)
{
lock (lockObj)
{
if (_ServiceContext == null)
{
_ServiceContext = new AppContextExt();
}
}
}
return _ServiceContext;
}
/// <summary>
/// 注入Service到上下文
/// </summary>
/// <typeparam name="T">接口对象</typeparam>
/// <param name="t">Service对象</param>
/// <param name="servicesChangeEvent">服务实例更新时订阅的消息</param>
public static void RegisterService<T>(T t, Action<object> servicesChangeEvent = null) where T : class
{
if (t == null)
{
throw new Exception(string.Format("未将对象实例化,对象名:{0}.", typeof(T).Name));
}
if (!Services.ContainsKey(typeof(T)))
{
try
{
Services.Add(typeof(T), t);
if (servicesChangeEvent != null)
{
var eventList = new List<Action<object>>();
eventList.Add(servicesChangeEvent);
ServiceEvents.Add(typeof(T), eventList);
}
}
catch (Exception ex)
{
throw ex;
}
}
if (!Services.ContainsKey(typeof(T)))
{
throw new Exception(string.Format("注册Service失败,对象名:{0}.", typeof(T).Name));
}
}
/// <summary>
/// 动态注入dll中的多个服务对象
/// </summary>
/// <param name="serviceRuntime"></param>
public static void RegisterAssemblyServices(string serviceRuntime)
{
if (serviceRuntime.IndexOf(".dll") != -1 && !File.Exists(serviceRuntime))
throw new Exception(string.Format("类库{0}不存在!", serviceRuntime));
try
{
Assembly asb = Assembly.LoadFrom(serviceRuntime);
var serviceList = asb.GetTypes().Where(t => t.GetCustomAttributes(typeof(ExportAttribute), false).Any()).ToList();
if (serviceList != null && serviceList.Count > 0)
{
foreach (var service in serviceList)
{
var ifc = ((ExportAttribute)service.GetCustomAttributes(typeof(ExportAttribute), false).FirstOrDefault()).ContractType;
//使用默认的构造函数实例化
var serviceObject = Activator.CreateInstance(service, null);
if (serviceObject != null)
Services.Add(ifc, serviceObject);
else
throw new Exception(string.Format("实例化对象{0}失败!", service));
}
}
else
{
throw new Exception(string.Format("类库{0}里没有Export的Service!", serviceRuntime));
}
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 获取Service的实例
/// </summary>
/// <typeparam name="T">接口对象</typeparam>
/// <returns></returns>
public static T Resolve<T>()
{
if (Services.ContainsKey(typeof(T)))
return (T)Services[typeof(T)];
return default(T);
}
/// <summary>
/// 重置Service对象,实现热更新
/// </summary>
/// <typeparam name="T">接口对象</typeparam>
/// <param name="t">新的服务对象实例</param>
public static void ReLoadService<T>(T t)
{
if (t == null)
{
throw new Exception(string.Format("未将对象实例化,对象名:{0}.", typeof(T).Name));
}
if (Services.ContainsKey(typeof(T)))
{
try
{
Services[typeof(T)] = t;
if (ServiceEvents.ContainsKey(typeof(T)))
{
var eventList = ServiceEvents[typeof(T)];
foreach (var act in eventList)
{
act.Invoke(t);
}
}
}
catch (Exception ex)
{
throw ex;
}
}
else if (!Services.ContainsKey(typeof(T)))
{
throw new Exception(string.Format("Service实例不存在!对象名:{0}.", typeof(T).Name));
}
}
/// <summary>
/// 激活上下文
/// </summary>
public void Start()
{
GetInstance();
}
/// <summary>
/// 激活上下文
/// </summary>
/// <param name="appContext">真正的ApplicationContext对象</param>
public void Start(ApplicationContext appContext)
{
Application_Context = appContext;
GetInstance();
}
/// <summary>
/// 激活上下文
/// </summary>
/// <param name="config">Configuration</param>
public void Start(Configuration config)
{
AppConfig = config;
GetInstance();
}
/// <summary>
/// 激活上下文
/// </summary>
/// <param name="appContext">真正的ApplicationContext对象</param>
/// <param name="config">Configuration</param>
public void Start(ApplicationContext appContext, Configuration config)
{
AppConfig = config;
Application_Context = appContext;
GetInstance();
}
/// <summary>
/// Using支持
/// </summary>
public void Dispose()
{
Services.Clear();
ServiceEvents.Clear();
if (Application_Context != null)
{
Application_Context.ExitThread();
}
}
}

使用:

 AppContextExt.GetInstance().Start();
AppContextExt.RegisterAssemblyServices(AppDomain.CurrentDomain.BaseDirectory + "ModuleService.dll");
ILogService svr = AppContextExt.Resolve<ILogService>();
if (svr != null)
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. [总结] NOIP 前的考试记录

    sb博主又犯sb错误了! 他觉得以往模拟赛因为犯sb错误扔的分足足有1k分了! 于是他想记录一下自己犯的sb错误看看自己到底有多sb! 嗯就从今天开始吧 2018.9.28 1. 二分边界写错.骚什么 ...

  2. [Luogu4705] 玩游戏

    Description 给定两个长度分别为 \(n\) 和 \(m\) 的序列 \(a\) 和 \(b\).要从这两个序列中分别随机一个数,设为 \(a_x,b_y\),定义该次游戏的 \(k\) 次 ...

  3. webpack4.0各个击破(7)—— plugin篇

    webpack作为前端最火的构建工具,是前端自动化工具链最重要的部分,使用门槛较高.本系列是笔者自己的学习记录,比较基础,希望通过问题 + 解决方式的模式,以前端构建中遇到的具体需求为出发点,学习we ...

  4. C# 如何添加PPT背景(纯色背景、渐变色背景、图片背景)

    我们在创建Powerpoint文档时,系统默认的幻灯片是空白背景的,很多时候我们需要自定义幻灯片背景,以达到美观的文档效果.在下面的示例中将介绍给PowerPoint幻灯片设置背景的方法,主要包含以下 ...

  5. 【Mybatis】使用Mybatis-Generator自动生成entity、dao、mapping

    使用过mybatis的应该都有用过Mybatis-Generator,本文主要介绍使用Mybatis-Generator来自动生成entity.dao.mapping文件. Mybatis-Gener ...

  6. 18、实现strStr()

    18.实现strStr() 实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 ( ...

  7. JS 无限长form表单提交

    1 简介 开发时候,总会遇到根据后台传的变量{组件数}来动态渲染组件的情况,比如后台传命令要绑定10个父子关系,则前台展开十个input组件,后台决定绑定5个福字关系,则前台展开5个input组件.再 ...

  8. CSS常见的中属性级,选择符级的Hack

    注意:尽量找到通用方法而减少对CSS Hack的使用,大规模使用CSS Hack会带来维护成本的提高以及浏览器版本变化而带来类似Hack失效等系列问题. 星号 * 针对IE6,7:下划线 _ 针对ie ...

  9. bitset用法小结

    bitset bitset大概就是类似于bool数组一样的东西 但是它的每个位置只占1bit(特别特别小) bitset的原理大概是将很多数压成一个,从而节省空间和时间(暴力出奇迹) 一般来说bits ...

  10. Android WebView的HTML中的select标签不起作用

    Android WebView的HTML中的select标签不起作用 经过查询资料,了解到android对html里的select标签是弹出一个原生的选择器. 问题: Webview中的select没 ...