自己实现的一个简单的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容器
简单的来说,关键技术就是:注册器模式. 场景需求 我们知道写一个类的时候,类本身是有个目的的,类里面有很多方法,每个方法搞定一些事情:我们叫这个类为主类. 另外这个主类会依赖一些其他类的帮忙,我们叫这 ...
随机推荐
- Android Sutdio 编入System API 等隐藏API 方法
1. 将 classes.jar 放入 app/libs 文件夹下 右键点击 jar 包,点击 Add as Library 2. 项目级 Gradle 文件新增以下配置 gradle.project ...
- 飞码LowCode前端技术之画布的设计
简介 本章节从精准定位.分层设计.异步组件.拖拽四个方面分析飞码画布设计. 一.精准定位设计 飞码画布是一个套件,可对外提供画布能力.精准定位有两种情况,一是目标组件无子组件,而是目标组件有子组件. ...
- 一文带你掌握C语言的分支结构
C语言分支结构详解 1. if 语句 在本篇博客文章中,我们将深入探讨C语言中的if语句及其相关用法.if语句是一种用于条件判断的分支语句,它允许我们根据条件的真假来执行不同的代码块. 1.1 if ...
- freeswitch如何解决sip信令的NAT问题
概述 freeswitch是一款简单好用的VOIP开源软交换平台. 公网环境复杂多变,客户环境更是各种稀奇古怪的问题. fs在针对sip信令的NAT问题有针对性的参数设置. 本文讨论的范围限于fs的公 ...
- [cnn]FashionMINST训练+保存模型+调用模型判断给定图片
import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim impor ...
- npm install 报-4048错误
报错原因: 有缓存 权限不够 有三种解决方法: 第一种:找到.npmrc文件并删除 在 C:\Users\自己用户的文件夹\ 下找到 .npmrc 文件并删除 注意:这个文件是隐藏的,需要显示隐藏才能 ...
- Chrome扩展开发系列开篇
大家好,我是 dom 哥.这是我关于 Chrome 扩展开发的系列文章,感兴趣的可以 点个小星星. 浏览器现状 研究机构 Statcounter 发布了 2023 年 9 月报告,揭示了有关浏览器的最 ...
- 用JS实现简单的屏幕录像机
本文将介绍如何用JS实现简单的屏幕录像机. 一.录制准备 创建一个按钮 <button id="recording-toggle">Start recording< ...
- 一文掌握 Kubernetes 证书
如果你正在自己的环境中运行 Kubernetes,那么了解证书的工作原理以及如何管理它们以确保集群的安全性和完整性至关重要.在本文中,我们将解释什么是 Kubernetes 证书.其重要性,以及如何检 ...
- ez_curl【代码审计】
ez_curl[代码审计][难度:4] 题目描述 代码审计类题目,附上代码: <?php highlight_file(__FILE__); $url = 'http://back-end:30 ...