/// <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)); }
/// <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)); } }
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)); }
/// <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)); }
/// <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)); } }
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; }
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; }
/// <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)); }
/// <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))); }
public object Resolve(Type serviceType, object serviceKey, IfUnresolved ifUnresolved, Type requiredServiceType, Request preResolveParent, object[] args) { throw new NotImplementedException(); }
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; }
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); }
object IResolver.ResolveDefault(Type serviceType, IfUnresolved ifUnresolved) { var compiledFactory = _defaultResolutionCache.GetValueOrDefault(serviceType) ?? ResolveAndCacheFactory(serviceType, ifUnresolved); return compiledFactory(_constants, resolutionScope: null); }
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))); }
/// <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);
public object Resolve(Type serviceType, IfUnresolved ifUnresolved) { return(_resolveItem); }