Mos*_*aou 8 c# runtime properties poco ormlite-servicestack
我为我的项目选择了ServiceStack OrmLite,这是一个纯粹的面向数据的应用程序.我愿意允许最终用户创建自己的XML格式定义的对象类型,这些格式将用于在运行时使用CodeDOM生成类.
我还将定义应用程序所需的一些"系统"对象(即User)但我无法预见最终用户将使用的所有属性,因此我正在寻找一种方法来允许扩展我在设计时创建的类.样品波纹管
public class User
{
public Guid Uid { get; set; }
public String Username { get; set; }
public String Password { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
最终用户希望拥有Email和Address.他应该能够将2个属性添加到上层类,并且整个类将是(OrmLite仍然可以使用它,因为它允许覆盖:
public class User
{
public Guid Uid { get; set; }
public String Username { get; set; }
public String Password { get; set; }
public String Email{ get; set; }
public String Address { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我知道可能存在崩溃系统的风险(如果类已经实例化),所以我正在寻找避免这个问题并模仿我需要的最佳方法.
您在这里所做的事情似乎分为两个部分。您需要动态创建类型以支持其他属性。您还需要确保您的 AppDomain 中永远不会出现重复的类型,即User.
已经给出的各种建议处理如何创建类型。在一个项目中,我们有类似的东西。我们创建了一个具有核心属性的基类和一个用于存储“扩展”属性的字典。然后我们用来Reflection.Emit创建一个具有所需属性的派生类型。每个属性定义只是从基类中的字典中读取或写入。由于Reflection.Emit需要编写低级 IL 代码,因此乍一看似乎很复杂。我们在另一个类库中编写了一些示例派生类并编译了它们。这些是我们在运行时实际需要实现的示例。然后我们使用 ildasm.exe 来查看编译器生成了哪些代码。这使得我们很容易弄清楚如何在运行时生成相同的代码。
您的第二个挑战是避免重复的类型名称。我们在每个生成类型的名称中附加了一个 guid(删除了无效字符),以确保这种情况永远不会发生。很容易修复,但我不知道你是否可以用你的 ORM 解决这个问题。
如果这是服务器代码,您还需要考虑程序集永远不会在 .NET 中卸载的事实。因此,如果您在运行时重复生成新类型,您的进程将继续增长。客户端代码中也会发生同样的情况,但如果您不希望该进程长时间运行,那么这可能不是什么问题。
我说的是程序集没有被卸载;但是,您可以卸载整个AppDomain. 因此,如果这是服务器代码,您可以让整个操作在其自己的应用程序域中运行,然后将其拆除,以确保卸载动态创建的类型。