private ServiceCallSite CreateCallSite(Type serviceType, CallSiteChain callSiteChain) { if (!_stackGuard.TryEnterOnCurrentStack()) { return(_stackGuard.RunOnEmptyStack((type, chain) => CreateCallSite(type, chain), serviceType, callSiteChain)); } ServiceCallSite callSite; try { //检查是否已被创建,如果已创建,则抛出异常 callSiteChain.CheckCircularDependency(serviceType); //获取指定服务的实例对象方式 // 1.首先创建普通类型的ServiceCallSite // 2.创建泛型类型的ServiceCallSite // 3.如果服务类型是集合.那么将获取当前类型所有实现对象 callSite = TryCreateExact(serviceType, callSiteChain) ?? TryCreateOpenGeneric(serviceType, callSiteChain) ?? TryCreateEnumerable(serviceType, callSiteChain); } finally { callSiteChain.Remove(serviceType); } _callSiteCache[serviceType] = callSite; return(callSite); }
internal IServiceCallSite CreateCallSite(Type serviceType, CallSiteChain callSiteChain) { lock (_callSiteCache) { if (_callSiteCache.TryGetValue(serviceType, out var cachedCallSite)) { return(cachedCallSite); } IServiceCallSite callSite; try { callSiteChain.CheckCircularDependency(serviceType); callSite = TryCreateExact(serviceType, callSiteChain) ?? TryCreateOpenGeneric(serviceType, callSiteChain) ?? TryCreateEnumerable(serviceType, callSiteChain); } finally { callSiteChain.Remove(serviceType); } _callSiteCache[serviceType] = callSite; return(callSite); } }
private ServiceCallSite CreateCallSite(Type serviceType, CallSiteChain callSiteChain) { if (!_stackGuard.TryEnterOnCurrentStack()) { return(_stackGuard.RunOnEmptyStack((type, chain) => CreateCallSite(type, chain), serviceType, callSiteChain)); } // We need to lock the resolution process for a single service type at a time: // Consider the following: // C -> D -> A // E -> D -> A // Resolving C and E in parallel means that they will be modifying the callsite cache concurrently // to add the entry for C and E, but the resolution of D and A is synchronized // to make sure C and E both reference the same instance of the callsite. // This is to make sure we can safely store singleton values on the callsites themselves var callsiteLock = _callSiteLocks.GetOrAdd(serviceType, static _ => new object()); lock (callsiteLock) { callSiteChain.CheckCircularDependency(serviceType); ServiceCallSite callSite = TryCreateExact(serviceType, callSiteChain) ?? TryCreateOpenGeneric(serviceType, callSiteChain) ?? TryCreateEnumerable(serviceType, callSiteChain); return(callSite); } }
private ServiceCallSite CreateCallSite(Type serviceType, CallSiteChain callSiteChain) { if (!_stackGuard.TryEnterOnCurrentStack()) { return(_stackGuard.RunOnEmptyStack((type, chain) => CreateCallSite(type, chain), serviceType, callSiteChain)); } ServiceCallSite callSite; try { callSiteChain.CheckCircularDependency(serviceType); callSite = TryCreateExact(serviceType, callSiteChain) ?? TryCreateOpenGeneric(serviceType, callSiteChain) ?? TryCreateEnumerable(serviceType, callSiteChain); } finally { callSiteChain.Remove(serviceType); } _callSiteCache[serviceType] = callSite; return(callSite); }