Why can't I get the boolean value from nested classes property?

211 views Asked by At

I am trying to use the GetValue() method of PropertyInfo, but it seems like its not working.

public bool IsDeviceOperable(ServiceType type, bool isServer, string domain)
{
    string settingsFileContent = _fileReader.Read(_filePathProvider.GetSettingsFilePath());

    var settings = _jsonDeserializer.Deserialize<Settings>(settingsFileContent);
    var settingsName = GetSettingsNameByType(type);

    string deviceType = GetDeviceType(isServer);

    var info = settings.GetType().GetProperty(domain.ToUpper())
        .PropertyType.GetProperty(settingsName)
        .PropertyType.GetProperty(deviceType);


    bool value = (bool)info.GetValue(settings, null);

    return value;
}

It throws System.Reflection.TargetException: 'Object does not match target type.'

My Settings file looks like this:

public class Settings
{
    public FirstDomain First { get; set; }
    public SecondDomain Second { get; set; }
    ...
}

Domain classes looks like this:

public class FirstDomain
{
    public Settings1 firstSettings { get; set; }
    public Settings2 secondSettings { get; set; }
    ...
}

public class SecondDomain
{
    public Settings1 firstSettings { get; set; }
    public Settings2 secondSettings { get; set; }
    ...
}

Settings classes look like this:

public class Settings1
{
    public bool RunOnClient { get; set; }
    public bool RunOnServer { get; set; }
}

public class Settings2
{
    public bool RunOnClient { get; set; }
    public bool RunOnServer { get; set; }
}

Please dont comment on the structure of the classes, it has to be this way. There is a reason for First Domain Second domain, and also the settings differ from each other, just for easier understanding, I renamed them.

1

There are 1 answers

0
Markus On BEST ANSWER

The problem is that the code creates the property info for a nested property, but provides an instance of the parent object. The property info always operates on an instance of the type that the property is defined on.

Therefore, you have to get the parent instances first and then call the property on the correct instance:

var settings = _jsonDeserializer.Deserialize<Settings>(settingsFileContent);
var settingsName = GetSettingsNameByType(type);

string deviceType = GetDeviceType(isServer);

var domainProp = settings.GetType().GetProperty(domain.ToUpper());
var domainInst = domainProp.GetValue(settings, null);
var settingsProp = domainProp
    .PropertyType.GetProperty(settingsName);
var settingsInst = settingsProp.GetValue(domainInst, null);
var deviceTypeProp = settingsProp
    .PropertyType.GetProperty(deviceType);

bool value = (bool)deviceTypeProp.GetValue(settingsInst, null);