private void ProcessAll() { var typesToProcess = context.ModelDef.Types .Where(t => !t.IsGenericTypeDefinition && !t.IsAutoGenericInstance); foreach (var type in typesToProcess) { var underlyingType = type.UnderlyingType; if (verbose) { BuildLog.Info(Strings.LogProcessingX, underlyingType.GetShortName()); } var request = new MappingRequest(underlyingType.Assembly, underlyingType.Namespace); MappingResult result; if (!mappingCache.TryGetValue(request, out result)) { result = Process(underlyingType); mappingCache.Add(request, result); } else { if (verbose) { BuildLog.Info(Strings.LogReusingCachedMappingInformationForX, underlyingType.GetShortName()); } } type.MappingDatabase = result.MappingDatabase; type.MappingSchema = result.MappingSchema; } }
private static void ApplyModelFixesForMySql(DomainModelDef model) { BuildLog.Info("Applying changes to Metadata-related types for MySQL"); // Fixing length of Assembly.Name field TypeDef type = model.Types.TryGetValue(typeof(Assembly)); FieldDef field; if (type != null && type.Fields.TryGetValue("Name", out field)) { field.Length = 255; } // Fixing length of Extension.Name field type = model.Types.TryGetValue(typeof(Extension)); if (type != null && type.Fields.TryGetValue("Name", out field)) { field.Length = 255; } // Removing index on Type.Name field type = model.Types.TryGetValue(typeof(Type)); if (type != null && type.Indexes.Count > 0) { var indexes = type.Indexes.Where(i => i.KeyFields.ContainsKey("Name")).ToList(); foreach (var index in indexes) { type.Indexes.Remove(index); } } }
private void BuildNestedFields(FieldInfo source, FieldInfo target, IEnumerable<FieldInfo> fields) { var buffer = fields.ToList(); foreach (var field in buffer) { var clone = field.Clone(); if (target.SkipVersion) clone.SkipVersion = true; clone.IsSystem = false; clone.IsLazyLoad = field.IsLazyLoad || target.IsLazyLoad; if (target.IsDeclared) { clone.Name = context.NameBuilder.BuildNestedFieldName(target, field); clone.OriginalName = field.OriginalName; // One-field reference if (target.IsEntity && buffer.Count == 1) { clone.MappingName = target.MappingName; clone.DefaultValue = target.DefaultValue; } else clone.MappingName = context.NameBuilder.BuildMappingName(target, field); } if (target.Fields.Contains(clone.Name)) continue; clone.Parent = target; target.ReflectedType.Fields.Add(clone); if (field.IsStructure || field.IsEntity) { BuildNestedFields(source, clone, field.Fields); foreach (FieldInfo clonedFields in clone.Fields) target.Fields.Add(clonedFields); } else { if (field.Column!=null) clone.Column = BuildInheritedColumn(clone, field.Column); } if (target.IsStructure && clone.IsEntity && !IsAuxiliaryType(clone.ReflectedType)) { var origin = context.Model.Associations .Find(context.Model.Types[field.ValueType], true) .FirstOrDefault(a => a.OwnerField.Equals(field)); if (origin!=null && !clone.IsInherited) { AssociationBuilder.BuildAssociation(context, origin, clone); context.DiscardedAssociations.Add(origin); } } if (!clone.IsStructure && !clone.IsEntitySet && !target.ReflectedType.IsInterface && 0!=(clone.Attributes & FieldAttributes.Indexed)) { var typeDef = context.ModelDef.Types[target.DeclaringType.UnderlyingType]; var attribute = new IndexAttribute(clone.Name); var index = context.ModelDefBuilder.DefineIndex(typeDef, attribute); if (typeDef.Indexes.Contains(index.Name)) throw new DomainBuilderException( string.Format(Strings.ExIndexWithNameXIsAlreadyRegistered, index.Name)); typeDef.Indexes.Add(index); BuildLog.Info(Strings.LogIndexX, index.Name); } } }
private void ProcessAll() { using (BuildLog.InfoRegion(Strings.LogProcessingFixupActions)) while (context.ModelInspectionResult.Actions.Count > 0) { var action = context.ModelInspectionResult.Actions.Dequeue(); BuildLog.Info(string.Format(Strings.LogExecutingActionX, action)); action.Run(this); } }
public TypeDef ProcessType(Type type) { var modelDef = context.ModelDef; var typeDef = modelDef.Types.TryGetValue(type); if (typeDef != null) { return(typeDef); } using (BuildLog.InfoRegion(Strings.LogDefiningX, type.GetFullName())) { typeDef = DefineType(type); if (modelDef.Types.Contains(typeDef.Name)) { throw new DomainBuilderException(string.Format(Strings.ExTypeWithNameXIsAlreadyDefined, typeDef.Name)); } HierarchyDef hierarchyDef = null; if (typeDef.IsEntity) { // HierarchyRootAttribute is required for hierarchy root var hra = type.GetAttribute <HierarchyRootAttribute>(AttributeSearchOptions.Default); if (hra != null) { hierarchyDef = DefineHierarchy(typeDef, hra); } } ProcessProperties(typeDef, hierarchyDef); if (typeDef.IsEntity || typeDef.IsInterface) { ProcessIndexes(typeDef); } if (hierarchyDef != null) { BuildLog.Info(Strings.LogHierarchyX, typeDef.Name); modelDef.Hierarchies.Add(hierarchyDef); } modelDef.Types.Add(typeDef); ProcessFullTextIndexes(typeDef); var validators = type.GetCustomAttributes(false).OfType <IObjectValidator>(); foreach (var validator in validators) { typeDef.Validators.Add(validator); } return(typeDef); } }
public void ProcessProperties(TypeDef typeDef, HierarchyDef hierarchyDef) { var properties = typeDef.UnderlyingType.GetProperties( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (var propertyInfo in properties) { // Domain builder stage-related filter if (!IsFieldAvailable(propertyInfo)) { continue; } // FieldAttribute presence is required var reversedFieldAttributes = GetReversedFieldAttributes <FieldAttribute>(propertyInfo); if (reversedFieldAttributes.Count == 0) { continue; } var field = DefineField(propertyInfo, reversedFieldAttributes); // Declared & inherited fields must be processed for hierarchy root if (hierarchyDef != null) { typeDef.Fields.Add(field); BuildLog.Info(Strings.LogFieldX, field.Name); var keyAttributes = propertyInfo.GetAttribute <KeyAttribute>(AttributeSearchOptions.InheritAll); if (keyAttributes != null) { attributeProcessor.Process(hierarchyDef, field, keyAttributes); } } // Only declared properties must be processed in other cases else if (propertyInfo.DeclaringType == propertyInfo.ReflectedType) { typeDef.Fields.Add(field); BuildLog.Info(Strings.LogFieldX, field.Name); } // Checking whether property type is registered in model var propertyType = field.UnderlyingProperty.PropertyType; if (propertyType.IsGenericParameter) { continue; } if (propertyType.IsSubclassOf(WellKnownOrmTypes.Persistent) && !context.ModelDef.Types.Contains(propertyType)) { types.Enqueue(propertyType); } } }
private MappingResult Process(Type type) { var rule = mappingRules.First(r => RuleMatch(r, type)); var resultDatabase = !string.IsNullOrEmpty(rule.Database) ? rule.Database : defaultDatabase; var resultSchema = !string.IsNullOrEmpty(rule.Schema) ? rule.Schema : defaultSchema; if (verbose) { BuildLog.Info(Strings.ApplyingRuleXToY, rule, type.GetShortName()); } return(new MappingResult(resultDatabase, resultSchema)); }
private void BuildInheritedField(TypeInfo type, FieldInfo inheritedField) { BuildLog.Info(Strings.LogBuildingInheritedFieldXY, type.Name, inheritedField.Name); var field = inheritedField.Clone(); type.Fields.Add(field); field.ReflectedType = type; field.DeclaringType = inheritedField.DeclaringType; field.IsInherited = true; BuildNestedFields(inheritedField, field, inheritedField.Fields); if (inheritedField.Column!=null) field.Column = BuildInheritedColumn(field, inheritedField.Column); }
public void BuildLogTest() { if (File.Exists(filePath)) { File.Delete(filePath); } BuildLog.Debug("Test message", null); BuildLog.Debug("Test message with parameter {0}", new object[] { 1 }); BuildLog.Debug(new Exception("Some exception"), "Test message with parameter {0}", new object[] { 1 }); BuildLog.Debug("Test message", new object[] { 1 }); BuildLog.Debug("Test message {0}", null); BuildLog.Debug(new Exception("Some exeption")); BuildLog.Debug(null, new object[] { 1 }); BuildLog.Info("Test message", null); BuildLog.Info("Test message with parameter {0}", new object[] { 1 }); BuildLog.Info(new Exception("Some exception"), "Test message with parameter {0}", new object[] { 1 }); BuildLog.Info("Test message", new object[] { 1 }); BuildLog.Info("Test message {0}", null); BuildLog.Info(new Exception("Some exeption")); BuildLog.Info(null, new object[] { 1 }); BuildLog.Warning("Test message", null); BuildLog.Warning("Test message with parameter {0}", new object[] { 1 }); BuildLog.Warning(new Exception("Some exception"), "Test message with parameter {0}", new object[] { 1 }); BuildLog.Warning("Test message", new object[] { 1 }); BuildLog.Warning("Test message {0}", null); BuildLog.Warning(new Exception("Some exeption")); BuildLog.Warning(null, new object[] { 1 }); BuildLog.Error("Test message", null); BuildLog.Error("Test message with parameter {0}", new object[] { 1 }); BuildLog.Error(new Exception("Some exception"), "Test message with parameter {0}", new object[] { 1 }); BuildLog.Error("Test message", new object[] { 1 }); BuildLog.Error("Test message {0}", null); BuildLog.Error(new Exception("Some exeption")); BuildLog.Error(null, new object[] { 1 }); BuildLog.FatalError("Test message", null); BuildLog.FatalError("Test message with parameter {0}", new object[] { 1 }); BuildLog.FatalError(new Exception("Some exception"), "Test message with parameter {0}", new object[] { 1 }); BuildLog.FatalError("Test message", new object[] { 1 }); BuildLog.FatalError("Test message {0}", null); BuildLog.FatalError(new Exception("Some exeption")); BuildLog.FatalError(null, new object[] { 1 }); Assert.IsTrue(File.Exists(filePath)); Assert.AreEqual(File.ReadAllLines(filePath).Count(), 35); }
private void ProcessIndexes(TypeDef typeDef) { // process indexes which defined directly for type var ownIndexesOfType = typeDef.Fields .Where(f => f.IsIndexed) .Select(f => new IndexAttribute(f.Name)) .Concat(typeDef.UnderlyingType.GetAttributes <IndexAttribute>(AttributeSearchOptions.InheritNone) ?? Enumerable.Empty <IndexAttribute>()); var ownIndexesCollection = new HashSet <IndexAttribute>(); foreach (var attribute in ownIndexesOfType) { var index = DefineIndex(typeDef, attribute); ownIndexesCollection.Add(attribute); if (typeDef.Indexes.Contains(index.Name)) { throw new DomainBuilderException( string.Format(Strings.ExIndexWithNameXIsAlreadyRegistered, index.Name)); } typeDef.Indexes.Add(index); BuildLog.Info(Strings.LogIndexX, index.Name); } //process indexes which inherited from base classes //GetAttribute<T>(AttributeSearchOptions.InheritFromAllBase) extension returns all attributes of T - own indexes of type and inherited. var allIndexes = typeDef.UnderlyingType .GetAttributes <IndexAttribute>(AttributeSearchOptions.InheritFromAllBase) ?? Enumerable.Empty <IndexAttribute>(); //We need only inherited attributes. We checks all IndexAttributes in allIndexes and skip indexes //which own of type. foreach (var attribute in allIndexes.Where(index => !ownIndexesCollection.Contains(index))) { var index = DefineIndex(typeDef, attribute); if (typeDef.Indexes.Contains(index.Name)) { throw new DomainBuilderException( string.Format(Strings.ExIndexWithNameXIsAlreadyRegistered, index.Name)); } index.IsInherited = true; typeDef.Indexes.Add(index); BuildLog.Info(Strings.LogIndexX, index.Name); } }
public static void Inspect(BuildingContext context, HierarchyDef hierarchyDef) { var root = hierarchyDef.Root; BuildLog.Info(Strings.LogInspectingHierarchyX, root.Name); context.Validator.ValidateHierarchy(hierarchyDef); // Skip open generic hierarchies if (root.IsGenericTypeDefinition) { return; } // Check the presence of TypeId field FieldDef typeIdField; if (!root.Fields.TryGetValue(WellKnown.TypeIdFieldName, out typeIdField)) { context.ModelInspectionResult.Actions.Enqueue(new AddTypeIdFieldAction(root)); } else { context.ModelInspectionResult.Actions.Enqueue(new MarkFieldAsSystemAction(root, typeIdField)); } // Should TypeId field be added to key fields? if (hierarchyDef.IncludeTypeId && hierarchyDef.KeyFields.Find(f => f.Name == WellKnown.TypeIdFieldName) == null) { context.ModelInspectionResult.Register(new AddTypeIdToKeyFieldsAction(hierarchyDef)); } context.ModelInspectionResult.Actions.Enqueue(new ReorderFieldsAction(hierarchyDef)); foreach (var keyField in hierarchyDef.KeyFields) { var field = root.Fields[keyField.Name]; InspectField(context, root, field, true); } context.ModelInspectionResult.Actions.Enqueue(new AddPrimaryIndexAction(root)); }
private FieldInfo BuildDeclaredField(TypeInfo type, FieldDef fieldDef) { BuildLog.Info(Strings.LogBuildingDeclaredFieldXY, type.Name, fieldDef.Name); var fieldInfo = new FieldInfo(type, fieldDef.Attributes) { UnderlyingProperty = fieldDef.UnderlyingProperty, Name = fieldDef.Name, OriginalName = fieldDef.Name, MappingName = fieldDef.MappingName, ValueType = fieldDef.ValueType, ItemType = fieldDef.ItemType, Length = fieldDef.Length, Scale = fieldDef.Scale, Precision = fieldDef.Precision, Validators = fieldDef.Validators, }; if (fieldInfo.IsStructure && DeclaresOnValidate(fieldInfo.ValueType)) { fieldInfo.Validators.Add(new StructureFieldValidator()); } if (fieldInfo.IsEntitySet && DeclaresOnValidate(fieldInfo.ValueType)) { fieldInfo.Validators.Add(new EntitySetFieldValidator()); } type.Fields.Add(fieldInfo); if (fieldInfo.IsEntitySet) { AssociationBuilder.BuildAssociation(context, fieldDef, fieldInfo); return(fieldInfo); } if (fieldInfo.IsEntity) { var fields = context.Model.Types[fieldInfo.ValueType].Fields.Where(f => f.IsPrimaryKey); // Adjusting default value if any if (fields.Count() == 1 && fieldDef.DefaultValue != null) { fieldInfo.DefaultValue = ValueTypeBuilder.AdjustValue(fieldInfo, fields.First().ValueType, fieldDef.DefaultValue); } BuildNestedFields(null, fieldInfo, fields); if (!IsAuxiliaryType(type)) { AssociationBuilder.BuildAssociation(context, fieldDef, fieldInfo); if (type.IsStructure) { fieldInfo.Associations.ForEach(a => context.DiscardedAssociations.Add(a)); } } // Adjusting type discriminator field for references if (fieldDef.IsTypeDiscriminator) { type.Hierarchy.TypeDiscriminatorMap.Field = fieldInfo.Fields.First(); } } if (fieldInfo.IsStructure) { BuildNestedFields(null, fieldInfo, context.Model.Types[fieldInfo.ValueType].Fields); var structureFullTextIndex = context.ModelDef.FullTextIndexes.TryGetValue(fieldInfo.ValueType); if (structureFullTextIndex != null) { var hierarchyTypeInfo = context.Model.Types[fieldInfo.DeclaringType.UnderlyingType]; var structureTypeInfo = context.Model.Types[fieldInfo.ValueType]; var currentIndex = context.ModelDef.FullTextIndexes.TryGetValue(hierarchyTypeInfo.UnderlyingType); if (currentIndex == null) { currentIndex = new FullTextIndexDef(context.ModelDef.Types.TryGetValue(type.UnderlyingType)); context.ModelDef.FullTextIndexes.Add(currentIndex); } currentIndex.Fields.AddRange(structureFullTextIndex.Fields .Select(f => new { fieldInfo.DeclaringType .StructureFieldMapping[new Pair <FieldInfo>(fieldInfo, structureTypeInfo.Fields[f.Name])].Name, f.IsAnalyzed, f.Configuration, f.TypeFieldName }) .Select(g => new FullTextFieldDef(g.Name, g.IsAnalyzed) { Configuration = g.Configuration, TypeFieldName = g.TypeFieldName })); } } if (fieldInfo.IsPrimitive) { fieldInfo.DefaultValue = fieldDef.DefaultValue; fieldInfo.DefaultSqlExpression = fieldDef.DefaultSqlExpression; fieldInfo.Column = BuildDeclaredColumn(fieldInfo); if (fieldDef.IsTypeDiscriminator) { type.Hierarchy.TypeDiscriminatorMap.Field = fieldInfo; } } return(fieldInfo); }
public static void Inspect(BuildingContext context, TypeDef typeDef) { BuildLog.Info(Strings.LogInspectingTypeX, typeDef.Name); if (typeDef.IsInterface) { // Remove open generic interface if (typeDef.IsGenericTypeDefinition) { context.ModelInspectionResult.Register(new RemoveTypeAction(typeDef)); return; } // Base interfaces foreach (var @interface in context.ModelDef.Types.FindInterfaces(typeDef.UnderlyingType)) { context.DependencyGraph.AddEdge(typeDef, @interface, EdgeKind.Inheritance, EdgeWeight.High); } // Fields foreach (var field in typeDef.Fields) { InspectField(context, typeDef, field, false); } return; } if (typeDef.IsStructure) { if (typeDef.UnderlyingType.IsGenericTypeDefinition) { context.ModelInspectionResult.Register(new RemoveTypeAction(typeDef)); return; } // Ancestor var parent = context.ModelDef.Types.FindAncestor(typeDef); if (parent != null) { context.DependencyGraph.AddEdge(typeDef, parent, EdgeKind.Inheritance, EdgeWeight.High); } // Fields foreach (var field in typeDef.Fields) { InspectField(context, typeDef, field, false); } return; } if (typeDef.IsEntity) { // Should we remove it or not? var hierarchyDef = context.ModelDef.FindHierarchy(typeDef); if (hierarchyDef == null) { context.ModelInspectionResult.Register(new RemoveTypeAction(typeDef)); return; } // Register closed generic types if (typeDef.IsGenericTypeDefinition) { var allGenericConstraintsAreEntity = typeDef.UnderlyingType.GetGenericArguments() .SelectMany(ga => ga.GetGenericParameterConstraints()) .All(constraintType => WellKnownOrmInterfaces.Entity.IsAssignableFrom(constraintType)); // Skip automatic registration for open generic types which constraints are not IEntity if (!allGenericConstraintsAreEntity) { return; } if (!typeDef.IsAbstract) { context.ModelInspectionResult.Register(new BuildGenericTypeInstancesAction(typeDef)); } context.ModelInspectionResult.Register(new RemoveTypeAction(typeDef)); return; } // Ancestor var parent = context.ModelDef.Types.FindAncestor(typeDef); if (parent != null) { context.DependencyGraph.AddEdge(typeDef, parent, EdgeKind.Inheritance, EdgeWeight.High); } // Interfaces foreach (var @interface in context.ModelDef.Types.FindInterfaces(typeDef.UnderlyingType)) { context.DependencyGraph.AddEdge(typeDef, @interface, EdgeKind.Implementation, EdgeWeight.High); } context.Validator.ValidateType(typeDef, hierarchyDef); // We should skip key fields inspection as they have been already inspected foreach (var field in typeDef.Fields.Where(f => hierarchyDef.KeyFields.All(kf => kf.Name != f.Name))) { InspectField(context, typeDef, field, false); } } }
static Mod() { BuildLog.Info("Starting initialization."); }