/// <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);
        }
示例#2
0
        /// <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);
 }