国产探花免费观看_亚洲丰满少妇自慰呻吟_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));
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 延安市| 郯城县| 历史| 钟山县| 蒙自县| 肇东市| 五常市| 道孚县| 铁岭县| 三江| 东港市| 中江县| 隆尧县| 齐齐哈尔市| 新疆| 林甸县| 临沂市| 湾仔区| 镇安县| 荥经县| 临颍县| 凤台县| 江都市| 宕昌县| 商水县| 嘉荫县| 宜黄县| 凤冈县| 新竹市| 沙河市| 绵阳市| 武鸣县| 平凉市| 张家口市| 惠安县| 淮滨县| 定西市| 丽水市| 广灵县| 石城县| 宾阳县|