Beispiel #1
0
        /// <summary>
        /// Gets all static rules defined on the specified types.
        /// </summary>
        /// <param name="types"></param>
        /// <returns></returns>
        public static IEnumerable <Rule> GetRules(IEnumerable <Type> types)
        {
            // Fetch the set of rules declared on the specified types
            List <Rule> rules = new List <Rule>();

            foreach (Type type in types
                     .Where(type => type.IsClass)
                     .SelectMany(type => type.BaseType.IsGenericType ? new Type[] { type, type.BaseType } : new Type[] { type }))
            {
                rules.AddRange(
                    type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
                    .Where(field => typeof(IRuleProvider).IsAssignableFrom(field.FieldType))
                    .SelectMany(field =>
                {
                    IRuleProvider ruleProvider = (IRuleProvider)field.GetValue(null);

                    if (ruleProvider != null)
                    {
                        return(ruleProvider.GetRules(type, field.Name));
                    }
                    else
                    {
                        StackTrace stackTrace = new StackTrace();
                        List <MethodBase> callStackMethods = stackTrace.GetFrames()
                                                             .Select(f => f.GetMethod())
                                                             .ToList();

                        Type currentType = callStackMethods.First().DeclaringType;

                        callStackMethods.Reverse();
                        MethodBase ruleProviderCall = callStackMethods.FirstOrDefault(method => currentType != method.DeclaringType && typeof(IRuleProvider).IsAssignableFrom(method.DeclaringType));

                        if (ruleProviderCall != null)
                        {
                            string errorMessage = string.Format(
                                "'{0}'.'{1}' is null, declared as a '{2}', and '{3}'.'{4}' is creating/accessing rules. As such, it appears that the '{2}' is still initializing and rules will not register properly. Please see the call stack.",
                                type.Name, field.Name, typeof(IRuleProvider).Name, ruleProviderCall.DeclaringType.Name, ruleProviderCall.Name
                                );
                            throw new ApplicationException(errorMessage);
                        }
                    }

                    return(new Rule[] { });
                })
                    .Where(rule => rule != null)
                    );

                // Ensure the error code has been set on all statically declared condition types
                foreach (ConditionType error in
                         type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
                         .Where(field => typeof(ConditionType).IsAssignableFrom(field.FieldType))
                         .Select(field =>
                {
                    ConditionType error = (ConditionType)field.GetValue(null);
                    if (error != null && error.Code == null)
                    {
                        error.Code = field.DeclaringType.Name + "." + field.Name;
                    }
                    return(error);
                }))
                {
                }
            }
            return(rules);
        }
Beispiel #2
0
 /// <summary>
 /// Creates a new <see cref="Condition"/> based on the specified <see cref="ConditionType"/>
 /// and error message.
 /// </summary>
 /// <param name="error"></param>
 public Condition(ConditionType type, string message, object target, params string[] properties)
 {
     this.Type    = type;
     this.Message = message;
     this.AddTarget(target, properties);
 }
Beispiel #3
0
 internal void ClearCondition(ConditionType error)
 {
     conditions.Remove(error.Code);
 }
Beispiel #4
0
 /// <summary>
 /// Creates a new <see cref="Condition"/> based on the specified <see cref="ConditionType"/>.
 /// </summary>
 /// <param name="error"></param>
 public Condition(ConditionType type, object target, params string[] properties)
     : this(type, type.Message, target, properties)
 {
 }