Ejemplo n.º 1
0
        protected AbstractServiceJob(IDictionary stateMap) : this()
        {
            if (log.IsInfoEnabled)
            {
                log.Info(@"ServiceJob을 위한 StateMap 정보를 제공받았습니다!!!");
            }

            if (stateMap != null)
            {
                foreach (DictionaryEntry de in stateMap)
                {
                    StateMap.Add(de.Key, de.Value);
                }

                JobDataMap.SetJobData(stateMap);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Create a state machine of the given base type and will set it on the given context
        /// Will internally called by the <see cref="StateMachine"/> wrapper class
        /// </summary>
        internal static void Create <TStateBase>(IStateContext context, int?initialKey)
            where TStateBase : StateBase
        {
            var stateBaseType = typeof(TStateBase);

            // Check the base type
            if (!stateBaseType.IsAbstract)
            {
                throw new ArgumentException("The state base class must be abstract!");
            }

            // Load all fields
            // 1. Get all fields which are static constant with the attribute
            // 2. let attribute and create an anonymous array
            var definedStates = (from stateField in GetStateFields(stateBaseType)
                                 let att = stateField.GetCustomAttribute <StateDefinitionAttribute>()
                                           select new { Key = (int)stateField.GetValue(null), att.IsInitial, att.Type }).ToArray();

            if (definedStates.Length == 0)
            {
                throw new InvalidOperationException("There was no state constant defined in the given base type." +
                                                    $"There musst be at least one constant integer attributed with the {nameof(StateDefinitionAttribute)}.");
            }

            // If a initial key is set, we check if it exists
            if (initialKey.HasValue && definedStates.All(s => s.Key != initialKey.Value))
            {
                throw new InvalidOperationException($"There was no state defined with key: {initialKey}");
            }

            // Group by type to find multiple defined state types
            var duplicates = definedStates.GroupBy(state => state.Type).Where(g => g.Count() > 1).Select(g => g.Key).ToArray();

            if (duplicates.Any())
            {
                var typeNames = string.Join(", ", duplicates.Select(type => type.Name));
                throw new InvalidOperationException($"State types are only allowed once: {typeNames}");
            }

            var       stateMap     = new StateMap();
            StateBase initialState = null;

            foreach (var definedState in definedStates)
            {
                var instance = (StateBase)Activator.CreateInstance(definedState.Type, context, stateMap);
                instance.Key = definedState.Key;

                if (initialKey.HasValue && initialKey.Value == definedState.Key)
                {
                    initialState = instance;
                }
                else if (definedState.IsInitial && initialState == null)
                {
                    initialState = instance;
                }
                else if (definedState.IsInitial && initialState != null)
                {
                    throw new InvalidOperationException("At least one state must be flagged as '" +
                                                        $"{nameof(StateDefinitionAttribute.IsInitial)} = true'.");
                }

                stateMap.Add(definedState.Key, instance);
            }

            if (initialState == null)
            {
                throw new InvalidOperationException("There is no state flagged with " +
                                                    $"'{nameof(StateDefinitionAttribute.IsInitial)} = true'.");
            }

            context.SetState(initialState);
            initialState.OnEnter();
        }