存储库/服务层设计模式的建议
尝试在这里创建一个非常简单的存储库和服务层模式。 (.NET 4、C#、LINQ,尽管这个问题部分与语言无关)。注意:这只是研发。
我的目标是最大限度地减少服务层中方法定义的数量。
这是我的存储库合同:
interface IFooRepository
{
IEnumerable<Foo> Find();
void Insert(Foo foo);
void Update(Foo foo);
void Delete(Foo foo);
}
没有什么新内容。
现在,这就是我(试图)在我的服务合同中包含的内容:
interface IFooDataService
{
public IEnumerable<Foo> Find(FooSearchArgs searchArgs);
}
本质上,任何特定的“Foo”都有许多属性(id、名称等),我希望能够搜索这些属性。
所以,我不想为每个不同的属性都有 1x Find 方法,我只想要一个 - 这样当我创建额外的属性时,我不必修改合同。
“FooSearchArgs”只是一个简单的 POCO,其中包含所有不同的“Foo”属性。
所以,这就是我想做的,这是我的问题:
- 这是糟糕的设计吗?如果是这样,有哪些替代方案?
- 如何在服务层实现这种过滤?我是否必须检查设置了“FooSearchArgs”的哪些属性,然后继续过滤? (if this, then query.where,if this,query.where,等等)有人知道一个聪明的 LINQ IEnumerable 扩展方法来执行此操作吗? (即
repository.WhereMeetsSearchCriteria(fooSearchArgs)
)
感谢您的帮助。
Trying to make a really simple repository and service layer pattern here. (.NET 4, C#, LINQ, although this question is partially language-agnostic). Note: this is just R&D.
My goal is to minimize the amount of method definitions in my service layer.
Here's my Repository Contract:
interface IFooRepository
{
IEnumerable<Foo> Find();
void Insert(Foo foo);
void Update(Foo foo);
void Delete(Foo foo);
}
Nothing new there.
Now, here's what im (trying) to have in my Service Contract:
interface IFooDataService
{
public IEnumerable<Foo> Find(FooSearchArgs searchArgs);
}
Essentially, any particular "Foo" has many properties (id, name, etc), which i would like to be able to search upon.
So, i dont want to have 1x Find method for each different property, i just want one - that way when i create extra properties i dont have to modify the contracts.
The "FooSearchArgs" is just a simple POCO with all the different "Foo" properties it.
So, that's what im trying to do, here's my questions:
- Is this poor design? If so, what are the alternatives?
- How can i implement this filtering in the service layer? Would i have to check what properties of "FooSearchArgs" are set, then keep filtering down? (if this, then query.where, if this, query.where, etc) Anyone have an idea of a clever LINQ IEnumerable extension method to do this? (ie
repository.WhereMeetsSearchCriteria(fooSearchArgs)
)
Appreciate the help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我们使用非常相似的东西。您需要决定的一件事是是否要在存储库外部公开 IQueryable。您的 find 方法返回 IEnumerable ,它可能是从 when 子句返回的 IQueryable 。
返回 IQueryable 的优点是您可以在存储库层之外进一步细化您的标准。
该表达式仅在您使用返回的数据时才会被编译,这就是缺点。因为只有在实际使用结果时才访问数据库,所以最终可能会在会话 (nhibernate) 或连接关闭后尝试调用数据库。
我个人偏好是使用规范模式,在该模式中向 find 方法传递一个 ISpecification 对象,用于执行查询。
运行查询后,存储库对从规范返回的结果 IQueryable 调用 ToArray 或 ToList,以便立即评估查询。虽然这看起来不如公开 IQueryable 灵活,但它有几个优点。
We use something very similar. One thing you need to decide on is if you are going to expose IQueryable outside of the repository. Your find method returns IEnumerable which could be the IQueryable returned from your when clause.
The advantage of returning the IQueryable is that you can further refine your criteria up outside of your repository layer.
The expression will only be compiled when you come to use the returned data and here in lies the disadvantage. Because you only hit the database when you actually come to use the results you could end up trying to call the database after your session (nhibernate) or connections have been closed.
My personal preference is to use the specification pattern where you pass your find method an ISpecification object is used to do the query.
After the query is run the repository calls ToArray or ToList on the resulting IQueryable returned from the specification so that the query is evaluated there and then. Whilst this may seem less flexible than exposing IQueryable it comes with several advantages.
将 Func 作为参数传递给服务层的 Find 方法,而不是 FooSearchArgs,一个选项?枚举有一个Where方法(linq),它接受Func作为参数,因此您可以使用它来过滤结果。
Is passing a Func as a parameter to your service layer's Find method, instead of the FooSearchArgs, an option? Enumerables have a Where method (linq) that takes a Func as a parameter, so you could use it to filter the results.