国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

[Asp.net 5] DependencyInjection項目代碼分析4-微軟的實現(4)

2019-11-17 02:07:10
字體:
來源:轉載
供稿:網友

[asp.net 5] DependencyInjection項目代碼分析4-微軟的實現(4)

這個系列已經寫了6篇,鏈接地址如下:

[Asp.net 5] DependencyInjection項目代碼分析

[Asp.net 5] DependencyInjection項目代碼分析2-Autofac

[Asp.net 5] DependencyInjection項目代碼分析3-Ninject

[Asp.net 5] DependencyInjection項目代碼分析4-微軟的實現(1)

[Asp.net 5] DependencyInjection項目代碼分析4-微軟的實現(2)

[Asp.net 5] DependencyInjection項目代碼分析4-微軟的實現(3)

如果想對本篇有個更好的了解,建議需要先看

“[Asp.net 5] DependencyInjection項目代碼分析”

“[Asp.net 5] DependencyInjection項目代碼分析4-微軟的實現(1)”

“[Asp.net 5] DependencyInjection項目代碼分析4-微軟的實現(2)”。

"[Asp.net 5] DependencyInjection項目代碼分析4-微軟的實現(3)"

繼續ServicePRovider類

在之前的講解中我們提到過Service類調用CreateCallSite方法時會遞歸調用,但是我們沒具體說明如何遞歸調的。實際上Service類,通過反射創建實例的時候,會實例化的參數對象,而實例話參數對象通過ServiceProvider類創建,而ServiceProvider類創建參數的實例,又需要通過Service類(如果是通過Type注冊的)創建。下面我們把Service的CreateInstanceCallSite方法以及ServiceProvider相關的方法列出來。

public IServiceCallSite CreateCallSite(ServiceProvider provider, ISet<Type> callSiteChain)        {            ConstructorInfo[] constructors = _descriptor.ImplementationType.GetTypeInfo()                .DeclaredConstructors                .Where(IsInjectable)                .ToArray();            // TODO: actual service-fulfillment constructor selection            if (constructors.Length == 1)            {                ParameterInfo[] parameters = constructors[0].GetParameters();                IServiceCallSite[] parameterCallSites = new IServiceCallSite[parameters.Length];                for (var index = 0; index != parameters.Length; ++index)                {                    parameterCallSites[index] = provider.GetServiceCallSite(parameters[index].ParameterType, callSiteChain);                                    if (parameterCallSites[index] == null && parameters[index].HasDefaultValue)                    {                        parameterCallSites[index] = new ConstantCallSite(parameters[index].DefaultValue);                    }                    if (parameterCallSites[index] == null)                    {                        throw new InvalidOperationException(Resources.FormatCannotResolveService(                                parameters[index].ParameterType,                                 _descriptor.ImplementationType));                    }                }                return new ConstructorCallSite(constructors[0], parameterCallSites);            }            return new CreateInstanceCallSite(_descriptor);        }
Service的CreateCallSite
internal IServiceCallSite GetServiceCallSite(Type serviceType, ISet<Type> callSiteChain)        {            try            {                if (callSiteChain.Contains(serviceType))                {                    throw new InvalidOperationException(Resources.FormatCircularDependencyException(serviceType));                }                callSiteChain.Add(serviceType);                ServiceEntry entry;                if (_table.TryGetEntry(serviceType, out entry))                {                    return GetResolveCallSite(entry.Last, callSiteChain);                }                object emptyIEnumerableOrNull = GetEmptyIEnumerableOrNull(serviceType);                if (emptyIEnumerableOrNull != null)                {                    return new EmptyIEnumerableCallSite(serviceType, emptyIEnumerableOrNull);                }                return null;            }            finally            {                callSiteChain.Remove(serviceType);            }        }        internal IServiceCallSite GetResolveCallSite(IService service, ISet<Type> callSiteChain)        {            IServiceCallSite serviceCallSite = service.CreateCallSite(this, callSiteChain);            if (service.Lifetime == ServiceLifetime.Transient)            {                return new TransientCallSite(serviceCallSite);            }            else if (service.Lifetime == ServiceLifetime.Scoped)            {                return new ScopedCallSite(service, serviceCallSite);            }            else            {                return new SingletonCallSite(service, serviceCallSite);            }        }
ServiceProvider

對于Service的CreateCallSite方法,之前我們已經介紹過,現在我們重點講下ServiceProvider的GetServiceCallSite方法。從上面代碼中我們發現參數中含有“ISet<Type> callSiteChain”,這個參數是防止發生A的構造函數有B類型參數,B的構織函數中有A類型參數,當A,B都是通過類型注入的,那么系統會陷入死循環。而callSiteChain得作用就是防止這樣的死循環發生,當創建A時,會在callSiteChain中查詢歷史中是否有A的創建過程,如果有則說明發生死循環了,直接拋出異常,結束;如果沒有將A加入到callSiteChain中,繼續創建其參數。GetResolveCallSite方法比較簡單,對于ServiceProvider已經能夠獲取的IServiceCallSite實例,進行包裝,已保證生成的實例能夠適應不同的Scoped(該處應該使用設計模式中的代理模式,不過我設計模式不過關,請幫忙確認)。

對于TransientCallSite、ScopedCallSite、SingletonCallSite以及EmptyIEnumerableCallSite代碼,如下所示:

 private class EmptyIEnumerableCallSite : IServiceCallSite        {            private readonly object _serviceInstance;            private readonly Type _serviceType;            public EmptyIEnumerableCallSite(Type serviceType, object serviceInstance)            {                _serviceType = serviceType;                _serviceInstance = serviceInstance;            }            public object Invoke(ServiceProvider provider)            {                return _serviceInstance;            }            public Expression Build(Expression provider)            {                return Expression.Constant(_serviceInstance, _serviceType);            }        }        private class TransientCallSite : IServiceCallSite        {            private readonly IServiceCallSite _service;            public TransientCallSite(IServiceCallSite service)            {                _service = service;            }            public object Invoke(ServiceProvider provider)            {                return provider.CaptureDisposable(_service.Invoke(provider));            }            public Expression Build(Expression provider)            {                return Expression.Call(                    provider,                    CaptureDisposableMethodInfo,                    _service.Build(provider));            }        }        private class ScopedCallSite : IServiceCallSite        {            private readonly IService _key;            private readonly IServiceCallSite _serviceCallSite;            public ScopedCallSite(IService key, IServiceCallSite serviceCallSite)            {                _key = key;                _serviceCallSite = serviceCallSite;            }            public virtual object Invoke(ServiceProvider provider)            {                object resolved;                lock (provider._sync)                {                    if (!provider._resolvedServices.TryGetValue(_key, out resolved))                    {                        resolved = provider.CaptureDisposable(_serviceCallSite.Invoke(provider));
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 白水县| 大兴区| 仁布县| 新竹市| 鹤岗市| 普宁市| 沙田区| 温宿县| 黄石市| 浪卡子县| 金湖县| 永安市| 绍兴县| 莱芜市| 屯昌县| 赤壁市| 顺昌县| 海丰县| 肇州县| 库车县| 太仆寺旗| 彰化市| 保康县| 务川| 保靖县| 安平县| 潍坊市| 蕲春县| 长沙县| 佛学| 鄂托克前旗| 庐江县| 项城市| 宜章县| 泸溪县| 昌黎县| 乐业县| 徐闻县| 博客| 武清区| 绥化市|