public ContextControllerKeyedFactoryForge( ContextControllerFactoryEnv ctx, ContextSpecKeyed detail) : base(ctx) { this.detail = detail; }
protected internal static Type[] ValidateContextDesc( string contextName, ContextSpecKeyed partitionSpec) { if (partitionSpec.Items.IsEmpty()) { throw new ExprValidationException("Empty list of partition items"); } // verify properties exist foreach (var item in partitionSpec.Items) { var type = item.FilterSpecCompiled.FilterForEventType; foreach (var property in item.PropertyNames) { var getter = type.GetGetter(property); if (getter == null) { throw new ExprValidationException( "For context '" + contextName + "' property name '" + property + "' not found on type " + type.Name); } } } // verify property number and types compatible var firstItem = partitionSpec.Items[0]; if (partitionSpec.Items.Count > 1) { // verify the same filter event type is only listed once for (var i = 0; i < partitionSpec.Items.Count; i++) { var compareTo = partitionSpec.Items[i].FilterSpecCompiled.FilterForEventType; for (var j = 0; j < partitionSpec.Items.Count; j++) { if (i == j) { continue; } EventType compareFrom = partitionSpec.Items[j].FilterSpecCompiled.FilterForEventType; if (compareFrom == compareTo) { throw new ExprValidationException( "For context '" + contextName + "' the event type '" + compareFrom.Name + "' is listed twice"); } if (EventTypeUtility.IsTypeOrSubTypeOf(compareFrom, compareTo) || EventTypeUtility.IsTypeOrSubTypeOf(compareTo, compareFrom)) { throw new ExprValidationException( "For context '" + contextName + "' the event type '" + compareFrom.Name + "' is listed twice: Event type '" + compareFrom.Name + "' is a subtype or supertype of event type '" + compareTo.Name + "'"); } } } // build property type information var names = new string[firstItem.PropertyNames.Count]; var types = new Type[firstItem.PropertyNames.Count]; var typesBoxed = new Type[firstItem.PropertyNames.Count]; for (var i = 0; i < firstItem.PropertyNames.Count; i++) { var property = firstItem.PropertyNames[i]; names[i] = property; types[i] = firstItem.FilterSpecCompiled.FilterForEventType.GetPropertyType(property); typesBoxed[i] = types[i].GetBoxedType(); } // compare property types and numbers for (var item = 1; item < partitionSpec.Items.Count; item++) { ContextSpecKeyedItem nextItem = partitionSpec.Items[item]; // compare number of properties if (nextItem.PropertyNames.Count != types.Length) { throw new ExprValidationException( "For context '" + contextName + "' expected the same number of property names for each event type, found " + types.Length + " properties for event type '" + firstItem.FilterSpecCompiled.FilterForEventType.Name + "' and " + nextItem.PropertyNames.Count + " properties for event type '" + nextItem.FilterSpecCompiled.FilterForEventType.Name + "'"); } // compare property types for (var i = 0; i < nextItem.PropertyNames.Count; i++) { var property = nextItem.PropertyNames[i]; var type = nextItem.FilterSpecCompiled.FilterForEventType.GetPropertyType(property) .GetBoxedType(); var typeBoxed = type.GetBoxedType(); var left = TypeHelper.IsSubclassOrImplementsInterface(typeBoxed, typesBoxed[i]); var right = TypeHelper.IsSubclassOrImplementsInterface(typesBoxed[i], typeBoxed); if (typeBoxed != typesBoxed[i] && !left && !right) { throw new ExprValidationException( "For context '" + contextName + "' for context '" + contextName + "' found mismatch of property types, property '" + names[i] + "' of type '" + types[i].CleanName() + "' compared to property '" + property + "' of type '" + typeBoxed.CleanName() + "'"); } } } } var propertyTypes = new Type[firstItem.PropertyNames.Count]; for (var i = 0; i < firstItem.PropertyNames.Count; i++) { var property = firstItem.PropertyNames[i]; propertyTypes[i] = firstItem.FilterSpecCompiled.FilterForEventType.GetPropertyType(property); } return propertyTypes; }