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;
        }
Example #4
0
        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);
            }
        }
Example #5
0
 /// <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);
        }
Example #9
0
 private void InvokeComponentInstanceAdded(ComponentInstance componentInstance)
 {
     this.ComponentInstanceAdded(this, new ComponentInstanceEventArgs(componentInstance));
 }