依赖项注入-记录c#.net核心库的最佳实践-同时隐藏子库依赖项?
我在C#.net核心库中有一个入口点类(MotionDetectionSerializer),它使用System.Text.JSON将JSON反序列化为一个不可变的POCO类(见下文) 在构造函数中,我构建依赖项,注册自定义转换器和相关记录器。这主要是为了向库用户隐藏System.Text.Json依赖项 然而,我不相信这种设计是一种好的实践,并且已经读到日志记录器的依赖注入更易于测试。我读过一篇建议不要使用iLogger工厂的文章 其他人是如何在入口点类和相关帮助程序中为其库提供记录器的,同时在构造函数中隐藏第三方库依赖项的依赖项注入-记录c#.net核心库的最佳实践-同时隐藏子库依赖项?,c#,.net-core,C#,.net Core,我在C#.net核心库中有一个入口点类(MotionDetectionSerializer),它使用System.Text.JSON将JSON反序列化为一个不可变的POCO类(见下文) 在构造函数中,我构建依赖项,注册自定义转换器和相关记录器。这主要是为了向库用户隐藏System.Text.Json依赖项 然而,我不相信这种设计是一种好的实践,并且已经读到日志记录器的依赖注入更易于测试。我读过一篇建议不要使用iLogger工厂的文章 其他人是如何在入口点类和相关帮助程序中为其库提供记录器的,同时
using System;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using WebApp.Data.Serializers.Converters;
using WebApp.Data.Serializers.Converters.Visitors;
namespace WebApp.Data.Serializers
{
/// <summary>
/// Class to deserialize json into a MotionDetection object
/// Deserialization is performed to class instance properties
/// using CamelCase property naming policy.
/// </summary>
public class MotionDetectionSerializer
{
private JsonSerializerOptions SerializationOptions { get; set; }
/// <summary>
/// Construct a serializer to deserialize json into a MotionDetection object's
/// corresponding CamelCase properties.
/// </summary>
public MotionDetectionSerializer()
{
var logger = default(ILogger<MotionDetectionConverter>);
var loggerInfo = default(ILogger<MotionInfoConverter>);
var loggerVisitor = default(ILogger<JsonVisitor>);
using (var logFactory = LoggerFactory.Create(builder => builder.AddConsole()))
{
logger = logFactory.CreateLogger<MotionDetectionConverter>();
loggerInfo = logFactory.CreateLogger<MotionInfoConverter>();
loggerVisitor = logFactory.CreateLogger<JsonVisitor>();
}
JsonVisitor visitor = new JsonVisitor(loggerVisitor);
SerializationOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
SerializationOptions.Converters.Add(new MotionDetectionConverter(visitor, logger));
SerializationOptions.Converters.Add(new MotionInfoConverter(visitor, loggerInfo));
}
/// <summary>
/// Reads a json stream and deserializes into a MotionDetection object.
/// The underlying stream is closed after the operation completes or an exception is thrown.
/// The stream is read until completion.
/// </summary>
public async Task<MotionDetection> FromJSONAsync(Stream stream)
{
if (stream is null)
{
throw new ArgumentNullException(@"Failed to deserialize from null stream");
}
MotionDetection obj = await JsonSerializer.DeserializeAsync<MotionDetection>(stream, SerializationOptions);
return obj;
}
/// <summary>
/// Reads a json stream and deserializes into a MotionDetection object.
/// The underlying stream is closed after the operation completes or an exception is thrown.
/// The stream is read until completion.
/// </summary>
public MotionDetection FromJSON(Stream stream)
{
if (stream is null)
{
throw new ArgumentNullException(@"Failed to deserialize from null stream");
}
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
return JsonSerializer.Deserialize<MotionDetection>(reader.ReadToEnd(), SerializationOptions);
}
}
}
使用系统;
使用System.IO;
使用系统文本;
使用System.Text.Json;
使用System.Threading.Tasks;
使用Microsoft.Extensions.Logging;
使用WebApp.Data.Serializers.Converters;
使用WebApp.Data.Serializers.Converters.Visitors;
命名空间WebApp.Data.Serializers
{
///
///类将json反序列化为MotionDetection对象
///对类实例属性执行反序列化
///使用CamelCase属性命名策略。
///
公共类MotionDetectionSerializer
{
私有JsonSerializerOptions序列化选项{get;set;}
///
///构造一个序列化程序,将json反序列化为MotionDetection对象的
///相应的CamelCase属性。
///
public MotionDetectionSerializer()
{
var记录器=默认值(ILogger);
var loggerInfo=默认值(ILogger);
var loggerVisitor=默认值(ILogger);
使用(var logFactory=LoggerFactory.Create(builder=>builder.AddConsole())
{
logger=logFactory.CreateLogger();
loggerInfo=logFactory.CreateLogger();
loggerVisitor=logFactory.CreateLogger();
}
JsonVisitor=新的JsonVisitor(loggerVisitor);
SerializationOptions=new JSONSerializationRoptions{PropertyNamingPolicy=JsonNamingPolicy.CamelCase};
添加(新的MotionDetectionConverter(访问者、记录器));
添加(新的MotionInfoConverter(访问者,loggerInfo));
}
///
///读取json流并反序列化为MotionDetection对象。
///操作完成或引发异常后,基础流将关闭。
///读取流直到完成。
///
来自JsonAsync(流)的公共异步任务
{
if(流为空)
{
抛出新ArgumentNullException(@“未能从空流反序列化”);
}
MotionDetection obj=await JsonSerializer.DeserializeAsync(流,序列化选项);
返回obj;
}
///
///读取json流并反序列化为MotionDetection对象。
///操作完成或引发异常后,基础流将关闭。
///读取流直到完成。
///
来自JSON(流)的公共运动检测
{
if(流为空)
{
抛出新ArgumentNullException(@“未能从空流反序列化”);
}
使用(StreamReader=newstreamreader(stream,Encoding.UTF8))
返回JsonSerializer.Deserialize(reader.ReadToEnd(),SerializationOptions);
}
}
}
出于好奇的问题:为什么要使用var logger=default(ILogger)代码>而不仅仅是ILogger logger=null
(或C#7+中的ILogger logger=default;
)@John当设计稳定时,没有任何理由可以改变。。。。