最初使用serilog组件,做日志记录工具,有了以下插件代码:
public static class ServiceHostBuilderExtensions
{
public static IServiceCollection UseSeriLog(this IServiceCollection collection, Serilog.ILogger logger = null,
bool dispose = false,
LoggerProviderCollection providers = null)
{
if (providers != null)
{
collection.AddSingleton<ILoggerFactory>(services =>
{
var factory = new SerilogLoggerFactory(logger, dispose, providers);
foreach (var provider in services.GetServices<ILoggerProvider>())
factory.AddProvider(provider);
return factory;
});
}
else
{
collection.AddSingleton<ILoggerFactory>(services => new SerilogLoggerFactory(logger, dispose));
}
ConfigureServices(collection, logger);
return collection;
}
static void ConfigureServices(IServiceCollection collection, Serilog.ILogger logger)
{
if (collection == null) throw new ArgumentNullException(nameof(collection));
if (logger != null)
{
collection.AddSingleton(logger);
}
}
}
.net core 使用 webhost 或者通用主机ihost,在controller或者自定义host服务里,logger都正常的获取到了。
public class TimedHostedService : BackgroundService
{
private readonly ILogger _logger;
private Timer _timer;
public TimedHostedService(ILogger<TimedHostedService> logger)
{
this._logger = logger;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
_timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));
return Task.CompletedTask;
}
private void DoWork(object state)
{
_logger.LogInformation(string.Format("[{0:yyyy-MM-dd hh:mm:ss}] Timed Background Service is working.", DateTime.Now));
}
public override Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Timed Background Service is stopping.");
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public override void Dispose()
{
_timer?.Dispose();
base.Dispose();
}
}
控制台程序写下了如下测试代码:
static void Main(string[] args)
{
var builder = new ServiceCollection()
.AddTransient<IFoo, Foo>()
.AddTransient<IGux, Gux>()
.AddLogging()
.UseSeriLog()
.BuildServiceProvider();
var log= builder.GetService<Microsoft.Extensions.Logging.ILogger>(); var m = builder.GetServices<IBar>();
}
public interface IFoo { }
public interface IBar { }
public class Foo : IFoo { }
public class Bar: IBar
{
public Gux(IFoo foo, Microsoft.Extensions.Logging.ILogger<Gux> logger)
{
Console.WriteLine("Test ");
}
}
得到的log是空。这里的原因是AddLogging()里注册的是泛型。
DI的核心对象
- ServiceCollection 服务的注册
- ServiceProvider 服务提供
我们将相应的服务注册到ServiceCollection对象之上,然后BuildServiceProvider 创建的ServiceProvider 。
服务构建:ServiceProvider 内部会构建相应的 ServiceProviderEngine 它内部会创建运行时解析器,创建CallSiteFactory
这里通过Dictionary<Type, ServiceDescriptorCacheItem> _descriptorLookup = new Dictionary<Type, ServiceDescriptorCacheItem>() 维护servicetype 和描叙之间的关系。
获取服务对象
ServiceProvider 服务提取的主要对象,ServiceProviderEngineScope
- CallSiteVisitor
- ServiceCallSite

- CallSiteChain