控制器或模型中的存储库?
我一直在学习 NerdDinner 教程,其中大部分都很有意义。 我不确定为什么在控制器中直接使用存储库而不是模型对象。 例如,如果我们想实现自己的会员系统,并且它有一个带有 Login 方法的 AccountController,那么连接它的最佳解决方案是什么? 例如
Login(username,password){
repo = AccountRepository
account = repo.getLogin(username,password)
//check account isn't locked
//check account has been verified etc etc
//throw error or proceed to secure area
}
OR
Login(username,password){
repo = AccountRepository
account = repo.getLogin(username,password)
account.login() //business logic is handled in Account (Model)
}
OR
Login(username,password){
//no reference to repository
account = Account
//Account (Model) uses repository and handles business logic
account.login(username,password)
}
我建议让 Account 对象直接使用 AccountRepository,而不是 AccountController 从 AccountRepository 获取信息,然后将其传递给 Account 对象,例如
NerdDinnner 风格:
1 登录请求进来
2 AccountController 使用 AccountRepository 根据请求获取登录详细信息
3 AccountController 使用 Account 对象并传入步骤 1 中的信息
4 Account 对象处理请求并通知 AccountController
我的建议是:
1 登录请求进来
2 AccountController根据请求使用Account对象处理登录
3 Account对象使用AccountRepository获取登录详细信息
4 Account 对象处理请求并通知 AccountController
后一种样式的原因是,从 AccountRepository 返回登录详细信息后,将遵循业务规则,例如帐户是否锁定、帐户是否验证等。如果使用第一种样式,则获取逻辑详细信息和使用它们分为两个步骤。 后一种风格将所有逻辑保持在一起,同时仍然使用 AccountRepository,例如
Account.Login(username,password){
repo = AccountRepository
account = repo.GetLogin(username,password)
//check account isn't locked
//check account has been verified etc etc
//throw error or proceed to secure area
}
我希望这是有道理的。
I've been working through the NerdDinner Tutorial and most of it makes sense. What I'm not sure about is why the Repository is used directly in the Controller and not the Model objects. For instance, if we wanted to implement our own membership system and it had an AccountController with a Login method, what would be the best solution for hooking it up? e.g.
Login(username,password){
repo = AccountRepository
account = repo.getLogin(username,password)
//check account isn't locked
//check account has been verified etc etc
//throw error or proceed to secure area
}
OR
Login(username,password){
repo = AccountRepository
account = repo.getLogin(username,password)
account.login() //business logic is handled in Account (Model)
}
OR
Login(username,password){
//no reference to repository
account = Account
//Account (Model) uses repository and handles business logic
account.login(username,password)
}
I'm suggesting having the Account object use the AccountRepository directly, instead of the AccountController getting the information from the AccountRepository and then passing it to the Account object e.g.
NerdDinnner style:
1 Login request comes in
2 AccountController uses AccountRepository to get login details based on request
3 AccountController uses Account object and passes in info from step 1
4 Account object processes request and notifies AccountController
What I'm suggesting:
1 Login request comes in
2 AccountController uses Account object to process login based on request
3 Account object uses AccountRepository to get login details
4 Account object processes request and notifies AccountController
The reason for the latter style is that after login details are returned from the AccountRepository there would be business rules to follow e.g. is account locked, is account verified etc If the first style is used the logic for getting the details and then using them is split over 2 steps. The latter style keeps all the logic together while still using the AccountRepository e.g.
Account.Login(username,password){
repo = AccountRepository
account = repo.GetLogin(username,password)
//check account isn't locked
//check account has been verified etc etc
//throw error or proceed to secure area
}
I hope that makes sense.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
mvc 中的“模型”是表示模型而不是领域模型。 您可以将 MVC 中的模型视为控制器用来向视图引擎提供数据的数据传输对象。
控制器是与服务层连接的唯一参与者。
The "model" in mvc is a presentational model not a domain model. You can consider the model in MVC as a Data Transfer Object used by the Controller to feed the view engine.
The controller is the only actor connected with the service layer.
您至少应该有另一层(不是控制器)负责与存储库接口交互。 这允许将 UI(控制器是它的一部分)更改为另一个。 这样,无论是命令行、桌面还是 Web 界面都无关紧要。
在 ASP.NET MVC 中,我更喜欢将模型(不是我的域模型,MVC 模型)放在一个单独的项目中,而不是放入 MVC 项目中。 这允许与其他类型的 UI 共享 DTO(MVC 模型)。
You should at least have another layer (not the controller) that is responsible to interact with a repository interface. Thil allows to change de UI (the controller is a part of it) for another. In this way, it doesn't matter if it's a command line, desktop or web interface.
In ASP.NET MVC I prefer to have the model (not my domain model, the MVC one) in a separate project, not into the MVC one. This allows to share the DTOs (the MVC model) with other kind of UIs.
存储库是一个基础设施问题。 您正在做的就是让您的模型依赖于您的基础设施。 这是一种落后的做法。 这意味着,如果您想要执行诸如使用依赖项注入之类的操作,则必须从容器中解析模型,这对我来说没有多大意义。
另外,重点并不是要把所有东西都放在同一个地方。 您应该努力将您的关注点分成逻辑单元。 通过这种方式,您可以轻松识别应用程序的哪个部分执行什么操作。 它还适合于测试。
Repository is an infrastructure concern. What you are doing is making your model rely on your infrastructure. That is kind of a backward way of doing it. It means that if you wanted to do things like use dependency injection you would then have to resolve your model from your container which doesn't make much sense to me.
Also the point is not really to keep everything in once place. You should be striving to keep your concerns separated into logical units. This way you can easily identify what part of the application does what. It also lends itself to testing.
我想说的是,执行登录的不是帐户,而是您使用该帐户登录应用程序,因此在帐户上调用 Login 方法似乎有点不自然。
在领域驱动设计中,有一个不适合 Account 类的业务逻辑位置:这称为服务。 您可以在此处了解有关 DDD 服务的更多信息。
I would say that it is not the account that performs the login, but you use the account to login to the application, so calling the Login method on the account seems a little bit unnatural.
In Domain Driven Design there is a place for business logic which does not fit into the Account class: this is called a service. You can read more on DDD services e.g. here.
我会避免将数据访问放入模型中。 这很可能导致模型对存储机制的依赖。 我通常会将此逻辑放置在服务/业务逻辑层中,该层将与数据层和模型进行对话。 在您只有模型和控制器的情况下,控制器将完成这项工作。
我认为领域模型是一组玩具或工具,你可以拿起、使用、操纵等等。玩具并不真正关心它们存储在哪里,也不应该关心它们。 您应该能够将玩具放在架子上或工具箱中。 对玩具没有影响。
I would avoid putting your data access inside of your model. This could quite possibly lead to a dependency in the model on the storage mechanism. I would typically place this logic in the service/business logic layer which would do the speaking to the data layer and models. In your case with only model and controller it would be the controller that does this job.
I think of the domain model as a group of toys or tools, that you pick up, use, manipulate, etc. The toys don't really care where they are stored, nor should they. You should be able to put a toy on the shelf, or in a toolbox. It doesn't affect the toy.