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


    你可能想通过一个字符串或者其他的类型来获取一个具体的服务实现,那么在 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();
    services.AddSingleton();
    services.AddSingleton(sp =>
    {
    return dataType =>
    {
    switch (dataType)
    {
    case "json":
    return sp.GetRequiredService();
    case "msgpack":
    return sp.GetRequiredService();
    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()
    .GetSection("SerializerMapping")
    .Getstring, 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();
    services.AddSingleton();
    services.AddSingleton(SerializerFactoryExtensions.CreateSerializerFactory);

    总结

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

    参考

    感谢阅读,如果觉得本文有用,不妨点击推荐👍或者在评论区留下 Mark,让更多的人可以看到。

    欢迎关注作者的微信公众号“newbe技术专栏”,获取更多技术内容。 关注微信公众号“newbe技术专栏”


    1. https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection-guidelines?WT.mc_id=DX-MVP-5003606

  • 相关阅读:
    XGBoost算法原理详解与参数详解
    关于Godot动态生成节点的细节
    java基于SpringBoot+Vue+nodejs的协同过滤算法商品推荐系统 element
    领域适应Domain Adaptation
    大数据(一)背景和概念
    Spark UI中Shuffle dataSize 和shuffle bytes written 指标区别
    Mybatis整合MP
    (论文阅读笔记)Network planning with deep reinforcement learning
    代码随想录算法训练营第23期day17| 110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和
    三模块七电平级联H桥整流器电压平衡控制策略Simulink仿真
  • 原文地址:https://www.cnblogs.com/newbe36524/p/0x023-aspnetcore-natively-implements-key-based-service-resolving.html