3

我要归档的内容:

  • 包含 EntityClasses 的服务程序集(项目) - 纯数据。
  • 扩展这些实体的 GUI 程序集以用于自己的用途 - GUI 的运行时信息。

我尝试了什么:

  • 推导(Gui 定义类 ExtendedEntity : Service.BaseEntity)

    对我来说似乎是最常见且唯一可行的方式,但是:

    从服务中检索数据后将 Service.BaseEntity 转换为 ExtendedEntity 很痛苦。可以通过使用反射基于基本实体实例生成新的 ExtendedEntity 实例来“解决”这个问题,但这不是“正确”的解决方案。

  • 部分课程

    正是我正在寻找的东西,除了它不能交叉组装。

我非常感谢任何帮助我找到合适且干净的解决方案而没有反射作弊的提示=)

4

3 回答 3

1

这不是一个直接的答案,但您可能需要多考虑一下您的设计。为什么您的 GUI 需要深入了解数据存储机制?通常,我们会非常努力地确保 UI 和数据访问是松散耦合的,因此我们可以对其中任何一个进行更改,而不必担心破坏已经工作的内容。您要实施的设计可能会在以后导致无法预料的问题。

一种适用于此类事物的常见模式称为存储库模式。本质上,服务程序集(存储库)将包含将数据推入和推出特定数据存储所需的所有知识。数据的“形状”是众所周知的,并且在 GUI 和存储库之间共享。服务组件将使 CRUD 操作对 GUI 可用,并且 GUI 将持有对存储库的引用,并在其上调用方法来获取、创建和更新它需要的数据。

这里有一些链接可以开始了解松散耦合、存储库模式和依赖注入的想法。

内聚和耦合

什么是依赖注入

什么是好的存储库模式教程

于 2011-10-16T01:57:24.250 回答
0

您可以让您的 GUI 程序集在实体类上定义扩展方法。使用适当using的指令,这意味着使用代码将不知道或不关心方法的实际定义位置。

一个轻微的烦恼是扩展属性的不存在,所以即使是概念上的属性也必须作为方法来实现。

它看起来有点像这样:

  • 在服务组装

    public class FooDTO
    {
        public string Name { get; set; }
    }
    
  • 在 GUI 程序集中

    internal static class Extensions
    {
        // Artificial example!
        public static int GetNameLength(this FooDTO foo)
        {
            return foo.Name.Length;
        }
    }
    
    // Consuming code
    int myFooNameLength =  myFooDTO.GetNameLength();
    
于 2011-10-07T14:52:16.360 回答
0

反编译是一种选择吗?如果是,您可以使用PostSharpMono Cecil来重写有问题的类,并在其中添加您想要的代码。我很好奇为什么你不想使用像推导这样的标准 OO 方法。这绝对不是黑客攻击。

“最干净”的 OO 解决方案是使用聚合并将 Entity 类封装在对象中,您可以在其中完全控制可以对数据执行的操作以及您希望如何操作或查询数据。当您的聚合类不再需要公开内部实体类时,您已经达到了“天堂”,因为您的类足够强大,可以使用正确的抽象支持所有必要的操作。

如果您要扩展的类是密封的,那么您需要认真思考为什么这些类的作者不希望您扩展它们。

Eric Lippert 有一篇关于sealed 关键字用法的好文章。

...

现在,我认识到开发人员是非常实际的人,他们只想完成工作。当然,能够扩展任何类都很方便。典型的开发人员会说“IS-A-SHMIZ-A,我只是想在 Froboznicator 类中加入一个 Confusticator”。该开发人员可以编写一个哈希表以将一个映射到另一个,但是您必须担心何时删除项目等 - 这不是火箭科学,但它是工作。

显然,这里有一个权衡。权衡是在让开发人员节省一点时间(一方面允许他们将任何旧对象视为属性包)和在合理的时间——我将严重倾向于后者。因为你知道吗?如果我们提供给他们的框架因为半生不熟、脆弱、不安全且没有经过全面测试而拖慢了他们的速度,这些开发人员将会痛苦地抱怨!

...

你的,阿洛伊斯克劳斯

于 2011-10-15T23:41:46.527 回答