繁体   English   中英

C#类结构,以确保始终应用某些过滤器

[英]C# Class Structure to Ensure Certain Filters Are Always Applied

因此,我目前正在与一个团队一起进行一个项目,而我和我的团队遇到了一个特定的设计方案,我们正在尝试提出解决方案。

当前项目实施的背景信息:

该问题涉及我们解决方案中的三个主要项目:存储库,模型和服务项目。 如果不清楚,每个项目的目的如下。 Models项目包含我们存储在数据库中的所有数据的模型。 Repository项目有一个主要的数据库访问类,该类使用泛型根据传入的模型与不同的表进行交互。最后, Services项目包含在前端和存储库之间连接数据的类,并且通常每个服务类都映射1-到模型类的to-1。 正如人们所期望的那样,构建依赖项是:存储库依赖于模型,服务依赖于两个项目。

问题:

我们当前遇到的问题是,我们需要一种方法来确保如果开发人员尝试查询特定类型的对象(或称其为ModelA)或与之交互,那么我们要确保始终包含一组特定的过滤器默认值(这些过滤器部分基于特定用户是否有权查看列表中的某些对象)。 开发人员应该能够覆盖此过滤器。

我们要避免做的是在存储库类中使用if子句,该子句显示“如果要更新此模型类型,请添加这些过滤器”。

我们想到/考虑过的解决方案:

我们目前正在考虑的一种解决方案是在ServiceA中提供一个函数(与ModelA对应的服务),该函数将这些过滤器附加到给定的查询中,然后进行处理,以便任何人请求模型的db上下文时,它们都必须传入一个以某种方式操纵过滤的函数(换句话说,如果他们想与ModelA交互,则可以从ServiceA传递过滤函数)。 该解决方案的问题在于,开发人员必须始终意识到,如果他们曾经与ModelA进行交互,则他们必须从ServiceA传递函数。 另外,由于我们不希望每个模型都强制执行某些过滤器选项,因此我们可能希望将其作为可选参数,这可能会导致开发人员在与ModelA交互时忘记包括此功能的问题。

我们考虑的另一种解决方案是在ModelA上具有一个属性(简称为DefaultFilterAttribute),该属性存储应实现特定接口(称为IFilterProvider)的类类型。 ServiceA将实现此接口,并且ModelA的属性将被赋予ServiceA作为类型。 然后,存储库方法可以检查传入的实体是否具有DefaultFilterAttribute,然后简单地调用由附加到该属性的类实现的方法。 不幸的是,正如您中某些人可能已经注意到的那样,当前建立项目依赖关系的方式,我们实际上无法实现这样的解决方案。

因此,我想知道是否有针对此问题的干净解决方案,或者是否有可能我们错误地考虑了问题和/或设计模式,因此应该采用完全不同的方法。

我认为您正在使这不必要地变得复杂。 您所描述的几乎是服务层的全部目的。 大概,您将拥有类似GetModelAList东西(对于服务而言,这实际上是一种非常糟糕的方法,但是仅用于说明)。 然后,将自动应用某些过滤器的逻辑封装在该方法中。 该应用程序不知道或不在乎如何检索该数据。 它只知道是否需要ModelA实例列表,就调用该方法。

如果您随后想要一种不应用这些过滤器的方法,则可以提供另一种方法,例如GetModelAListUnfiltered ,或者将布尔值或其他内容传递给确定是否自动应用过滤器的原始方法。 确实,您可以根据需要进行处理,但要点是,它们都封装在服务中。

最后,您没有确切指定存储库正在执行的操作,但是存储库应该非常简单,实际上只是返回所有对象的集合。 像您所说的那样的逻辑属于服务层。 但是,即使仅在使用Dapper或ADO.NET之类进行直接数据库访问的情况下,此规则也适用。 如果您使用的是成熟的ORM(例如Entity Framework),请完全丢弃存储库层。 是的,您没听错我的话:将其完全丢弃。 围绕ORM的存储库是一个无用的抽象,仅用于添加不需要出于任何充分原因就需要维护和测试的更多代码。 服务层已经提供了某种抽象级别给您带来的好处。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM