自己实现的一个简单的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容器
简单的来说,关键技术就是:注册器模式. 场景需求 我们知道写一个类的时候,类本身是有个目的的,类里面有很多方法,每个方法搞定一些事情:我们叫这个类为主类. 另外这个主类会依赖一些其他类的帮忙,我们叫这 ...
随机推荐
- 深入理解RC4加密算法
RC4(Rivest Cipher 4)是一种广泛应用的加密算法,由Ronald L. Rivest于1987年发明.它是一种流密码(stream cipher)算法,适用于对网络通信中的数据进行加密 ...
- OpenSSL 使用AES对文件加解密
AES(Advanced Encryption Standard)是一种对称加密算法,它是目前广泛使用的加密算法之一.AES算法是由美国国家标准与技术研究院(NIST)于2001年发布的,它取代了原先 ...
- IDEA提示Cannot resolve class or package ‘beans‘等类似错误
一.解决方案 1.问题原因: 2.解决: 快捷键:Alt+Enter选择.
- .NET使用分布式网络爬虫框架DotnetSpider快速开发爬虫功能
前言 前段时间有同学在微信群里提问,要使用.NET开发一个简单的爬虫功能但是没有做过无从下手.今天给大家推荐一个轻量.灵活.高性能.跨平台的分布式网络爬虫框架(可以帮助 .NET 工程师快速的完成爬虫 ...
- 本地数据备份与FTP远程数据迁移
数据是电脑中最重要的东西.为了保证数据安全,我们经常会对数据进行备份.之前一直采用将重要数据拷贝至移动硬盘的方式实现备份,实现简单但每次都需要把所有文件拷贝一次,当文件很大时效率较低. 因此,考虑使用 ...
- jdk21的外部函数和内存API(MemorySegment)(官方翻译)
1.jdk21: 引入一个 API,通过该 API,Java 程序可以与 Java 运行时之外的代码和数据进行互操作.通过有效地调用外部函数(即JVM外部的代码)和安全地访问外部内存(即不由JVM ...
- serdes级联时钟
级联时钟在其他的IP领域下很少见到,在serdes中时个基本的功能. 因为高密场景下需要时钟数几十个IP,一般摆放在芯片边缘位置. 而SOC的管脚资源非常有限.因此就需要多个IP之间的ref clk进 ...
- [NOI online2022普及C]字符串
题目描述 Kri 非常喜欢字符串,所以他准备找 \(t\) 组字符串研究. 第 \(i\) 次研究中,Kri 准备了两个字符串 \(S\) 和\(R\) ,其中 \(S\) 长度为 \(n\),且只由 ...
- 浅谈 Socket.D 与响应式编程
一.Socket.D 的主要特性 首先,Scoket.D 是高效一个二进制的网络通讯协议(官方我讲法是:基于事件和语义消息流的网络应用协议),能够满足很多场景下使用.其次,Scoket.D 是温和的响 ...
- 在arm架构的银河麒麟系统部署Nginx
以下是在arm架构的银河麒麟系统上部署Nginx的详细步骤: 1. 创建文件夹 首先,在合适的位置创建必要的文件夹.在本例中,我们将创建/opt/nginx和/usr/src/nginx两个文件夹. ...