首页 > 编程语言 >aspnetcore 原生 DI 实现基于 key 的服务获取

aspnetcore 原生 DI 实现基于 key 的服务获取

时间:2023-02-22 08:22:44浏览次数:77  
标签:return DI dataType aspnetcore key services AddSingleton data public

你可能想通过一个字符串或者其他的类型来获取一个具体的服务实现,那么在 aspnetcore 原生的 MSDI 中,如何实现呢?本文将介绍如何通过自定义工厂来实现。

我们现在恰好有基于 Json 和 MessagePack 的两种序列化器

有一个接口是这样的

public interface ISerializer
{
    byte[] Serialize<T>(T obj);
    T Deserialize<T>(ReadOnlySpan<byte> data);
}

并且由两个不同的实现

// Json
public class MyJsonSerializer : ISerializer
{
    public byte[] Serialize<T>(T obj)
    {
        throw new NotImplementedException();
    }

    public T Deserialize<T>(ReadOnlySpan<byte> data)
    {
        throw new NotImplementedException();
    }
}

// MessagePack
public class MyMessagePackSerializer : ISerializer
{
    public byte[] Serialize<T>(T obj)
    {
        throw new NotImplementedException();
    }

    public T Deserialize<T>(ReadOnlySpan<byte> data)
    {
        throw new NotImplementedException();
    }
}

我有一个服务,需要使用这两种序列化器中的一种。

public class MyService
{
    public object DoSomething(string dataType, ReadOnlySpan<byte> data)
    {
        // 根据 dataType 来决定使用哪种序列化器
    }
}

使用委托来定义获取服务的方法

我们可以通过委托来定义获取服务的方法,如下

public delegate ISerializer SerializerFactory(string dataType);

然后在 ConfigureServices 方法中注册

services.AddSingleton<MyJsonSerializer>();
services.AddSingleton<MyMessagePackSerializer>();
services.AddSingleton<SerializerFactory>(sp =>
{
    return dataType =>
    {
        switch (dataType)
        {
            case "json":
                return sp.GetRequiredService<MyJsonSerializer>();
            case "msgpack":
                return sp.GetRequiredService<MyMessagePackSerializer>();
            default:
                throw new NotSupportedException();
        }
    };
});

这样我们就可以在 MyService 中通过委托来获取服务了

public class MyService
{
    private readonly SerializerFactory _serializerFactory;

    public MyService(SerializerFactory serializerFactory)
    {
        _serializerFactory = serializerFactory;
    }

    public object DoSomething(string dataType, ReadOnlySpan<byte> data)
    {
        var serializer = _serializerFactory(dataType);
        return serializer.Deserialize<object>(data);
    }
}

基于配置来改变工厂

因为本质是通过委托来获取服务,所以我们可以通过配置来改变委托的行为,如下

public static class SerializerFactoryExtensions
{
    public static SerializerFactory CreateSerializerFactory(this IServiceProvider sp)
    {
        // get mapping from configuration
        var mapping = sp.GetRequiredService<IConfiguration>()
                      .GetSection("SerializerMapping")
                      .Get<Dictionary<string, string>>();
        return dataType =>
        {
            var serializerType = mapping[dataType];
            return (ISerializer)sp.GetRequiredService(Type.GetType(serializerType));
        };
    }
}

然后在 appsettings.json 中配置

{
  "SerializerMapping": {
    "json": "WebApplication1.MyJsonSerializer",
    "msgpack": "WebApplication1.MyMessagePackSerializer"
  }
}

然后在 ConfigureServices 方法中注册

services.AddSingleton<MyJsonSerializer>();
services.AddSingleton<MyMessagePackSerializer>();
services.AddSingleton(SerializerFactoryExtensions.CreateSerializerFactory);

总结

本篇文章介绍了如何通过自定义工厂来实现基于 key 的服务获取,这种方式在 aspnetcore 原生的 DI 中是原生支持的。

参考

感谢阅读,如果觉得本文有用,不妨点击推荐

标签:return,DI,dataType,aspnetcore,key,services,AddSingleton,data,public
From: https://www.cnblogs.com/newbe36524/p/0x023-aspnetcore-natively-implements-key-based-servic

相关文章

  • 4、Redis底层原理(持久化+分布式锁)
    Redis底层原理持久化Redis虽然是个内存数据库,但是Redis支持RDB和AOF两种持久化机制,将数据写往磁盘,可以有效地避免因进程退出造成的数据丢失问题,当下次重启时利用之前持久......
  • Android studio开发工具下载
    参考:(2条消息)Android基础——2:开发环境搭建及开发工具_ThePromonkeyOf_HeLuo的博客-CSDN博客_thecollectionofandroidplatformapis,toolsand下载前提前安装好jdk......
  • Python报错: KeyError: 'HOME'——mac中的os.environ['HOME'],windows写法:os.environ['H
    windows写法——os.environ['HOMEPATH']对应的mac写法——os.environ['HOME']windows:os.environ['HOME']会报错—— KeyError:'HOME'  改成os.environ['HOMEPATH'......
  • uniapp解决未配置appkey成功运行并离线打包apk的详细图文
    官方文档https://nativesupport.dcloud.net.cn/AppDocs/usesdk/android.html一、将写好的uniapp右键→发行→原生app-本地打包→生成本地打包App资源(它会要求你登录账号)二......
  • Android开发环境的搭建-Android Studio
    开始android的学习,首先要搭建开发环境,并下载AndroidStudio。并且测试连接手机jdk的安装之前已经完成了,sdk的安装会在Androidstudio的安装之后自动完成,故不需要担心。找到......
  • 关于jellyfin浏览器能访问,而手机app和电脑Jellyfin Media Player无法访问的问题
    我的jellyfin布置在群晖6.2的docker中产生原因初步判断是域名ssl证书过期导致的在控制台-->联网找到启用HTTPS选项将它关闭在HTTPS设置中关闭强制HTTPS选项......
  • 部署堡垒机4——编译安装redis-6.0.9以上版本
    一、环境准备Redis官网:https://redis.io/历史版本:http://download.redis.io/releases/1、安装依赖yum-yinstallgccgcc-c++makecmakelrzsz复制2、解压re......
  • redis安装使用
    1、redis五大数据类型,开发必会的技能string字符串类型hash哈希类型,如同Python的dict(字典)Set无序集合Zset有序集合List双向列队,向右插入数据,向左,右提......
  • Redis一主多从哨兵模式
    首先配置一主多从示例如下:1、两台主机IP地址如下:主:192.168.3.81端口:6379从:192.168.3.82 端口:6379从:192.168.3.82 端口:6380  2、首先建立Redis数......
  • SONiC LAI OTN media management
    今天看了一下SONiCLAI代码仓库里面上载的代码,几个头文件,定义了一些类似SAI的数据结构。点开头文件看了看,里面的内容看起来就是一个线路系统的模型,但是这个模型和现有的模......