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);
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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);
        }