mardi 12 octobre 2021

how to access the class properties based on condition

I have below the object and its internal objects and I have added custom attributes to the property names which are required for the report.

public class Space
{
    public SpaceIdentity SpaceIdentity { get; set; } = new();
    public SpaceGeometry SpaceGeometry { get; set; } = new();
    public AirBalance AirBalance { get; set; } = new();
    public EngineeringChecks EngineeringChecks { get; set; } = new();
}
public class SpaceIdentity
{
    public int ElementId { get; set; } // Not required
    [DisplayNameWithUnits(DisplayName = "Space Number", IsIncludedInReport2 = true)]
    public string Number { get; set; }
    [DisplayNameWithUnits(DisplayName = "Space Name", IsIncludedInReport2 = true, IsIncludedInReport1 = true)]
    public string Name { get; set; }
    [DisplayNameWithUnits(DisplayName = "Room Number", IsIncludedInReport1 = true)]
    public string RoomNumber { get; set; }
    [DisplayNameWithUnits(DisplayName = "Room Name", IsIncludedInReport1 = true)]
    public string RoomName { get; set; }
}

public class SpaceGeometry
{
    public Vertex LocationPoint { get; set; } // this is not required
    [DisplayNameWithUnits(DisplayName = "Space Area", Units = "(ft²)", IsIncludedInReport1 = true)]
    public double FloorArea { get; set; }
}
.....

Here I am building an excel report, which I want to use property display name's as header column names of that report. Here are some of the properties attribute information used in multiple reports. What I did was I added a bool condition attribute like (isIncludedInReport1) and loop through the properties of space and loop through the properties of inner object(SpaceGeometry) to get a particular property name and its attribute values based on this boolean condition.

What I am looking for here is without adding these bool attributes, is there any way to access the property names based on condition. I thought about adding interfaces, but that is not possible here because I have multiple inner classes having properties that I need to include in a single report.

Could anyone please let me know is there any other way to achieve this?

Update:

   var columnResult = new OrderedDictionary();
    GetReportHeaderColumnName(typeof(Space), columnResult);
    
    public static void GetReportHeaderColumnName(Type type, OrderedDictionary headerNameByUnit)
    {
        var properties = type.GetProperties();
        foreach (var propertyInfo in properties)
        {
            if (propertyInfo.PropertyType.IsClass && !propertyInfo.PropertyType.FullName.StartsWith("System."))
            {
                if (propertyInfo.PropertyType == typeof(Overridable<double>))
                {
                    AddReportHeaderName(headerNameByUnit, propertyInfo);
                }
                else
                {
                    GetReportHeaderColumnName(propertyInfo.PropertyType, headerNameByUnit);
                }
            }
            else
            {
                AddReportHeaderName(headerNameByUnit, propertyInfo);
            }
        }
    }

    protected static void AddReportHeaderName(OrderedDictionary columnResult, PropertyInfo propertyInfo)
    {
        if (propertyInfo.GetCustomAttributes(typeof(DisplayNameWithUnitsAttribute), true).Any())
        {
            var displayNameWithUnitsAttribute = (DisplayNameWithUnitsAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(DisplayNameWithUnitsAttribute));

            if (displayNameWithUnitsAttribute.IsIncludedInReport2)
            {
                columnResult.Add(displayNameWithUnitsAttribute.DisplayName, displayNameWithUnitsAttribute.Units);
            }
        }
    }




Aucun commentaire:

Enregistrer un commentaire