วิธี C # ทั่วไปในการจัดเก็บคุณสมบัติที่ไม่รู้จักในรายการ

ฉันต้องการจัดเก็บ LicenseInformations สำหรับหลายโดเมนในแอปพลิเคชันของฉัน

โครงสร้างมีลักษณะดังนี้:

   public class LicenseData
    {
        // properties...
        public List<LicenseDomain> Domains { get; set; }
        // other properties...
    }

    public class LicenseDomain
    {
        // properties...
        public object LicenseConfig { get; set; }
    }

เรามีโดเมนหลายโดเมนที่มีคุณสมบัติแตกต่างกันโดยสิ้นเชิง แต่ใบอนุญาตอาจมีการกำหนดค่าหลายรายการ

ตัวอย่างเช่น:

{
   "MaxValidUsers": 5
}
{
   "Property": "xy"
   "SubProperty": { "Foo" : "Bar" 
   }
}

การสร้างนั้นไม่มีปัญหา แต่อย่างใด .. แต่ถ้าฉันกู้คืนข้อมูลจากไฟล์ json ที่ลงนามแล้ว ฉันจะทำการดีซีเรียลไลซ์เพื่อคัดค้าน ..

รูปแบบ / ความเป็นไปได้ใดที่ฉันต้องทำงานร่วมกับ Interfaces / Abstracts / ที่ฉันสามารถ (RE) จัดเก็บข้อมูลทั่วไปได้ที่นี่..

ตอนนี้ฉันแฮ็คด้วย:

JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(domain.LicenseConfig))

แต่ฉันไม่สามารถเห็นด้วยกับตัวเองได้


person Andréw    schedule 14.09.2020    source แหล่งที่มา
comment
พิจารณาใช้คลาสพื้นฐาน...   -  person Daniel A. White    schedule 14.09.2020
comment
มีเนื้อหาประเภทไหน? วัตถุนั้นคงอยู่ ฉันคิดว่า..   -  person Andréw    schedule 14.09.2020
comment
stackoverflow.com/a/4416536/2133965 เป็นยังไงบ้าง   -  person VietDD    schedule 14.09.2020


คำตอบ (1)


ดังนั้น ตามบริบทต่างๆ ที่ฉันสามารถคว้าได้ ฉันขอแนะนำให้จัดเก็บ LicenseConfig ของคุณเป็นสตริง JSON ซึ่งจะทำให้คุณสามารถดำเนินการบางอย่างดังนี้:

public class LicenseDomain
{
    // properties...

    // Depending on how this is loaded,
    // this property (or at least its setter) could be made private/protected/internal
    public string LicenseConfigJson { get; set; }

    public T LicenseConfig<T>() where T : BaseLicenseConfig
    {
        if (string.IsNullOrWhiteSpace(LicenseConfigJson))
        {
            return null;
        }
        return JsonConvert.DeserializeObject<T>(LicenseConfigJson);
    }
    public void SaveLicenseConfig<T>(T config) where T : BaseLicenseConfig
    {
        if (config == null)
        {
            LicenseConfigJson = null; 
        }
        else
        {
            LicenseConfigJson = JsonConvert.SerializeObject(config);
        }
    }


}

หรือหาก LicenseDomain แต่ละตัวมี LicenseConfig ได้เพียงประเภทเดียว คุณสามารถกำหนดให้เป็นพารามิเตอร์ทั่วไปสำหรับคลาสได้:

public class LicenseData
{
    // properties...
    public List<LicenseDomain<BaseLicenseConfig>> Domains { get; set; }
    // other properties...
}

public class LicenseDomain<T> where T : BaseLicenseConfig
{
    // properties...

    // Depending on where this value comes from, you could do this a variety of ways, 
    //but this is just one
    public string LicenseConfigJson { get; set; }
    public T LicenseConfig
    {
        get
        {
            if (string.IsNullOrWhiteSpace(LicenseConfigJson))
            {
                return null;
            }
            return JsonConvert.DeserializeObject<T>(LicenseConfigJson);
        }
        set
        {
            if (value == null)
            {
                LicenseConfigJson = null;
            }
            else
            {
                LicenseConfigJson = JsonConvert.SerializeObject(value);
            }
        }
    }
}

public abstract class BaseLicenseConfig
{
    
}

public class LicConfig1 : BaseLicenseConfig
{
    public int MaxValidUsers { get; set;}
}

public class LicConfig2 : BaseLicenseConfig
{
    public string Property {get;set;}
    public SubProp SubProperty {get;set;}
}

public class SubProp
{
    public string Foo {get;set;}
}

ในทั้งสองกรณี คลาส BaseLicenseConfig จะบังคับใช้อย่างเคร่งครัดว่าทุกสิ่งในรายการโดเมนสามารถมาจากคลาสพื้นฐานบางประเภทได้ หากนั่นไม่สำคัญ คุณไม่จำเป็นต้องมีคลาสพื้นฐานและสามารถลบตำแหน่ง T : BaseLicenseConfig ออกจากคลาส LicenseDomain ได้

person s0n1c    schedule 15.09.2020