• 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↩

  • 相关阅读:
    初入编程之门的个人建议1.0
    分享职业技术培训类型
    详细介绍如何使用 NeRF 进行 3D 体积渲染-附源码下载
    C++内存管理:其七、标准库中的allocator
    React Native for Arcgis 地图开发 GraphicCtrl (十三)
    Unity中实现溶解(Dissolve)特效及其原理解析
    Mac配置iTerm样式终端
    Spring Boot 中 Nacos 配置中心使用实战
    《asp.net core 3 高级编程(第8版)》学习笔记 02
    DNA-CuInSeQDs近红外CuInSe量子点包裹脱氧核糖核酸DNA
  • 原文地址:https://www.cnblogs.com/newbe36524/p/0x023-aspnetcore-natively-implements-key-based-service-resolving.html