.net core DI注入

痴心易碎 提交于 2019-12-05 04:03:07

最初使用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

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!