代码之家  ›  专栏  ›  技术社区  ›  namenlos

C:将程序集(通过反射)用作(元数据)数据存储

  •  2
  • namenlos  · 技术社区  · 15 年前

    一些背景

    • 我的一个项目需要携带一些“元数据”(是的,我讨厌使用这个词)。
    • 元数据具体包含的内容并不重要,只是它比简单的“表”或“列表”更复杂——您可以将其视为一个小型的信息数据库。
    • 目前,我将这个元数据存储在一个XML文件中,并有一个定义模式的XSD。
    • 我希望将此元数据与我的项目一起打包,目前这意味着将XML文件作为资源保存。
    • 不过,我一直在寻找更多 强类型 另一种选择。我正在考虑将它从一个XML文件移动到C代码-因此,不用使用XML API来遍历我的元数据,而是通过对类型的反射依赖于.NET代码。
    • 除了强(ER)类型之外,我从使用程序集看到的一些有用特性是:(1)我可以在某种程度上用resharper等工具重构“模式”(schema);(2)元数据可以与代码一起提供;(3)不必依赖任何外部DB组件。

    问题

    • 如果你尝试过这样的方法,我很好奇你学到了什么。
    • 你的经历是积极的吗?
    • 你学到了什么?
    • 您发现了这种方法中的哪些问题?
    • 我应该考虑哪些因素?
    • 你能再做一次吗?

    笔记

    • 我不是在问如何使用反射-那里不需要帮助
    • 我从根本上询问您的经验和设计考虑

    更新:有关元数据的信息

    因为人们问我,我会再描述一点元数据。我试图抽象一点-所以这看起来有点人为。

    模型中有三个实体:

    • 一组“组”—每个组都有一个唯一的名称和几个属性(通常是表示某种ID号的int值)
    • 每个“组”包含一个或多个“小部件”(不超过50个)-每个项目都有名称(有多个名称)、ID和各种布尔属性等属性。
    • 每个小部件包含一个或多个“场景”。每个“场景”都是文档-一个指向如何使用小部件描述的URL。

    通常我需要运行这些类型的“查询”

    • 获取所有小部件的名称
    • 获取至少包含一个BoolProp1=true的小部件的所有组的名称
    • 获取小部件的ID,哪个组包含该小部件

    我是如何考虑在组件中建模实体的

    • 有3个类:组、小部件、文档
    • 有25个组,所以我将有25个组类-所以“foogroup”将从组派生,小部件和文档的模式相同
    • 每个类都有属性来解释名称、ID等。
    2 回复  |  直到 15 年前
        1
  •  1
  •   Iravanchi    15 年前

    我已经为我的大部分项目使用并扩展了元数据,其中许多与描述组件、它们之间的关系、映射等相关。

    (使用属性的主要类别广泛包括O/R映射器、依赖项注入框架和序列化描述-特别是XML序列化)

    好吧,我想请您多描述一点关于要作为资源嵌入的数据的性质。使用属性对于描述您的类型和类型元素的数据类型自然是很好的,但是属性的每种用法都是简单而简短的。属性(我认为)应该很有凝聚力,并且在某种程度上相互独立。

    我要指出的解决方案之一是“XML序列化”方法。您可以保留当前的XML,并将它们作为嵌入资源(这可能是您已经做过的)放入程序集中,然后将整个XML一次读取到对象的强类型层次结构中。

    在我看来,XML序列化非常简单,比典型的XML API甚至Linq2XML都要简单得多。它使用属性将类属性映射到XML元素和XML属性。一旦将XML加载到对象中,您就可以将内存中所需的所有内容作为“类型化”数据。

    根据我从你的描述中了解到的,我认为你有很多数据要放在一个类上。这意味着在类上面有一个大的(在我看来)丑陋的属性代码。(除非您可以在成员之间分发数据,使每个成员都小而独立,这很好。)

    我在使用XML序列化处理大量数据方面有很多积极的经验。您可以根据需要排列数据,获得类型安全性,获得智能化(如果您将XSD提供给Visual Studio),还可以获得一半的重构。Resharper(或我所知的任何其他重构工具)无法识别XML序列化,因此当您重构类型化的类时,它不会更改XML本身,而是更改数据的所有用法。

    如果你给我更多关于你的数据是什么的细节,我也许能在我的答案中添加一些东西。

    对于XML序列化示例,只需谷歌“XML序列化”或在msdn中查找即可。

    更新

    我强烈推荐 不是 使用类来表示数据的实例。甚至使用 封装数据违背了它的逻辑定义。

    我想您最好的选择是XML序列化,前提是您已经有了XML格式的数据。你可以用更少的代码获得你想要的所有好处。并且可以使用Linq2Objects对XML可序列化对象执行任何查询。

    代码的一部分可以如下所示:

    [XmlRoot]
    public class MyMetadata
    {
    
        [XmlElement]
        public Group[] Groups { get; set; }
    
    }
    
    public class Group
    {
    
        [XmlAttribute]
        public string Name { get; set; }
    
        [XmlAttribute]
        public int SomeNumber { get; set; }
    
        [XmlElement]
        public Widget[] Widgets { get; set; }
    
    }
    
    public class Widget
    {
        ...
    }
    

    你应该打电话 new XmlSerializer(typeof(MyMetadata)) 创建序列化程序,并调用 Deserialize 方法将XML流赋给它,然后得到 MyMetadata 班级。

        2
  •  1
  •   roufamatic RichardJohnn    15 年前

    从您的描述中不清楚,但听起来您有希望访问的程序集级元数据(与类型级相反)。可以在每个程序集中有一个实现公共接口的类,然后使用反射查找该类并实例化它。然后您可以在其中硬编码元数据。

    当然,问题在于XML所带来的好处,即如果没有新的构建,就无法修改元数据。但如果你朝这个方向走,你可能已经考虑到了。