Esempio n. 1
0
 /// <summary>Creates info by supplying all the properties and chaining it with current (parent) info.</summary>
 /// <param name="serviceType"></param> <param name="requiredServiceType"></param>
 /// <param name="serviceKey"></param> <param name="ifUnresolved"></param>
 ///  <param name="factoryID"></param><param name="factoryType"></param>
 /// <param name="implementationType"></param> <param name="reuseLifespan"></param>
 /// <returns>Created info chain to current (parent) info.</returns>
 public RequestInfo Push(
     Type serviceType, Type requiredServiceType, object serviceKey, IfUnresolved ifUnresolved,
     int factoryID, FactoryType factoryType, Type implementationType, int reuseLifespan)
 {
     return(new RequestInfo(serviceType, requiredServiceType, serviceKey, ifUnresolved,
                            factoryID, factoryType, implementationType, reuseLifespan, this));
 }
Esempio n. 2
0
        /// <summary>
        /// Resolve service with type and key<br/>
        /// Throw exception or return default value if not found, dependent on ifUnresolved<br/>
        /// 根据服务类型和服务键获取实例<br/>
        /// 找不到时根据ifUnresolved参数抛出例外或者返回默认值<br/>
        /// </summary>
        public object Resolve(
            Type serviceType, IfUnresolved ifUnresolved = IfUnresolved.Throw, object serviceKey = null)
        {
            var  key            = Pair.Create(serviceType, serviceKey);
            long factoriesCount = 0;
            // Get factories
            // Success unless there zero or more than one factories
            ConcurrentQueue <ContainerFactoryData> factories;

            if (Factories.TryGetValue(key, out factories))
            {
                // Use normal factory
                factoriesCount = factories.Count;
                if (factoriesCount == 1 && factories.TryPeek(out var factoryData))
                {
                    return(factoryData.GetInstance(this, serviceType));
                }
            }
            else if (serviceType.IsGenericType)
            {
                // Use factory from generic definition
                var baseKey = Pair.Create(serviceType.GetGenericTypeDefinition(), serviceKey);
                if (Factories.TryGetValue(baseKey, out factories))
                {
                    factoriesCount = factories.Count;
                    if (factoriesCount == 1 && factories.TryPeek(out var factoryData))
                    {
                        return(factoryData.GetInstance(this, serviceType));
                    }
                }
            }
            if (ifUnresolved == IfUnresolved.Throw)
            {
                // Error, throw exception
                var messageFormat = (factoriesCount <= 0) ?
                                    "no factory registered to type {0} and service key {1}" :
                                    "more than one factory registered to type {0} and service key {1}";
                throw new KeyNotFoundException(string.Format(messageFormat, serviceType, serviceKey));
            }
            else if (ifUnresolved == IfUnresolved.ReturnDefault)
            {
                // Error, return default value
                return(null);
            }
            else
            {
                throw new NotSupportedException(string.Format(
                                                    "unsupported ifUnresolved type {0}", ifUnresolved));
            }
        }
Esempio n. 3
0
        private object GetService(Type serviceType, IfUnresolved ifUnresolved)
        {
            if (serviceType == typeof(IServiceProvider))
            {
                return(this);
            }

            if (serviceType == typeof(IServiceScopeFactory))
            {
                return(this);
            }

            Debug.WriteLine(serviceType.Name);

            return(_currentResolver.Container.Resolve(serviceType, ifUnresolved));
        }
Esempio n. 4
0
 /// <summary>
 /// Resolve service with type and key<br/>
 /// Throw exception or return default value if not found, dependent on ifUnresolved<br/>
 /// 根据服务类型和服务键获取实例<br/>
 /// 找不到时根据ifUnresolved参数抛出例外或者返回默认值<br/>
 /// </summary>
 public TService Resolve <TService>(IfUnresolved ifUnresolved, object serviceKey)
 {
     if (serviceKey == null && ContainerFactoriesCache.Enabled)
     {
         // Use faster method
         var data = ContainerFactoriesCache <TService> .Data;
         if (data == null || !data.IsMatched(this))
         {
             data = UpdateFactoriesCache <TService>();
         }
         if (data.SingleFactory != null)
         {
             return((TService)data.SingleFactory());
         }
     }
     // Use default method
     return((TService)Resolve(typeof(TService), ifUnresolved, serviceKey));
 }
Esempio n. 5
0
        /// <summary>
        /// Resolve service with type and key
        /// Throw exception or return default value if not found, dependent on ifUnresolved
        /// </summary>
        public object Resolve(Type serviceType, IfUnresolved ifUnresolved, object serviceKey)
        {
            var           key            = Pair.Create(serviceType, serviceKey);
            Func <object> factory        = null;
            long          factoriesCount = 0;

            FactoriesLock.EnterReadLock();
            try {
                // Get factories
                // Only success if there single factory
                var factories = Factories.GetOrDefault(key);
                factoriesCount = factories?.Count ?? 0;
                if (factoriesCount == 1)
                {
                    factory = factories[0];
                }
            } finally {
                FactoriesLock.ExitReadLock();
            }
            if (factory != null)
            {
                // Success
                return(factory());
            }
            else if (ifUnresolved == IfUnresolved.Throw)
            {
                // Error, throw exception
                var messageFormat = (factoriesCount <= 0) ?
                                    "no factory registered to type {0} and service key {1}" :
                                    "more than one factory registered to type {0} and service key {1}";
                throw new KeyNotFoundException(string.Format(messageFormat, serviceType, serviceKey));
            }
            else if (ifUnresolved == IfUnresolved.ReturnDefault)
            {
                // Error, return default value
                return(serviceType.GetTypeInfo().IsValueType ?
                       Activator.CreateInstance(serviceType) : null);
            }
            else
            {
                throw new NotSupportedException(string.Format(
                                                    "unsupported ifUnresolved type {0}", ifUnresolved));
            }
        }
Esempio n. 6
0
        private RequestInfo(
            Type serviceType, Type requiredServiceType, object serviceKey, IfUnresolved ifUnresolved,
            int factoryID, FactoryType factoryType, Type implementationType, int reuseLifespan,
            RequestInfo parentOrWrapper)
        {
            ParentOrWrapper = parentOrWrapper;

            // Service info:
            ServiceType         = serviceType;
            RequiredServiceType = requiredServiceType;
            ServiceKey          = serviceKey;
            IfUnresolved        = ifUnresolved;

            // Implementation info:
            FactoryID          = factoryID;
            FactoryType        = factoryType;
            ImplementationType = implementationType;
            ReuseLifespan      = reuseLifespan;
        }
Esempio n. 7
0
        private Request(
            Type serviceType, Type requiredServiceType, object serviceKey, string metadataKey, object metadata, IfUnresolved ifUnresolved,
            int factoryID, FactoryType factoryType, Type implementationType, int reuseLifespan,
            Request directParent)
        {
            DirectParent = directParent;

            // Service info:
            ServiceType         = serviceType;
            RequiredServiceType = requiredServiceType;
            ServiceKey          = serviceKey;
            MetadataKey         = metadataKey;
            Metadata            = metadata;
            IfUnresolved        = ifUnresolved;

            // Implementation info:
            FactoryID          = factoryID;
            FactoryType        = factoryType;
            ImplementationType = implementationType;
            ReuseLifespan      = reuseLifespan;
        }
Esempio n. 8
0
 /// <summary>
 /// Resolve service with type and key
 /// Throw exception or return default value if not found, dependent on ifUnresolved
 /// </summary>
 public TService Resolve <TService>(IfUnresolved ifUnresolved, object serviceKey)
 {
     return((TService)Resolve(typeof(TService), ifUnresolved, serviceKey));
 }
Esempio n. 9
0
 /// <summary>
 /// Resolve service with type and key<br/>
 /// Throw exception or return default value if not found, dependent on ifUnresolved<br/>
 /// 根据服务类型和服务键获取实例<br/>
 /// 找不到时根据ifUnresolved参数抛出例外或者返回默认值<br/>
 /// </summary>
 public TService Resolve <TService>(
     IfUnresolved ifUnresolved = IfUnresolved.Throw, object serviceKey = null)
 {
     return((TService)(Resolve(typeof(TService), ifUnresolved, serviceKey) ?? default(TService)));
 }
Esempio n. 10
0
 public object Resolve(Type serviceType, object serviceKey, IfUnresolved ifUnresolved, Type requiredServiceType,
                       Request preResolveParent, object[] args)
 {
     throw new NotImplementedException();
 }
Esempio n. 11
0
 private CompiledFactory ResolveAndCacheFactory(Type serviceType, IfUnresolved ifUnresolved)
 {
     var request = Request.Create(serviceType);
     var factory = ((IRegistry)this).GetOrAddFactory(request, ifUnresolved);
     if (factory == null) return EmptyCompiledFactory;
     var compiledFactory = factory.GetExpression(request, this).ToFactoryExpression().CompileFactory();
     Interlocked.Exchange(ref _defaultResolutionCache,
         _defaultResolutionCache.AddOrUpdate(serviceType, compiledFactory));
     return compiledFactory;
 }
Esempio n. 12
0
        object IResolver.ResolveKeyed(Type serviceType, object serviceKey, IfUnresolved ifUnresolved)
        {
            var entry = _keyedResolutionCache.GetValueOrDefault(serviceType) ?? HashTree<object, CompiledFactory>.Empty;
            var compiledFactory = entry.GetValueOrDefault(serviceKey);
            if (compiledFactory == null)
            {
                var request = Request.Create(serviceType, serviceKey);
                var factory = ((IRegistry)this).GetOrAddFactory(request, ifUnresolved);
                if (factory == null) return null;
                compiledFactory = factory.GetExpression(request, this).ToFactoryExpression().CompileFactory();
                Interlocked.Exchange(ref _keyedResolutionCache,
                    _keyedResolutionCache.AddOrUpdate(serviceType, entry.AddOrUpdate(serviceKey, compiledFactory)));
            }

            return compiledFactory(_constants, resolutionScope: null);
        }
Esempio n. 13
0
 object IResolver.ResolveDefault(Type serviceType, IfUnresolved ifUnresolved)
 {
     var compiledFactory =
         _defaultResolutionCache.GetValueOrDefault(serviceType) ??
         ResolveAndCacheFactory(serviceType, ifUnresolved);
     return compiledFactory(_constants, resolutionScope: null);
 }
Esempio n. 14
0
        Factory IRegistry.GetOrAddFactory(Request request, IfUnresolved ifUnresolved)
        {
            Factory newFactory = null;
            lock (_syncRoot)
            {
                FactoriesEntry entry;
                Factory factory;
                if (_factories.TryGetValue(request.ServiceType, out entry) &&
                    entry.TryGet(out factory, request.ServiceType, request.ServiceKey, ResolutionRules.GetSingleRegisteredFactory))
                    return factory.GetFactoryPerRequestOrDefault(request, this) ?? factory;

                if (request.OpenGenericServiceType != null &&
                    _factories.TryGetValue(request.OpenGenericServiceType, out entry))
                {
                    Factory genericFactory;
                    if (entry.TryGet(out genericFactory, request.ServiceType, request.ServiceKey, ResolutionRules.GetSingleRegisteredFactory) ||
                        request.ServiceKey != null && // OR try find generic-wrapper by ignoring service key.
                        entry.TryGet(out genericFactory, request.ServiceType, null, ResolutionRules.GetSingleRegisteredFactory) &&
                        genericFactory.Setup.Type == FactoryType.GenericWrapper)
                    {
                        newFactory = genericFactory.GetFactoryPerRequestOrDefault(request, this);
                    }
                }
            }

            if (newFactory == null)
                newFactory = ResolutionRules.GetUnregisteredServiceFactoryOrDefault(request, this);

            if (newFactory == null)
                Throw.If(ifUnresolved == IfUnresolved.Throw, Error.UNABLE_TO_RESOLVE_SERVICE, request);
            else
                Register(newFactory, request.ServiceType, request.ServiceKey);

            return newFactory;
        }
 public static ParameterSelector Type(this ParameterSelector source, Type requiredServiceType = null, object serviceKey = null, IfUnresolved ifUnresolved = IfUnresolved.Throw, object defaultValue = null)
 {
     return(source.Details((r, p) => !requiredServiceType.IsAssignableTo(p.ParameterType) ? null
         : ServiceDetails.Of(requiredServiceType, serviceKey, ifUnresolved, defaultValue)));
 }
Esempio n. 16
0
 /// <summary>Creates info by supplying all the properties and chaining it with current (parent) info.</summary>
 public Request Push(
     Type serviceType, Type requiredServiceType, object serviceKey, string metadataKey, object metadata, IfUnresolved ifUnresolved,
     int factoryID, FactoryType factoryType, Type implementationType, int reuseLifespan) =>
 new Request(serviceType, requiredServiceType, serviceKey, metadataKey, metadata, ifUnresolved,
             factoryID, factoryType, implementationType, reuseLifespan, this);
Esempio n. 17
0
 public object Resolve(Type serviceType, IfUnresolved ifUnresolved)
 {
     return(_resolveItem);
 }