.net core DI注入

第三方日志

最初使用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()里注册的是泛型。

CORE DI

服务注册

  • ServiceCollection  
  • ServiceProvider    

1.Add

先看IserviceCollection定义:

public interface IServiceCollection : IList<ServiceDescriptor>{}

真正注册时使用的是

ServiceCollection().AddSingleton<>().AddTransient<>().AddScoped<>()

服务添加时,构建ServiceDescriptor(serviceType, implementationType, lifetime), IServiceCollection.add( ServiceDescriptor);

2.Builder

      我们将相应的服务注册到ServiceCollection对象之上,然后BuildServiceProvider 创建的ServiceProvider 。

服务构建:ServiceProvider  内部会构建相应的 ServiceProviderEngine 它内部会创建运行时解析器,比如:RuntimeServiceProviderEngine

复制代码
    internal class RuntimeServiceProviderEngine : ServiceProviderEngine
    {
        public RuntimeServiceProviderEngine(IEnumerable<ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback) : base(serviceDescriptors, callback)
        {
        }

        protected override Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite)
        {
            return scope =>
            {
                Func<ServiceProviderEngineScope, object> realizedService = p => RuntimeResolver.Resolve(callSite, p);

                RealizedServices[callSite.ServiceType] = realizedService;
                return realizedService(scope);
            };
        }
    }
复制代码
复制代码
internal abstract class ServiceProviderEngine : IServiceProviderEngine, IServiceScopeFactory
    {
        private readonly IServiceProviderEngineCallback _callback;

        private readonly Func<Type, Func<ServiceProviderEngineScope, object>> _createServiceAccessor;

        private bool _disposed;

        protected ServiceProviderEngine(IEnumerable<ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback)
        {
            _createServiceAccessor = CreateServiceAccessor;
            _callback = callback;
            Root = new ServiceProviderEngineScope(this);
            RuntimeResolver = new CallSiteRuntimeResolver();
            CallSiteFactory = new CallSiteFactory(serviceDescriptors);
            CallSiteFactory.Add(typeof(IServiceProvider), new ServiceProviderCallSite());
            CallSiteFactory.Add(typeof(IServiceScopeFactory), new ServiceScopeFactoryCallSite());
            RealizedServices = new ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>>();
        }

        internal ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>> RealizedServices { get; }

        internal CallSiteFactory CallSiteFactory { get; }

        protected CallSiteRuntimeResolver RuntimeResolver { get; }

        public ServiceProviderEngineScope Root { get; }

        public IServiceScope RootScope => Root;

        public void ValidateService(ServiceDescriptor descriptor)
        {
            if (descriptor.ServiceType.IsGenericType && !descriptor.ServiceType.IsConstructedGenericType)
            {
                return;
            }

            try
            {
                var callSite = CallSiteFactory.GetCallSite(descriptor, new CallSiteChain());
                if (callSite != null)
                {
                    _callback?.OnCreate(callSite);
                }
            }
            catch (Exception e)
            {
                throw new InvalidOperationException($"Error while validating the service descriptor '{descriptor}': {e.Message}", e);
            }
        }

        public object GetService(Type serviceType) => GetService(serviceType, Root);

        protected abstract Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite);
复制代码

下面是一个ServiceProvider的简单对象图

 

 

Service  GetService  Resolve

    ServiceProvider 服务提取的主要对象,ServiceProviderEngineScope 

  • CallSiteVisitor
  • ServiceCallSite                     
  • CallSiteChain

 

 

作者:RunStone

出处:https://www.cnblogs.com/RunStone/p/11904636.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   奔跑石头  阅读(824)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
more_horiz
keyboard_arrow_up light_mode palette
选择主题
点击右上角即可分享
微信分享提示