/// <summary> /// Extension method to <see cref="ExcelContext"/> to add domain objects that use the Attribute /// interface <see cref="ExcelColumnConfigurationAttribute"/> for column configuration /// </summary> /// <typeparam name="TEntity">type of entity configured with attributes</typeparam> /// <param name="context">the context that should track the entity</param> /// <returns></returns> public static ExcelContext BuildAttributedEntity <TEntity>(this ExcelContext context) where TEntity : class, new() { var typeBuilder = new ExcelEntityBuilder <TEntity>(); var typeBuilderType = typeBuilder.GetType(); var entityType = typeof(TEntity); var entityProperties = entityType.GetProperties(); //iterate through all properties of the entity foreach (var targetProp in entityProperties) { var allCustomAttributes = targetProp.GetCustomAttributes(true); //property is marked as audit attribute var excelAuditAttribute = allCustomAttributes.FirstOrDefault(x => x.GetType() == typeof(ExcelAuditAttribute)) as ExcelAuditAttribute; if (excelAuditAttribute != null) { switch (excelAuditAttribute.AuditProperty) { case ExcelAuditProperties.RowId: //use the fluent api to track the audit property typeBuilder.RowIdWithPropertyName(targetProp.Name); break; default: throw new NotSupportedException($"The audit property type '{excelAuditAttribute.AuditProperty}' is not supported by the method '{nameof(ExcelContextExtensions.BuildAttributedEntity)}'."); } continue; } //property is marked with a data attribute var excelConfigAttribute = allCustomAttributes.FirstOrDefault(x => x.GetType() == typeof(ExcelColumnConfigurationAttribute)) as ExcelColumnConfigurationAttribute; if (excelConfigAttribute != null) { //add the property as via the generic api method //this requires ad-hoc reflection based method construction from generic to type of property var genericMethod = typeBuilderType.GetMethod(nameof(ExcelEntityBuilder <TEntity> .PropertyWithPropertyName), BindingFlags.Instance | BindingFlags.NonPublic); var typedGenericMethod = genericMethod.MakeGenericMethod(targetProp.PropertyType); var propertyBuilder = typedGenericMethod.Invoke(typeBuilder, new object[] { targetProp.Name }); ///configuration property can be accessed from the non generic base class ((ExcelPropertyBuilder)propertyBuilder).Configuration = excelConfigAttribute.Configuration; } } try { context.ModelBuilder.Entities.Add(entityType, typeBuilder); } catch (ArgumentException e) { throw new ArgumentException($"The type '{typeof(TEntity)}' was already configured as a mapped entity in the excel context."); } context.ValidateModel(); return(context); }
/// <summary> /// tracks entity of type <typeparamref name="TEntity"/> in the context. Creates a new /// <see cref="ExcelEntityBuilder{TEntity}"/> and calls the passed configuration method /// </summary> /// <typeparam name="TEntity">type of the domain object</typeparam> /// <param name="buildAction">gets called by this method and contains the builder configuration</param> public virtual void Entity <TEntity>(Action <ExcelEntityBuilder <TEntity> > buildAction) where TEntity : class { var entityBuilder = new ExcelEntityBuilder <TEntity>(); try { Entities.Add(typeof(TEntity), entityBuilder); } catch (ArgumentException e) { throw new ArgumentException($"The type '{typeof(TEntity)}' was already configured as a mapped entity in the excel context."); } buildAction(entityBuilder); }
private static void DataPropertiesMustHaveUniqueColumnAdresses(ExcelEntityBuilder entityBuilder) { var adresses = entityBuilder.ColumnConfigurations.Values.Where(x => x.Configuration.AuditPropertyType == ExcelAuditProperties.NO_AUDIT_FIELD) .Select(x => x.Configuration.ColumnIndex); if (adresses.Any(x => x == default)) { throw new Exception($"Some columns where configured without a column index." + $" Use '{nameof(ExcelPropertyBuilder<object>)}.{nameof(ExcelPropertyBuilder<object>.Column)}' to set the column index."); } var duplicatedAddresses = adresses.CountDistinct().Where(x => x.Value > 1).Select(x => ExcelPropertyConfiguration.ColumnAdress(x.Key)); if (duplicatedAddresses.Count() > 0) { throw new Exception($"The excel column adresses [{string.Join(",", duplicatedAddresses)}] where defined multiple times."); } }
private void ValidateEntityBuilder(ExcelEntityBuilder entityBuilder) { DataPropertiesMustHaveUniqueColumnAdresses(entityBuilder); }