Asp.net 5的依賴注入注入系列可以參考鏈接: [Asp.net 5] DependencyInjection項(xiàng)目代碼分析-目錄
我們?cè)谥爸v微軟的實(shí)現(xiàn)時(shí),對(duì)于OpenIEnumerableService與ClosedIEnumerableService拋下沒(méi)講,現(xiàn)在我們就將該部分補(bǔ)充完整。
我們回憶ServicePRovider類的構(gòu)造函數(shù)(對(duì)外部使用的)中,注冊(cè)了IEnumerable<>、new OpenIEnumerableService(_table)的關(guān)系。
public ServiceProvider(IEnumerable<ServiceDescriptor> serviceDescriptors) { _root = this; _table = new ServiceTable(serviceDescriptors); _table.Add(typeof(IServiceProvider), new ServiceProviderService()); _table.Add(typeof(IServiceScopeFactory), new ServiceScopeService()); _table.Add(typeof(IEnumerable<>), new OpenIEnumerableService(_table)); }ServiceProvider構(gòu)造函數(shù)
因?yàn)镮Enumerable是泛型,所以我們可以推斷OpenIEnumerableService類應(yīng)該實(shí)現(xiàn)IGenericService接口。那么如果我們想查找IEnumerable<T>的實(shí)現(xiàn)類中間會(huì)有怎樣的過(guò)程呢?
OpenIEnumerableService與ClosedIEnumerableService
由于OpenIEnumerableService實(shí)現(xiàn)IGenericService接口,所以會(huì)返回IService類型的對(duì)象,該對(duì)象是ClosedIEnumerableService類型。ClosedIEnumerableService類型內(nèi)部實(shí)際上返回的是ServiceTable中_services所有T的注冊(cè)項(xiàng),之后以IEnumerable<T>類型返回。
internal class OpenIEnumerableService : IGenericService { private readonly ServiceTable _table; public OpenIEnumerableService(ServiceTable table) { _table = table; } public ServiceLifetime Lifetime { get { return ServiceLifetime.Transient; } } public IService GetService(Type closedServiceType) { var itemType = closedServiceType.GetTypeInfo().GenericTypeArguments[0]; ServiceEntry entry; return _table.TryGetEntry(itemType, out entry) ? new ClosedIEnumerableService(itemType, entry) : null; } }OpenIEnumerableService
internal class ClosedIEnumerableService : IService { private readonly Type _itemType; private readonly ServiceEntry _serviceEntry; public ClosedIEnumerableService(Type itemType, ServiceEntry entry) { _itemType = itemType; _serviceEntry = entry; } public IService Next { get; set; } public ServiceLifetime Lifetime { get { return ServiceLifetime.Transient; } } public IServiceCallSite CreateCallSite(ServiceProvider provider, ISet<Type> callSiteChain) { var list = new List<IServiceCallSite>(); for (var service = _serviceEntry.First; service != null; service = service.Next) { list.Add(provider.GetResolveCallSite(service, callSiteChain)); } return new CallSite(_itemType, list.ToArray()); } private class CallSite : IServiceCallSite { private readonly Type _itemType; private readonly IServiceCallSite[] _serviceCallSites; public CallSite(Type itemType, IServiceCallSite[] serviceCallSites) { _itemType = itemType; _serviceCallSites = serviceCallSites; } public object Invoke(ServiceProvider provider) { var array = Array.CreateInstance(_itemType, _serviceCallSites.Length); for (var index = 0; index != _serviceCallSites.Length; ++index) { array.SetValue(_serviceCallSites[index].Invoke(provider), index); } return array; } public Expression Build(Expression provider) { return Expression.NewArrayInit( _itemType, _serviceCallSites.Select(callSite => Expression.Convert( callSite.Build(provider), _itemType))); } } }ClosedIEnumerableService
[之前我們介紹ServiceEntry時(shí),明確指出是鏈表結(jié)構(gòu),而不是單獨(dú)存放一個(gè)值;其應(yīng)用在這進(jìn)行了淋漓盡致的表現(xiàn)]
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注