相同实体类型(任何 ORM)的不同版本用于不同的角色/授权级别

发布于 2024-08-19 15:57:24 字数 987 浏览 6 评论 0原文

例如,考虑一下:

public interface IStaff
{
    FullName name { get; set; }
    EMailAddress email_address { get; set; }
    SocialInsuranceId ssn { get; set; }
    PositiveInt age { get; set; }
    Address home_address { get; set; }
}

对于某些用户,视图模型只需要 nameemail_address。 其他人可能拥有包含这些属性以及 ssnagehome_address 的视图模型。假设还有一位统计学家,其视图获取 agehome_address

现在,我可以通过接口继承将其拆分为 IStaffBasicIStaffDetailsIStaffStats,以将给定视图模型中的 API 限制为适当的属性。

但是,当通过网络从数据服务检索该实体时,它仍将包含附加详细信息,这是绝对不能发生的。

那么,最好
(A) 为每个版本创建完全不同的实体类型,从而对每种类型进行许多额外的近乎重复的查询操作,从而在一定程度上污染服务层 API,或者
(B) 始终返回 Staff 实体,但 (1) 从服务中返回它们,并根据服务上的授权检查将排除的属性设置为 null 以及 (2)如上所述,在视图模型中使用有限的接口,或者
(C) 使用我没有考虑过但你要告诉我的非常优雅的模式或解决方案。

选项 A 在视图模型级别似乎更干净,但服务 API 会很糟糕。选项 B 似乎增加了服务器上实体处理的复杂性,但更好地遵守了开放-封闭原则。

想法?

Consider, for example:

public interface IStaff
{
    FullName name { get; set; }
    EMailAddress email_address { get; set; }
    SocialInsuranceId ssn { get; set; }
    PositiveInt age { get; set; }
    Address home_address { get; set; }
}

For some users, the viewmodel will only require name and email_address.
Others may have a viewmodel that includes those properties plus ssn, age and home_address. Let's say there is also a statistician, whose view gets age and home_address.

Now, I could split this out into IStaffBasic, IStaffDetails, and IStaffStats with interface inheritance to limit the API in a given viewmodel to the appropriate properties.

However, when this entity is retrieved from the data service across the wire, it will still include the additional details, which must not occur.

So, would it be better to
(A) create wholly different entity types for each of these versions, somewhat polluting the service layer API with many additional near-duplicate query operations for each type, or
(B) always return a Staff entity, but (1) return them from the service with excluded properties set to null based on the authorization check at the service and (2) use limited interfaces within the viewmodels as described above, or
(C) use the very elegant pattern or solution that I haven't considered, but about which you're going to tell me.

Option A seems cleaner at the viewmodel level, but the service API is going to be nasty. Option B seems to add complexity to entity handling on the server, but better adherence to the open-closed principle.

Thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

极致的悲 2024-08-26 15:57:24

投影是可行的方法 - 结合选项 A 和 B。

您的 ORM 应该只与单个实体类型 Staff 交互,因此您只需维护(和扩展)一组映射、查询等。

但是,您还可以创建适合每种安全场景的不同类(IStaffBasicIStaffDetails 等),将 Staff 实例投影到这些类中,并通过网络返回投影对象:

某些 ORM 支持投影作为框架功能,但如果需要,您可以在服务层中手动执行此操作。

Projection is the way to go - combine options A and B.

Your ORM should only interact with a single entity type, Staff, so you only have to maintain (and extend) a single set of mappings, queries, and so forth.

However, you'll also create different classes suitable for each security scenario (IStaffBasic, IStaffDetails, etc.), project the Staff instances into those, and return the projected objects over the wire:

Some ORMs support projection as a framework feature, but if need be, you can do it manually in your service layer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文