private async Task <object> CreateInstanceAsync(Type interfaceType, ComponentDescriptor componentDescriptor, Action <string> progressCallback, ComponentDescriptor[] resolveStack) { ComponentDescriptor[] ResolveStack = this.CheckPreventRecursion(resolveStack, componentDescriptor); ComponentInstance ComponentInstance = this.instances[componentDescriptor]; Func <Func <Task <object> >, Task <object> > RunCreate = componentDescriptor.MustCreateOnUiThread ? this.Repository.RunOnUiThread : Task.Run; object Instance = await RunCreate(async() => await ComponentInstance.CreateInstanceAsync(interfaceType, this, progressCallback, ResolveStack)); return(Instance); }
private object CreateInstance(Type interfaceType, ComponentDescriptor componentDescriptor, Action <string> progressCallback, ComponentDescriptor[] resolveStack) { ComponentDescriptor[] ResolveStack = this.CheckPreventRecursion(resolveStack, componentDescriptor); ComponentInstance ComponentInstance = this.instances[componentDescriptor]; if (componentDescriptor.MustCreateOnUiThread && this.Repository.IsUiThread() == false) { throw new ArgumentException(@"Attempting to synchronously create a compontent instance that needs to be created on the UI thread from a non-ui thread.\nEither marshal the creation to the UI Thread, or use the async creation method that implicitly marshals if needed"); } object Instance = ComponentInstance.CreateInstance(interfaceType, this, progressCallback, ResolveStack); return(Instance); }
/// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> /// <filterpriority>2</filterpriority> public void Dispose() { this.CheckDisposed(); foreach (ComponentInstance ComponentInstance in this.ComponentInstances) { try { ComponentInstance.Dispose(this); } catch { //Ignore } } this.disposed = true; }
public ComponentInstance this[ComponentDescriptor componentDescriptor] { get { foreach (ComponentInstance ComponentInstance in this.innerList) { if (ComponentInstance.Descriptor == componentDescriptor) { return(ComponentInstance); } } ComponentInstance NewComponentInstance = componentDescriptor.CreateComponentInstance(); this.innerList.Add(NewComponentInstance); this.InvokeComponentInstanceAdded(NewComponentInstance); return(NewComponentInstance); } }
/// <summary> /// Creates the event args. /// </summary> /// <param name="componentInstance">componentDescriptor that is accessible via the /// <see cref="ComponentInstance"/> property</param> public ComponentInstanceEventArgs(ComponentInstance componentInstance) { this.ComponentInstance = componentInstance; }
private object Create(Action <string> progressCallback, ConstructorInfo optimalConstructor, object[] constructorParameters) { DateTime Start = DateTime.Now; Debug.WriteLine($"{new string(' ', ComponentInstance.debugIndent * 3)}Start instantiation of {this.Name}"); ComponentInstance.debugIndent++; try { DateTime ParameterResolved = DateTime.Now; progressCallback?.Invoke(this.Descriptor.Name); object Component = optimalConstructor.Invoke(constructorParameters); DateTime ComponentCreated = DateTime.Now; ComponentInstance.debugIndent--; Debug.WriteLine($"{new string(' ', ComponentInstance.debugIndent * 3)}Instantiation of {this.Name} took {ComponentInstance.Format(ComponentCreated - Start)} (params: {ComponentInstance.Format(ParameterResolved - Start)}, ctor: {ComponentInstance.Format(ComponentCreated - ParameterResolved)})"); return(Component); } catch (Exception Error) { ComponentInstance.debugIndent--; Debug.WriteLine($"{new string(' ', ComponentInstance.debugIndent * 3)}Instantiation of {this.Name} failed with message: {Error.Message.Replace("\n", $"\n{new string(' ', ComponentInstance.debugIndent * 3)}")}"); throw; } }
/// <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); }
private void InvokeComponentInstanceAdded(ComponentInstance componentInstance) { this.ComponentInstanceAdded(this, new ComponentInstanceEventArgs(componentInstance)); }