自己实现的一个简单的C# IOC 容器
IService接口,以实现服务的启动、停止功能:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Utils
{
/// <summary>
/// 服务接口
/// </summary>
public interface IService
{
/// <summary>
/// 服务启动
/// </summary>
void OnStart(); /// <summary>
/// 服务停止
/// </summary>
void OnStop();
}
}
AbstractService服务抽象类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Utils
{
/// <summary>
/// 服务抽象类
/// </summary>
public abstract class AbstractService : IService
{
/// <summary>
/// 服务启动
/// </summary>
public virtual void OnStart() { } /// <summary>
/// 服务停止
/// </summary>
public virtual void OnStop() { }
}
}
IOC容器帮助类:

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Web; namespace Utils
{
/// <summary>
/// 服务帮助类
/// </summary>
public partial class ServiceHelper
{
#region 变量
/// <summary>
/// 接口的对象集合
/// </summary>
private static ConcurrentDictionary<Type, object> _dict = new ConcurrentDictionary<Type, object>();
#endregion #region Get 获取实例
/// <summary>
/// 获取实例
/// </summary>
public static T Get<T>()
{
Type type = typeof(T);
object obj = _dict.GetOrAdd(type, key => Activator.CreateInstance(type)); return (T)obj;
}
#endregion #region Get 通过Func获取实例
/// <summary>
/// 获取实例
/// </summary>
public static T Get<T>(Func<T> func)
{
Type type = typeof(T);
object obj = _dict.GetOrAdd(type, (key) => func()); return (T)obj;
}
#endregion #region RegisterAssembly 注册程序集
/// <summary>
/// 注册程序集
/// </summary>
/// <param name="type">程序集中的一个类型</param>
public static void RegisterAssembly(Type type)
{
RegisterAssembly(Assembly.GetAssembly(type).FullName);
} /// <summary>
/// 注册程序集
/// </summary>
/// <param name="assemblyString">程序集名称的长格式</param>
public static void RegisterAssembly(string assemblyString)
{
LogTimeUtil logTimeUtil = new LogTimeUtil();
Assembly assembly = Assembly.Load(assemblyString);
Type[] typeArr = assembly.GetTypes();
string iServiceInterfaceName = typeof(IService).FullName; foreach (Type type in typeArr)
{
Type typeIService = type.GetInterface(iServiceInterfaceName);
if (typeIService != null && !type.IsAbstract)
{
Type[] interfaceTypeArr = type.GetInterfaces();
object obj = Activator.CreateInstance(type);
_dict.GetOrAdd(type, obj); foreach (Type interfaceType in interfaceTypeArr)
{
if (interfaceType != typeof(IService))
{
_dict.GetOrAdd(interfaceType, obj);
}
}
}
}
logTimeUtil.LogTime("ServiceHelper.RegisterAssembly 注册程序集 " + assemblyString + " 耗时");
}
#endregion #region 启动所有服务
/// <summary>
/// 启动所有服务
/// </summary>
public static Task StartAllService()
{
return Task.Run(() =>
{
List<Task> taskList = new List<Task>();
foreach (object o in _dict.Values.Distinct())
{
Task task = Task.Factory.StartNew(obj =>
{
IService service = obj as IService; try
{
service.OnStart();
LogUtil.Log("服务 " + obj.GetType().FullName + " 已启动");
}
catch (Exception ex)
{
LogUtil.Error(ex, "服务 " + obj.GetType().FullName + " 启动失败");
}
}, o);
taskList.Add(task);
}
Task.WaitAll(taskList.ToArray());
});
}
#endregion #region 停止所有服务
/// <summary>
/// 停止所有服务
/// </summary>
public static Task StopAllService()
{
return Task.Run(() =>
{
List<Task> taskList = new List<Task>();
Type iServiceInterfaceType = typeof(IService);
foreach (object o in _dict.Values.Distinct())
{
Task task = Task.Factory.StartNew(obj =>
{
if (iServiceInterfaceType.IsAssignableFrom(obj.GetType()))
{
IService service = obj as IService; try
{
service.OnStop();
LogUtil.Log("服务 " + obj.GetType().FullName + " 已停止").Wait();
}
catch (Exception ex)
{
LogUtil.Error(ex, "服务 " + obj.GetType().FullName + " 停止失败").Wait();
}
}
}, o);
taskList.Add(task);
}
Task.WaitAll(taskList.ToArray());
});
}
#endregion }
}
说明:
RegisterAssembly方法:注册实现类,只要程序集中的类实现了某个接口,就注册,把它的类型以及接口的类型作为Key添加到字典中,以接口类型作为Key的时候,过滤掉IService这个接口。
StartAllService方法:调用所有服务的OnStart方法。
StopAllService方法:调用所有服务的OnStop方法。
如何使用:
服务的注册与启动:

ServiceHelper.RegisterAssembly(typeof(MyActionFilter));
ServiceHelper.StartAllService().Wait();
说明:RegisterAssembly方法的参数,传递程序集中任何一个类型即可。
服务的停止:

ServiceHelper.StopAllService().Wait();
服务的定义:

using Models;
using Newtonsoft.Json;
using NetWebApi.DAL;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Web;
using System.Collections.Concurrent;
using Utils;
using System.Configuration; namespace NetWebApi.BLL
{
/// <summary>
/// 通用
/// </summary>
public class CommonBll : AbstractService
{
#region OnStart 服务启动
/// <summary>
/// 服务启动
/// </summary>
public override void OnStart()
{ }
#endregion #region OnStop 服务停止
/// <summary>
/// 服务停止
/// </summary>
public override void OnStop()
{ }
#endregion }
}
调用服务:

CommonBll commonBll = ServiceHelper.Get<CommonBll>();
临时注册并调用服务:

SaveDataBll m_SaveDataBll = ServiceHelper.Get<SaveDataBll>();
自己实现的一个简单的C# IOC 容器的更多相关文章
- 造轮子:实现一个简易的 Spring IoC 容器
作者:DeppWang.原文地址 我通过实现一个简易的 Spring IoC 容器,算是入门了 Spring 框架.本文是对实现过程的一个总结提炼,需要配合源码阅读,源码地址. 结合本文和源码,你应该 ...
- (反射+内省机制的运用)简单模拟spring IoC容器的操作
简单模拟spring IoC容器的操作[管理对象的创建.管理对象的依赖关系,例如属性设置] 实体类Hello package com.shan.hello; public class Hello { ...
- 写了一个简单可用的IOC
根据<架构探险从零开始写javaweb框架>内容写的一个简单的 IOC 学习记录 只说明了主要的类,从上到下执行的流程,需要分清主次,无法每个类都说明,只是把整个主线流程说清楚,避免 ...
- 一个简单易用的容器管理平台-Humpback
什么是Humpback? 在回答这个问题前,我们得先了解下什么的 Docker(哦,现在叫 Moby,文中还是继续称 Docker). 在 Docker-百度百科 中,对 Docker 已经解释得很清 ...
- Spring容器的简单实现(IOC原理)
引言:容器是什么?什么是容器?Spring容器又是啥东西?我给Spring容器一个对象名字,为啥能给我创建一个对象呢? 一.容器是装东西的,就像你家的水缸,你吃饭的碗等等. java中能作为容器的有很 ...
- 自己动手实现一个简单的 IOC容器
控制反转,即Inversion of Control(IoC),是面向对象中的一种设计原则,可以用有效降低架构代码的耦合度,从对象调用者角度又叫做依赖注入,即Dependency Injection( ...
- 简单讲解Asp.Net Core自带IOC容器ServiceCollection
一. 理解ServiceCollection之前先要熟悉几个概念:DIP.IOC.DI.Ioc容器: 二. 接下来先简单说一下几个概念问题: 1.DIP(依赖倒置原则):六大设计原则里面一种设计原 ...
- 揣摩实现一个ioc容器需要做的事情
思路: ioc框架的核心就是管理bean的生命周期,bean的生命周期包括:创建,使用,销毁. 创建 容器在创建一个bean的实例之前必须要解决以下问题:第一个问题: 创建bean的信息如何提供给你容 ...
- 《Spring 手撸专栏》第 2 章:小试牛刀(让新手能懂),实现一个简单的Bean容器
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 上学时,老师总说:不会你就问,但多数时候都不知道要问什么! 你总会在小傅哥的文章前言 ...
- 详解依赖注入(DI)和Ioc容器
简单的来说,关键技术就是:注册器模式. 场景需求 我们知道写一个类的时候,类本身是有个目的的,类里面有很多方法,每个方法搞定一些事情:我们叫这个类为主类. 另外这个主类会依赖一些其他类的帮忙,我们叫这 ...
随机推荐
- Educational Codeforces Round 105 (Rated for Div. 2) A-C题解
写在前边 链接:Educational Codeforces Round 105 (Rated for Div. 2) A. ABC String 链接:A题链接 题目大意: 给定一个有\(A.B.C ...
- Android 锁屏时的生命周期
锁定屏幕前,应用被打开:onCreate->onStart->onResume 此时按下电源键,锁定屏幕:onPause->onStop 解锁屏幕,重新回到应用:onRestart- ...
- centos 7.9安装Prometheus
一.Prometheus功能 Prometheus 在系统监控和警报方面非常强大,它适用于多种应用场景.以下是一些常见的 Prometheus 应用场景,以及具体的例子: 性能监控:Prometheu ...
- 如何修改Ubuntu的时间与时间同步
1.安装ntpdate,同步标准时间 zce@ubuntu:~$ sudo apt install ntpdate 输入管理员密码确认安装 zce@ubuntu:~$ sudo apt install ...
- RTMP协议学习——Message与Chunk解读
前言 之前通过对抓包数据的学习和分析,对RTMP协议有了一个整体的认知,大致了解了RTMP从建立连接到播放视频的流程,文章请看<RTMP协议学习--从握手到播放>.但是对于RTMP消息传输 ...
- [CF1229E]Marek and Matching
This is a harder version of the problem. In this version, \(n \le 7\). Marek is working hard on crea ...
- 神经网络优化篇:详解归一化输入(Normalizing inputs)
归一化输入 训练神经网络,其中一个加速训练的方法就是归一化输入.假设一个训练集有两个特征,输入特征为2维,归一化需要两个步骤: 零均值 归一化方差: 希望无论是训练集和测试集都是通过相同的\(μ\)和 ...
- Windows 7更新失败的解决方法
你好,1.在开始菜单中点击运行,→输入"services.msc"→找到"windows update"右击选择"停止":2.进入C:\wi ...
- java:JDBC使用步骤(mysql)java小白的第一篇博客
1:环境要求 先在你的mysql里面创造一个数据库(并添加一点数据) 下载并导入驱动 2:jdbc的五大步骤 第一步:加载mysql驱动: 1 Class.forName("com.mysq ...
- ZincSearch轻量级全文搜索引擎入门到
ZincSearch轻量级全文搜索引擎入门到 Zinc是一个用于对文档进行全文搜索的搜索引擎.它是开源的,内置在 Go 中.Zinc不是从头开始构建索引引擎,而是构建在 bluge 之上,这是一个出色 ...