internal Array InternalResolveInstancesAsArray(Type interfaceType, Action <string> progressCallback, ComponentDescriptor[] resolveStack) { object[] Components = this.InternalResolveInstances(interfaceType, progressCallback, resolveStack).ToArray(); return(ComponentContainer.ToTypedArray(interfaceType, Components)); }
internal override async Task <object> CreateInstanceAsync(Type interfaceType, ComponentContainer componentContainer, Action <string> progressCallback, ComponentDescriptor[] resolveStack) { await this.instanceLock.WaitAsync(); try { return(this.instance ?? (this.instance = await this.DoCreateInstanceAsync(interfaceType, componentContainer, progressCallback, resolveStack))); } finally { this.instanceLock.Release(); } }
internal async Task <Array> InternalResolveInstancesAsArrayAsync(Type interfaceType, Action <string> progressCallback, ComponentDescriptor[] resolveStack) { object[] Components = (await this.InternalResolveInstancesAsync(interfaceType, progressCallback, resolveStack)).ToArray(); return(ComponentContainer.ToTypedArray(interfaceType, Components)); }
internal virtual void Dispose(ComponentContainer componentContainer) { this.CheckDisposed(); this.disposed = true; }
internal abstract object CreateInstance(Type interfaceType, ComponentContainer componentContainer, Action <string> progressCallback, ComponentDescriptor[] resolveStack);
/// <summary> /// /// </summary> private bool CanGetParametersFor(ConstructorInfo constructor, ComponentContainer componentContainer, out string diagnosisInformation) { foreach (ParameterInfo Parameter in constructor.GetParameters()) { Type ParameterType = Parameter.ParameterType; if (ComponentInstance.IsValidInterfaceReference(ParameterType)) { //Simple interface reference if (this.CheckInterfaceParameter(componentContainer, ParameterType, true, $"{ParameterType.Name} {Parameter.Name}", "a", out diagnosisInformation) == false) { return(false); } } else if (ComponentInstance.IsValidInterfaceTaskReference(ParameterType)) { //Task to Simple interface reference if (this.CheckInterfaceParameter(componentContainer, ParameterType.GenericTypeArguments[0], true, $"{ParameterType.Name} {Parameter.Name}", "a", out diagnosisInformation) == false) { return(false); } } else if (ComponentInstance.IsValidFuncToInterfaceReference(ParameterType)) { //Func<> Interface reference if (this.CheckInterfaceParameter(componentContainer, ParameterType.GenericTypeArguments[0], true, $"{ParameterType.Name} {Parameter.Name}", "Func<> returning a", out diagnosisInformation) == false) { return(false); } } else if (ComponentInstance.IsValidInterfaceArrayReference(ParameterType)) { //Array of interface if (this.CheckInterfaceParameter(componentContainer, ParameterType.GetElementType(), false, $"{ParameterType.Name} {Parameter.Name}", "an array of a", out diagnosisInformation) == false) { return(false); } } else if (ComponentInstance.IsValidInterfaceArrayTaskReference(ParameterType)) { //Task to Array of interface if (this.CheckInterfaceParameter(componentContainer, ParameterType.GenericTypeArguments[0].GetElementType(), false, $"{ParameterType.Name} {Parameter.Name}", "an array of a", out diagnosisInformation) == false) { return(false); } } else if (ComponentInstance.IsValidFuncToInterfaceArrayReference(ParameterType)) { //Func<> of Array of interface if (this.CheckInterfaceParameter(componentContainer, ParameterType.GenericTypeArguments[0].GetElementType(), false, $"{ParameterType.Name} {Parameter.Name}", "a Func<> returning an array of a", out diagnosisInformation) == false) { return(false); } } else if (ParameterType == typeof(ComponentRepository)) { //Parameter is OK } else if (ParameterType == typeof(ComponentContainer)) { //Parameter is OK } else if (this.Descriptor.ConfigType != null && ParameterType.IsAssignableFrom(this.Descriptor.ConfigType)) { //Parameter is OK } else { diagnosisInformation = $"parameter '{ParameterType.Name} {Parameter.Name}' type not supported. Except component interfaces, arrays of component interfaces, Func<> returning component interfaces or arrays of them or Tasks returning the above, only ComponentRepository, ComponentContainer and the 'Config' Type using in component registration (if given) can be used."; return(false); } } diagnosisInformation = "OK"; return(true); }
private IEnumerable <T> GetParametersFor <T>(ConstructorInfo constructor, ComponentContainer componentContainer, Action <string> progressCallback, ComponentDescriptor[] resolveStack, Func <object, T> wrapResult, Func <Type, string, T> createInstance, Func <Type, string, T> createInstances ) { async Task <object> CreateInstanceArrayAsync(Type parameterType) { Array Instances = await componentContainer.InternalResolveInstancesAsArrayAsync(parameterType, progressCallback, resolveStack); return(Instances); } List <T> Parameters = new List <T>(); foreach (ParameterInfo Parameter in constructor.GetParameters()) { Type ParameterType = Parameter.ParameterType; if (ComponentInstance.IsValidInterfaceReference(ParameterType)) { T Component = createInstance(ParameterType, Parameter.Name); Parameters.Add(Component); } else if (ComponentInstance.IsValidInterfaceTaskReference(ParameterType)) { object Component = ComponentInstance.DoDynamicCastAsync(ParameterType, componentContainer.InternalResolveInstanceAsync(ParameterType.GenericTypeArguments[0], true, null, new ComponentDescriptor[0])); Parameters.Add(wrapResult(Component)); } else if (ComponentInstance.IsValidFuncToInterfaceReference(ParameterType)) { LambdaExpression Lambda = Expression.Lambda( ParameterType, Expression.Convert( ((Expression <Func <object> >)(() => componentContainer.InternalResolveInstance(ParameterType.GenericTypeArguments[0], true, progressCallback, new ComponentDescriptor[0]))).Body, ParameterType.GenericTypeArguments[0])); Parameters.Add(wrapResult(Lambda.Compile())); } else if (ComponentInstance.IsValidInterfaceArrayReference(ParameterType)) { Parameters.Add(createInstances(ParameterType, Parameter.Name)); } else if (ComponentInstance.IsValidInterfaceArrayTaskReference(ParameterType)) { object Component = ComponentInstance.DoDynamicCastAsync(ParameterType, CreateInstanceArrayAsync(ParameterType.GenericTypeArguments[0].GetElementType())); Parameters.Add(wrapResult(Component)); } else if (ComponentInstance.IsValidFuncToInterfaceArrayReference(ParameterType)) { LambdaExpression Lambda = Expression.Lambda( ParameterType, Expression.Convert( ((Expression <Func <Array> >)(() => componentContainer.InternalResolveInstancesAsArray(ParameterType.GenericTypeArguments[0].GetElementType(), progressCallback, new ComponentDescriptor[0]))).Body, ParameterType.GenericTypeArguments[0])); Parameters.Add(wrapResult(Lambda.Compile())); } else if (ParameterType == typeof(ComponentRepository)) { Parameters.Add(wrapResult(this.Descriptor.PrivateRepository ?? this.Descriptor.Repository)); } else if (ParameterType == typeof(ComponentContainer)) { Parameters.Add(wrapResult(componentContainer)); } else if (ParameterType.IsAssignableFrom(this.Descriptor.ConfigType)) { Parameters.Add(wrapResult(this.Descriptor.Config)); } else { throw new InvalidOperationException("Internal error: tried to resolve constructor parameters even though the constructor wasn't adequate"); } } return(Parameters); }
/// <summary> /// Gets the parameter list to call the given constructor. If a parameter could not be /// resolved, null is returned /// </summary> private async Task <object[]> GetParametersForAsync(ConstructorInfo constructor, ComponentContainer componentContainer, Action <string> progressCallback, ComponentDescriptor[] resolveStack) { Task <Object> WrapResult(object value) { return(Task.FromResult(value)); } // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local async Task <object> CreateInstance(Type parameterType, string parameterName) { object Instance = await componentContainer.InternalResolveInstanceAsync(parameterType, true, progressCallback, resolveStack); Instance.DbC_AssureNotNull($"Could not resolve component '{this.Descriptor.Type.FullName}' even though resolver claimed that he can. Parameter '{parameterName}' (type providing '{parameterType.FullName}' implementation) could not be instanciated"); return(Instance); } async Task <object> CreateInstances(Type parameterType, string parameterName) { Array Instance = await componentContainer.InternalResolveInstancesAsArrayAsync(parameterType.GetElementType(), progressCallback, resolveStack); return(Instance); } return(await Task.WhenAll(this.GetParametersFor(constructor, componentContainer, progressCallback, resolveStack, WrapResult, CreateInstance, CreateInstances))); }