首页 > 其他分享 >.Net 一套接口多实现

.Net 一套接口多实现

时间:2023-07-21 15:35:28浏览次数:40  
标签:__ 实现 接口 public private 一套 Net IMultiInterface

.Net 一套接口多实现

接口(interface)可理解为规范、标准、协议。接口是用来约束各方都在同一组规范下工作。

电脑外设USB接口,各个品牌商家生产的U盘、鼠标都能够被电脑主板识别并工作,这是因为个生产商都遵循实现了USB接口协议。

在编程中接口应用非常广泛,例如IDbConnection接口,这是一组数据库连接的接口,由各个数据库驱动实现,因此.Net可以操作多种数据库。

一套接口多实现的基本结构如下

image

实现思路是,通过在各实现类上使用Attribute进行标记,然后定义一个实例获取类,通过反射获取所有实现该接口并且标记了的实现类,并将各个实现类通过IOC注册,然后通过标记的类型获取对应的实现类。

接下来是demo演示

定义服务标记

    [AttributeUsageAttribute(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
    public class MultiServiceTypeAttribute : Attribute
    {
        public string ServiceType { get; private set; }
        public MultiServiceTypeAttribute(string serviceType)
        {
            ServiceType = serviceType;
        }
    }

定义接口IMultiInterface

    public interface IMultiInterface
    {
        void Do();
    }

定义实现类AMultiInterfaceImplA并标记

    [MultiServiceTypeAttribute("A")]
   public class MultiInterfaceImplA : IMultiInterface
    {
        public void Do()
        {
            Console.WriteLine("这是A实现的调用");
        }
    }

定义实现类BMultiInterfaceImplB并标记

    [MultiServiceTypeAttribute("B")]
    public class MultiInterfaceImplB : IMultiInterface
    {
        public void Do()
        {
            Console.WriteLine("这是B实现的调用");
        }
    }

将接口与实现添加到IOC容器,这里使用 Microsoft.Extensions.DependencyInjection.dllMicrosoft.Extensions.DependencyInjection.Abstractions.dll两个库来实现简易IOC容器

    public class ServiceLoader
    {
        private readonly ServiceCollection __ioc = new ServiceCollection();
        private ServiceProvider __iocServiceProvider;
        private static object _lock = new object();

        private static ServiceLoader _inst;

        public static ServiceLoader Inst
        {
            get
            {
                if (_inst == null)
                {
                    lock (_lock)
                    {
                        if (_inst == null)
                        {
                            _inst = new ServiceLoader();
                            _inst.Init();
                        }
                    }
                }
                return _inst;
            }
        }

        private void Init()
        {
            var tps = typeof(IMultiInterface).Assembly.GetTypes().Where(x =>
                  x.GetInterfaces().Any(_ => _.Name == nameof(IMultiInterface)));
            foreach (var item in tps)
            {
                if (item.IsClass)
                {
                    Inst.AddTransient(typeof(IMultiInterface), item);
                }
            }
            Interlocked.Exchange(ref __iocServiceProvider, Inst.__ioc.BuildServiceProvider());
        }

        private void AddTransient(Type iface, Type impl)
        {
            __ioc.AddTransient(iface, impl);
        }
    }

根据标记的类型获取对应的接口实现。在ServiceLoader中继续添加以下方法

        public IMultiInterface GetService(string serviceType)
        {
            var svcList = __iocServiceProvider.GetServices<IMultiInterface>();
            var svc = svcList.FirstOrDefault(x => x.GetType().GetCustomAttribute<MultiServiceTypeAttribute>()?.ServiceType == serviceType);
            if (svc == null)
            {
                //Console.WriteLine($@"未找到 {serviceType} 服务实现,使用默认实现");
                // 如果有默认实现类,这里可选择调用默认实现
                //svc = svcList.FirstOrDefault(x => x.GetType().GetCustomAttribute<MultiServiceTypeAttribute>()?.ServiceType == "__default__");
                throw new Exception($"未找到 {serviceType} 服务实现");
            }

            return svc;
        }

通过ServiceLoader.Inst.GetService("serviceType").Do();来获取对应的接口实例,入参就是各个实现类上标记的类型,并调用接口。

调用示例如下

image

至此实现了一接口多实现的雏形。

标签:__,实现,接口,public,private,一套,Net,IMultiInterface
From: https://www.cnblogs.com/ycit/p/17571500.html

相关文章

  • 从零开始针对 .NET 应用的 DevOps 运营实践 - enkins & SonarQube自动化
    从零开始针对.NET应用的DevOps运营实践-MSbuild&Java环境搭建 一、Overview#最近的一段时间,在公司里我都在进行基于Jenkins和SonarQube配合已有的Gitlab搭建部门的持续集成环境的工作,虽然之前有使用过GitHubActions和AzureDevOps,但是从头开始搭建这样的一......
  • 基准测试工具 --- BenchmarkDotNet
    介绍今天介绍一个非常强大的基于.Net的基准测试工具BenchmarkDotNet。BenchmarkDotNet已经被14300多个项目采用,包括非常多的知名开源项目,例如dotnet/performance(.Net所有运行时的基准测试项目)dotnet/runtime(.Net运行时库),Roslyn(c#和VisualBasic编译器),Mono、ASP.NET......
  • 接口默认方法,接口应用和适配器设计模式
    静态方法只能通过接口名调用!!! 私有方法主要用于提取两个不同方法的相同部分,两个不同方法分别调用私有方法,从而简化代码 ......
  • DataArts Studio实践丨通过Rest Client 接口读取RESTful接口数据的能力
    本文分享自华为云社区《DataArtsStudio通过RestClient接口读取RESTful接口数据的能力,通过Hive-SQL存储》,作者:张浩奇。RestClient提供了读取RESTful接口数据的能力。RestClient从RESTful地址中获取数据,转换为数据集成支持的数据类型,然后传递给下游的hive-sql节点存储。本文......
  • 以程序员为视角,关于商品详情API接口的说明
    ​商品详情API接口是现代电商平台中非常重要的一部分,它提供了获取淘宝商品详细信息的能力。作为一个程序员,了解如何调用这个API接口是非常关键的。首先,我们需要明确的是,API接口是应用程序与服务器之间进行通信和数据交换的一种方式。在调用商品详情API接口之前,我们需要先获得相......
  • 基准测试工具 --- BenchmarkDotNet
    介绍今天介绍一个非常强大的基于.Net的基准测试工具BenchmarkDotNet。BenchmarkDotNet已经被14300多个项目采用,包括非常多的知名开源项目,例如dotnet/performance(.Net所有运行时的基准测试项目)dotnet/runtime(.Net运行时库),Roslyn(c#和VisualBasic编译器),Mono、ASP.NET......
  • 个人微信API接口,WeChat机器人
    本篇文章主要讨论微信机器人的开发经验。微信机器人的功能需求很简单,业务代码贼好撸,但是如何和微信交互呢,如何取到微信数据调用相关聊天接口呢,具体分为以下几种技术类型:1.微信Web接口17年后微信都不支持了,不过还是有一些牛×的star都是过Wstar的项目,可惜荒废了。2.手机Xposed......
  • 高效 API 接口对接淘宝天猫 1688 拼多多京东商品详情数据(H5 端,PC 端)
    api接口详解大全?优秀的设计是产品变得卓越的原因设计API意味着提供有效的接口,可以帮助API使用者更好地了解、使用和集成,同时帮助人们有效地维护它每个产品都需要使用手册,API也不例外在API领域,可以将设计视为服务器和客户端之间的协议进行建模API协议可以帮助内部和外部......
  • pythonETL案例
    PythonETL案例的实现流程ETL(Extract,Transform,Load)是指从数据源抽取数据,对数据进行转换,然后将数据加载到目标数据库或数据仓库中的一种常见数据处理过程。在本篇文章中,我将教会你如何使用Python实现一个简单的ETL案例。一、整体流程下面是整个ETL案例的流程,我们将按照以下步......
  • 批量新增接口正确传参以及优化(含数组传参)
    需求页面: 接口文档说明: 单个新增计划传参: 批量新增计划传参:批量新增7月24日和8月1日的复制计划 接口优化:由于当前医生给指定的患者新增计划时,当前医生和患者都不会发生变化,批量新增时仅是新增多个计划时间,所以计划时间可以调整为数组进行传参接口文档优化: 单个计......