你可能想通过一个字符串或者其他的类型来获取一个具体的服务实现,那么在 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 中是原生支持的。

参考

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

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


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

最新文章

  1. 【swift】BlockOperation和GCD实用代码块
  2. Lrc2Srt字幕转换精灵
  3. JAVA IO 序列化与设计模式
  4. 文档生成工具 appledoc
  5. SGU 105 div.3 找规律
  6. 彻底理解android中的内部存储与外部存储
  7. cocos2d-x笔记5: 通过jni实现C++调用Java
  8. GIT学习(一)--&gt;Git产生的历史原因
  9. HttpClient and FileUpload
  10. ubuntu dash
  11. 【iOS基础】iOS 线程相关技术
  12. spark原理介绍
  13. WCF契约之---服务契约 、数据契约、 消息契约
  14. 【转】Ecshop 后台增加一个左侧列表菜单menu菜单的方法
  15. -Swift.h not find
  16. ionic3-ng4学习见闻--(多语言方案)
  17. 第十三节 Ajax基础
  18. 看到一个想收藏的的AJAX小列子
  19. Unity IOC容器的构造函数使用笔记(不能错过的Unity示例)
  20. .gitignore &amp; .DS_Store

热门文章

  1. Vue 路由跳转显示空白页面的问题
  2. HCIE Routing&amp;Switching之MPLS静态LSP配置
  3. JavaScript入门①-基础知识筑基
  4. 数电第四周周结_by_yc
  5. 【Java】FileUtils-获取路径的所有文件(或文件夹)
  6. node版本管理工具fnm踩坑
  7. 监控Kubernetes集群证书过期时间的三种方案
  8. 什么是django中间件?(七个中间件-自定义中间件)
  9. buuctf_Dest0g3_crypto
  10. 结合商业项目深入理解Go知识点