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. Codeforces Round #704 (Div. 2) A~C题解

    写在前边 链接:Codeforces Round #704 (Div. 2) D就不补了,大fst场. A. Three swimmers 链接:A题链接 题目大意: 给定三个游泳者的到达岸边的周期, ...

  2. Mariadb 10.4 root 用户无法使用无密码登录的原因

    Mariadb现在是网站建设中使用的主流数据库之一,当前它很多个版本:10.1.10.2.10.3.10.4. 其中10.1和10.2在程序中使用root用户登录连接数据库都没有什么问题. 如果是10 ...

  3. python01-基础概念与环境搭建

    学习目标 了解硬件 & 操作系统 & 软件(应用系统)之间的关系. 了解常见的操作系统都有哪些. 了解编译器和解释器的区别和作用. 了解编程语言进行分类 了解Python解释器的种类 ...

  4. RabbitMQ高可用集群的搭建部署(Centos7)

    高可用集群架构 节点域名 操作系统 RabbitMQ版本 Erlang版本 iamdemo.tp-link.com Centos7.9 3.8.28 23.3-2 iamdemo2.tp-link.c ...

  5. 关于mac电脑突然搜不到家里wifi但手机却能连上的问题解决

    今天用mac电脑时,突然遇到一个奇怪的问题,家里wifi用的好好的,突然就连不上了,在看电脑能搜索到的wifi,居然家里的wifi都没有搜索到,但自己的手机却是正常的,然后我再看看我另外一台windo ...

  6. [USACO2007NOVG] Telephone Wire G

    题目描述 Farmer John's cows are getting restless about their poor telephone service; they want FJ to rep ...

  7. Hystrix:Spring Cloud服务熔断与降级组件

    Hystrix:Spring Cloud服务熔断与降级组件 问题总结 熔断器? Spring Cloud Hystrix? Hystrix服务降级? 全局降级方法? 解耦降级逻辑? Hystrix服务 ...

  8. Java的特性、内容和环境的配置

    Java的特性和优势 简单性 面向对象 可移植性 高性能 分布式 动态性 多线程 安全性 健壮性 JDK包含JRE包含JVM JDK:Java Development Kit JRE:Java Run ...

  9. 看完这篇,DWS故障修复不再愁

    摘要:本文详细梳理分析了DWS服务面临软硬件故障场景和对应的修复原理,希望借此能够让你对DWS的集群故障修复有个全面深入的了解. 本文分享自华为云社区<GaussDB(DWS)故障修复系统性介绍 ...

  10. 基于ModelArts进行流感患者密接排查

    摘要:针对疫情期间存在的排查实时性差.排查效率低.无法追踪密接者等问题,可以使用基于YOLOv4的行人检测.行人距离估计.多目标跟踪的方案进行解决. 本文分享自华为云社区<基于ModelArts ...