Home > Back-end >  How do I Dynamically set properties from the name in a parent class?
How do I Dynamically set properties from the name in a parent class?

Time:11-20

How do I dynamically set the "Name" properties of each of the AlarmModel's as the name of the model (i.e. HardwareFault) from the parent class?

public class NotificationModel
{
    public string UnrelatedProperty { get; set; }  // any solution should ignore other properties.

    public AlarmModel HardwareFault{ get; set; }

    public AlarmModel TimeoutFault { get; set; }

    public AlarmModel GenericFault { get; set; }
}

public class AlarmModel
{
    public string Name { get; set; }

    public bool isActive { get; set; }

    public bool isEnabled { get; set; }

    public bool isSilenced { get; set; }
}

CodePudding user response:

You should move property "Name" to parent class. and try to extend/inherit it to child class.

CodePudding user response:

If I understand correctly, you want to set the Name property of each AlarmModel to the name of the property in the parent NotificationModel?

If that is the case, you could do something like this:

public class NotificationModel
{
    private AlarmModel _hardwareFault;

    private AlarmModel _timeoutFault;

    private AlarmModel _genericFault;

    public string UnrelatedProperty { get; set; }  // any solution should ignore other properties.

    public AlarmModel HardwareFault
    { 
        get => _hardwareFault; 
        set
        {
            _hardwareFault = value;
            SetName(value);
        }
    }

    public AlarmModel TimeoutFault 
    {
        get => _timeoutFault; 
        set
        {
            _timeoutFault= value;
            SetName(value);
        }
    }

    public AlarmModel GenericFault 
    {
        get => _genericFault; 
        set
        {
            _genericFault= value;
            SetName(value);
        }
    }

    private SetName(AlarmModel model, [CallerMemberName] string propertyName = null)
    {
        model.Name = propertyName;
    }
}

CodePudding user response:

If you have already initialized NotificationModel with also already initialized HardwareFault, TimeoutFault, GenericFault properties, you can use this example:

var notificationModel = new NotificationModel()
{
    HardwareFault = new AlarmModel(),
    GenericFault = new AlarmModel(),
    TimeoutFault = new AlarmModel()
};

notificationModel?.GetType().GetProperties().Where(p => p.PropertyType.Name == "AlarmModel") // Or p.PropertyType == typeof(AlarmModel)
                                            .ToList().ForEach(alarmModelProperty =>
{
    // Get AlarmModel property instance
    var alarmModelInstance = alarmModelProperty.GetValue(notificationModel);
    // Get Name property
    var nameProperty = alarmModelIntance?.GetType().GetProperty("Name");
    // Set Name property value with name of AlarmModel property
    nameProperty?.SetValue(alarmModelInstance, alarmModelProperty.Name);
});

If you have already initialized NotificationModel, but without initialized HardwareFault, TimeoutFault, GenericFault properties, you can use this example:

var notificationModel = new NotificationModel();

notificationModel?.GetType().GetProperties().Where(p => p.PropertyType.Name == "AlarmModel") // Or p.PropertyType == typeof(AlarmModel)
                                            .ToList().ForEach(alarmModelProperty =>
{
    // Initialize new AlarmModel 
    var alarmModelInstance = Activator.CreateInstance(alarmModelProperty.PropertyType);
    // Get Name property of AlarmModel
    var nameProperty = alarmModelInstance.GetType().GetProperty("Name");
    // Set Name property of AlarmModel
    nameProperty?.SetValue(alarmModelInstance, alarmModelProperty.Name);
    // Set AlarmModel property of NotificationModel
    alarmModelProperty.SetValue(notificationModel, alarmModelInstance);
});

If you need full initialization with Reflection, you can use this example:

var notificationModelType = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(type => type.Name == "NotificationModel"); // Or type == typeof(NotificationModel)
if (notificationModelType is null) // No NotificationModel found in current assembly
    return;

// Initializing NotificationModel
var notificationModel = Activator.CreateInstance(notificationModelType);

notificationModel?.GetType().GetProperties().Where(p => p.PropertyType.Name == "AlarmModel") // Or p.PropertyType == typeof(AlarmModel)
                                            .ToList().ForEach(alarmModelProperty =>
{
    // Initialize new AlarmModel 
    var alarmModelInstance = Activator.CreateInstance(alarmModelProperty.PropertyType);
    // Get Name property of AlarmModel
    var nameProperty = alarmModelInstance.GetType().GetProperty("Name");
    // Set Name property of AlarmModel
    nameProperty?.SetValue(alarmModelInstance, alarmModelProperty.Name);
    // Set AlarmModel property of NotificationModel
    alarmModelProperty.SetValue(notificationModel, alarmModelInstance);
});

If NotificationModel declared NOT in current assembly (so it won't be in Assembly.GetExecutingAssembly().GetTypes()) - you can search through all loaded assemblies in AppDomain.CurrentDomain:

var notificationModelType = AppDomain.CurrentDomain.GetAssemblies()
                                                   .SelectMany(assembly => assembly.GetTypes())
                                                   .FirstOrDefault(type => type.Name == "NotificationModel");
  • Related