你可能想通过一个字符串或者其他的类型来获取一个具体的服务实现,那么在 aspnetcore 原生的 MSDI 中,如何实现呢?本文将介绍如何通过自定义工厂来实现。
我们现在恰好有基于 Json 和 MessagePack 的两种序列化器
有一个接口是这样的
public interface ISerializer
{
byte[] Serialize(T obj);
T Deserialize(ReadOnlySpan data);
}
并且由两个不同的实现
// Json
public class MyJsonSerializer : ISerializer
{
public byte[] Serialize(T obj)
{
throw new NotImplementedException();
}
public T Deserialize(ReadOnlySpan data)
{
throw new NotImplementedException();
}
}
// MessagePack
public class MyMessagePackSerializer : ISerializer
{
public byte[] Serialize(T obj)
{
throw new NotImplementedException();
}
public T Deserialize(ReadOnlySpan data)
{
throw new NotImplementedException();
}
}
我有一个服务,需要使用这两种序列化器中的一种。
public class MyService
{
public object DoSomething(string dataType, ReadOnlySpan 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 data)
{
var serializer = _serializerFactory(dataType);
return serializer.Deserialize
基于配置来改变工厂
因为本质是通过委托来获取服务,所以我们可以通过配置来改变委托的行为,如下
public static class SerializerFactoryExtensions
{
public static SerializerFactory CreateSerializerFactory(this IServiceProvider sp)
{
// get mapping from configuration
var mapping = sp.GetRequiredService()
.GetSection("SerializerMapping")
.Get>();
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 中是原生支持的。
参考
感谢您的阅读,如果您觉得本文有用,快点击下方点赞按钮,让更多的人看到本文。
欢迎关注作者的微信公众号“newbe技术专栏”,获取更多技术内容。
- 本文作者: newbe36524
- 本文链接: https://www.newbe.pro/Others/0x023-aspnetcore-natively-implements-key-based-service-resolving/
- 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!