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 容器的更多相关文章

  1. 造轮子:实现一个简易的 Spring IoC 容器

    作者:DeppWang.原文地址 我通过实现一个简易的 Spring IoC 容器,算是入门了 Spring 框架.本文是对实现过程的一个总结提炼,需要配合源码阅读,源码地址. 结合本文和源码,你应该 ...

  2. (反射+内省机制的运用)简单模拟spring IoC容器的操作

    简单模拟spring IoC容器的操作[管理对象的创建.管理对象的依赖关系,例如属性设置] 实体类Hello package com.shan.hello; public class Hello { ...

  3. 写了一个简单可用的IOC

    根据<架构探险从零开始写javaweb框架>内容写的一个简单的 IOC 学习记录    只说明了主要的类,从上到下执行的流程,需要分清主次,无法每个类都说明,只是把整个主线流程说清楚,避免 ...

  4. 一个简单易用的容器管理平台-Humpback

    什么是Humpback? 在回答这个问题前,我们得先了解下什么的 Docker(哦,现在叫 Moby,文中还是继续称 Docker). 在 Docker-百度百科 中,对 Docker 已经解释得很清 ...

  5. Spring容器的简单实现(IOC原理)

    引言:容器是什么?什么是容器?Spring容器又是啥东西?我给Spring容器一个对象名字,为啥能给我创建一个对象呢? 一.容器是装东西的,就像你家的水缸,你吃饭的碗等等. java中能作为容器的有很 ...

  6. 自己动手实现一个简单的 IOC容器

    控制反转,即Inversion of Control(IoC),是面向对象中的一种设计原则,可以用有效降低架构代码的耦合度,从对象调用者角度又叫做依赖注入,即Dependency Injection( ...

  7. 简单讲解Asp.Net Core自带IOC容器ServiceCollection

    一.  理解ServiceCollection之前先要熟悉几个概念:DIP.IOC.DI.Ioc容器: 二.  接下来先简单说一下几个概念问题: 1.DIP(依赖倒置原则):六大设计原则里面一种设计原 ...

  8. 揣摩实现一个ioc容器需要做的事情

    思路: ioc框架的核心就是管理bean的生命周期,bean的生命周期包括:创建,使用,销毁. 创建 容器在创建一个bean的实例之前必须要解决以下问题:第一个问题: 创建bean的信息如何提供给你容 ...

  9. 《Spring 手撸专栏》第 2 章:小试牛刀(让新手能懂),实现一个简单的Bean容器

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 上学时,老师总说:不会你就问,但多数时候都不知道要问什么! 你总会在小傅哥的文章前言 ...

  10. 详解依赖注入(DI)和Ioc容器

    简单的来说,关键技术就是:注册器模式. 场景需求 我们知道写一个类的时候,类本身是有个目的的,类里面有很多方法,每个方法搞定一些事情:我们叫这个类为主类. 另外这个主类会依赖一些其他类的帮忙,我们叫这 ...

随机推荐

  1. 🔥🔥Java开发者的Python快速进修指南:文件操作

    Python提供的文件操作相对于Java来说,确实简单方便许多.不仅操作简单,代码可读性也相对较高.然而,我们需要注意的不仅仅是文件操作的简单性,还有文件操作的各种模式.在Java中,我们并不经常使用 ...

  2. Springboot 自动发送邮件

    完成Springboot配置发件邮箱,自动给其他邮箱发送邮件功能 一.创建springboot基础项目,引入依赖 <!-- Spring Boot 邮件依赖 --> <depende ...

  3. 聊聊分布式 SQL 数据库Doris(六)

    负载均衡 此处的负载均衡指的是FE层的负载均衡. 当部署多个 FE 节点时,用户可以在多个 FE 之上部署负载均衡层来实现 Doris 的高可用.官方文档描述: 负载均衡 . 实现方式 实现方式有多种 ...

  4. 本地部署modelscope-agent

    本地部署modelscope-agent 部署流程 在modelscope社区创建一个自己的空间(假设name是LocalAgent),clone空间到本地(或云服务器如魔搭Notebook) git ...

  5. uniapp的下载

    简介 - HBuilderX 文档 (dcloud.net.cn) 下载Hbuiler 直接打开HbuilderX.exe就可以直接使用 可以通过他来创建模板 目录

  6. 7、If分支语句

    1.程序的流程结构 程序的流程控制结构一共有三种: 顺序结构 选择结构 循环结构. 顺序结构: 从上向下 逐行执行 选择结构:条件满足,某些代码才会执行.0-1次 分支语句: if,switch,se ...

  7. 华企盾DSC邮件服务器测试连接提示Server has closed the connection(端口不对)

    解决方法:邮件服务器端口填错了,应该是smtp.126.com:s465,或者smtp.126.com:s587 其他邮箱同理.

  8. 华企盾DSC邮箱服务器测试连接提示Undefined error id(端口不通)

    解决方法:由于云服务器没有开25端口,telnet不通(telnet smtp.163.com 25),允许一下25端口即可,如果不能启用25端口,则开启465或者587

  9. IntelliJ IDEA下载安装,以及关联gitee

    https://www.jetbrains.com.cn/ 点击下载 IntelliJ IDEA Ultimate 旗舰版(收费) IntelliJ IDEA Community 社区版(免费) 安装 ...

  10. Fdfs上传的图片批量删除

    介绍: 因为计划利用fdfs上传的图片会有很多,所以在考虑到重复利用的情况下,把半年前的图片删除掉. 1)编写清理图片脚本clear.sh 在/home/data目录下创建 clear.sh脚本 内容 ...