亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

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

[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));
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久的精品视频| 91久久夜色精品国产网站| 日韩av在线看| 尤物yw午夜国产精品视频| 亚洲女人天堂色在线7777| 欧美激情日韩图片| 亚洲欧美日韩国产成人| 国产精品久久久久久久久久久久| 大胆人体色综合| 日韩资源在线观看| 亚洲美女激情视频| 成人国产精品一区二区| 国产成人精品视频| 亚洲最大成人网色| 中文字幕久久久av一区| 日韩免费观看高清| 亚洲欧美国产精品va在线观看| 久久在线观看视频| 久久国产精品久久精品| 久久免费福利视频| 成人两性免费视频| 欧美日韩中文字幕在线| 国产精品久久久久久一区二区| 国产精品美女www爽爽爽视频| 日本成人精品在线| 色综合天天综合网国产成人网| 亚洲日本欧美日韩高观看| 国产精品偷伦视频免费观看国产| 欧美一区二区三区四区在线| 精品久久久久久亚洲国产300| 亚洲加勒比久久88色综合| 97人洗澡人人免费公开视频碰碰碰| 国产精品亚洲欧美导航| 久热精品视频在线观看一区| 国产精品久久久久久久电影| 欧美性xxxx| 欧美精品videosex牲欧美| 国产精品免费一区二区三区都可以| 午夜伦理精品一区| 欧美激情综合色综合啪啪五月| 欧美在线播放视频| 亚洲在线观看视频网站| 日韩中文字幕亚洲| 久久精品中文字幕| 欧美日韩美女在线| 久久99精品视频一区97| 日韩在线视频网站| 2019亚洲男人天堂| 久久人人爽人人爽人人片av高请| 国产成人精品视频| 亚洲欧洲国产伦综合| 国产999精品| 日韩欧美综合在线视频| 国产精品精品国产| 国产精品99蜜臀久久不卡二区| 欧美性videos高清精品| 国产精品久久久久久久久久久久久| 欧美大片在线免费观看| 裸体女人亚洲精品一区| 成人免费福利视频| 欧美激情高清视频| 成人写真福利网| 国产精品扒开腿做爽爽爽男男| 夜夜嗨av一区二区三区四区| 国产一区二区丝袜| 中文字幕亚洲欧美日韩在线不卡| 97国产成人精品视频| 亚洲精品在线91| 欧美午夜激情视频| 欧美成在线观看| 精品久久久国产| 日韩欧美精品网站| 欧美性xxxx极品高清hd直播| 日韩风俗一区 二区| 欧美激情精品久久久久久变态| 精品自拍视频在线观看| 亚洲a在线观看| 欧美激情精品久久久久| 日韩二区三区在线| 日韩美女写真福利在线观看| 在线观看欧美视频| 成人福利视频在线观看| 亚洲精品视频二区| 日韩在线视频观看| 亚洲免费小视频| www.久久久久| 欧美成年人视频| 成人欧美一区二区三区在线| 欧美人在线观看| 中文字幕日韩欧美在线| 久久精品亚洲一区| 性色av一区二区三区在线观看| 日韩三级影视基地| 777777777亚洲妇女| 欧美成人精品一区| 国产精品大陆在线观看| 久久精品亚洲精品| 一本色道久久88综合亚洲精品ⅰ| 欧美有码在线观看| 日韩中文视频免费在线观看| 欧美日韩精品在线| 夜夜嗨av一区二区三区免费区| 亚洲自拍偷拍网址| 精品成人69xx.xyz| 国产精品扒开腿做| 亚洲男人天堂2019| 91中文字幕一区| 亚洲色图17p| 91视频免费网站| 91在线无精精品一区二区| 九九热视频这里只有精品| 欧美丝袜第一区| 欧美成人精品在线播放| 欧美综合国产精品久久丁香| 69视频在线免费观看| 国产欧美精品一区二区三区-老狼| 欧美性猛交xxxx乱大交3| 欧美高清在线观看| 亚洲一区二区免费| 国产精品入口免费视频一| 性日韩欧美在线视频| 亚洲最大激情中文字幕| 日韩精品在线观看一区| 狠狠躁夜夜躁久久躁别揉| 国产精品99久久久久久久久久久久| 欧美性猛交xxxxx水多| 中文字幕日韩精品在线观看| 日韩黄色av网站| 国产91精品在线播放| 日韩精品中文在线观看| 最新中文字幕亚洲| 国产欧美精品一区二区| 高潮白浆女日韩av免费看| 国产欧美精品日韩精品| 精品一区二区三区四区| 精品调教chinesegay| 久久久久这里只有精品| 91在线无精精品一区二区| 国产高清视频一区三区| 亚洲高清福利视频| 亚洲欧美中文另类| 国产美女精品免费电影| 国产精品视频不卡| 国产91在线播放精品91| 欧美激情视频给我| 一本一道久久a久久精品逆3p| 九九热视频这里只有精品| 在线观看成人黄色| 欧美性受xxx| 96sao精品视频在线观看| www.亚洲人.com| 国产精品视频免费观看www| 亚洲精品视频免费在线观看| 免费不卡在线观看av| 视频在线观看一区二区| 久久精视频免费在线久久完整在线看| 91牛牛免费视频| 欧美电影免费在线观看| 久久精品视频播放| 成人国产精品色哟哟| 亚洲成成品网站| 日韩欧美在线免费| 一区二区三区www| 国产精品女主播|