private static void CheckIsComponentInterface <TInterface>() where TInterface : class
 {
     if (!ComponentRepository.IsComponentInterface(typeof(TInterface)))
     {
         throw new ArgumentException($"Interface given is not a component interface: {typeof(TInterface).Name}");
     }
 }
 internal ComponentDescriptor(ComponentRepository componentRepository, Type type, object config, ComponentRepository privateRepository)
 {
     this.Repository           = componentRepository;
     this.Type                 = type;
     this.Name                 = ComponentDescriptor.GetComponentName(type);
     this.Config               = config;
     this.ConfigType           = config?.GetType();
     this.PrivateRepository    = privateRepository;
     this.MustCreateOnUiThread = ComponentDescriptor.GetComponentUiThreadAffinity(type, this.Repository);
 }
 internal IEnumerable <Type> GetProvidedInterfaces()
 {
     return((
                from InterfaceType in this.Type.GetInterfaces()
                where ComponentRepository.IsComponentInterface(InterfaceType)
                select InterfaceType
                ).Union(
                from Property in this.GetProvidedDelegatedProperties()
                select Property.PropertyType
                ));
 }
        private IEnumerable <PropertyInfo> GetProvidedDelegatedProperties()
        {
            return(from Property in this.Type.GetRuntimeProperties()
                   where ComponentBindingPropertyAttribute.IsSetFor(Property)
                   .DbC_Assure(_ => _ == false || Property.CanWrite == false || Property.SetMethod?.IsPublic == false, $"{Property.DeclaringType.Name}.{Property.Name}: ComponentBindingProperty on set attributes no longer supported. Use Constructor Parameter with Func<TInterface> instead for deferred component resolution") &&
                   Property.CanRead && Property.GetMethod?.IsPublic == true &&       //must have a public get method
                   Property.PropertyType.IsInterface() &&
                   ComponentRepository.IsComponentInterface(Property.PropertyType)

                   select Property);
        }
 internal IEnumerable <Type> GetRequiredInterfaces()
 {
     return((
                from Constructor in this.Type.GetConstructors()
                from ConstructorParameter in Constructor.GetParameters()
                let ParameterType = ConstructorParameter.ParameterType
                                    let InterfaceType = ParameterType.IsArray
             ? ParameterType.GetElementType() //interface array
             : ParameterType.IsConstructedGenericType && ParameterType.GetGenericTypeDefinition() == typeof(Func <>)
                 ? ParameterType.GenericTypeArguments[0].IsArray
                     ? ParameterType.GenericTypeArguments[0].GetElementType() //func interface array
                     : ParameterType.GenericTypeArguments[0]                  //func interface
                 : ParameterType                                              // interface
                                                        where ComponentRepository.IsComponentInterface(InterfaceType)
                                                        select InterfaceType
                ).Distinct());
 }
        private static bool GetComponentUiThreadAffinity(Type type, ComponentRepository repository)
        {
            ThreadAffinity ThreadAffinity = ComponentAttribute.FromType(type).ThreadAffinity;

            switch (ThreadAffinity)
            {
            case ThreadAffinity.Automatic:
                return(repository.MustRunOnUiThread(type));

            case ThreadAffinity.NeedsUiThread:
                return(true);

            case ThreadAffinity.SupportsBackground:
                return(false);

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
 private bool CheckInterfaceParameter(ComponentContainer componentContainer, Type parameterType, bool mustResolve, string parameterTypeAndName, string specialTypeName, out string diagnosisInformation)
 {
     if (ComponentRepository.IsComponentInterface(parameterType))
     {
         if (mustResolve == false || componentContainer.CanResolveComponent(parameterType))
         {
             //Parameter is OK
         }
         else
         {
             diagnosisInformation = $"parameter '{parameterTypeAndName}' cannot be resolved. Make sure there is a registered component providing this interface.";
             return(false);
         }
     }
     else
     {
         diagnosisInformation = $"parameter '{parameterTypeAndName}' is not {specialTypeName} component interface. Make sure that the interfaces to use are marked with the [ComponentInterface] attribute.";
         return(false);
     }
     diagnosisInformation = "OK";
     return(true);
 }
 /// <summary/>
 public ComponentContainer(ComponentRepository repository, params object[] externalInstances)
 {
     this.Repository        = repository;
     this.externalInstances = externalInstances;
 }
 internal SingletonComponentDescriptor(ComponentRepository componentRepository, Type type, object config, ComponentRepository privateRepository)
     : base(componentRepository, type, config, privateRepository)
 {
 }