예제 #1
0
        private void AddContractInfo(Type componentContractType, ComponentContractInfo componentContractInfo)
        {
            List <ComponentContractInfo> contractList;

            if (_componentContracts.ContainsKey(componentContractType))
            {
                contractList = _componentContracts[componentContractType];
            }
            else
            {
                contractList = new List <ComponentContractInfo>();
                _componentContracts[componentContractType] = contractList;
            }

            contractList.Add(componentContractInfo);
        }
예제 #2
0
        /// <summary>
        /// Special method to register contract directly.
        /// Should be used only by KioskApplicationBase.
        /// </summary>
        internal void RegisterContractInternal <TComponentContract>(string componentRole, ComponentContractInfo componentContractInfo)
        {
            Assure.ArgumentNotNull(componentRole, nameof(componentRole));
            Assure.ArgumentNotNull(componentContractInfo, nameof(componentContractInfo));

            var contactType = typeof(TComponentContract);

            Assure.CheckFlowState(contactType.IsInterface, $"{contactType.FullName} is not interface.");

            _componentsByRole[componentRole] = componentContractInfo.Component;
            AddContractInfo(contactType, componentContractInfo);
        }
예제 #3
0
        private void RegisterComponentContracts(ComponentBase component, Type[] componentContracts)
        {
            if (componentContracts == null || componentContracts.Length == 0)
            {
                // component doesn't implement any contracts
                return;
            }

            var componentType = component.GetType();

            foreach (var componentContractType in componentContracts
                     // ignore contract duplicates
                     .Distinct())
            {
                if (!componentContractType.IsInterface ||
                    !typeof(IComponentContract).IsAssignableFrom(componentContractType))
                {
                    Log.Error(LogContextEnum.Configuration, $"Component contract '{componentContractType.FullName}' is not an interface or doesn't inherit {nameof(IComponentContract)}.");
                    continue;
                }

                if (!componentContractType.IsAssignableFrom(componentType))
                {
                    Log.Error(LogContextEnum.Configuration, $"Component '{componentType.FullName}' returned contract '{componentContractType.FullName}' that is not implemented by the component.");
                    continue;
                }

                var contractStatusProperty = componentContractType.GetProperty(ContractStatusPropertyName);
                if (contractStatusProperty == null ||
                    !contractStatusProperty.CanRead ||
                    contractStatusProperty.CanWrite ||
                    contractStatusProperty.PropertyType != typeof(BindableComponentStatus))
                {
                    Log.Error(LogContextEnum.Configuration, $"Component contract '{componentContractType.FullName}' doesn't declare readable-only {ContractStatusPropertyName} property of type {nameof(BindableComponentStatus)} (required by convention).");
                    continue;
                }

                var contractStatus = (BindableComponentStatus)contractStatusProperty.GetValue(component);
                // check if separate contract status
                if (contractStatus != component.Status)
                {
                    if (contractStatus == null)
                    {
                        Log.Error(LogContextEnum.Configuration, $"Component contract '{componentContractType.FullName}' status is null.");
                        continue;
                    }

                    // todo: add support for a separate contract statuses (see architecture docs)
                    // bind separate contract status to component status (status inheritance)
                    // implement appropriate monitoring representation
                }

                ComponentState contractState         = null;
                var            contractStateProperty = componentContractType.GetProperty(ContractStatePropertyName);
                if (contractStateProperty != null &&
                    contractStateProperty.CanRead)
                {
                    // no need to check on null - it's already checked
                    contractState = (ComponentState)contractStateProperty.GetValue(component);
                }

                var componentContractInfo = new ComponentContractInfo(component, contractStatus, contractState);

                AddContractInfo(componentContractType, componentContractInfo);
            }
        }