关于使用哪些服务以及按什么顺序的决定是否构成 MVC 控制器方法中的逻辑?
我正在开发的新 ASP.NET MVC 应用程序即将结束,并且我意识到我并没有 100% 明白我的控制器方法中应该发生什么。
操作方法是否更好地决定调用哪些服务/方法以及按什么顺序调用:
AccountService _accountService;
BillingService _billingService;
InvoiceService _invoiceService;
...
public ActionResult UpgradeAccountPackage(PackageType packageType, int accountId)
{
_accountService.UpgradeAccountPackage(packageType, accountId);
_billingService.BillForAccountUpgrade(packageType, accountId);
_invoiceService.CreateAccountUpgradeInvoice(packageType, accountId);
}
或者是否最好坚持对一个服务进行单一方法调用并允许该方法调用它需要的其他服务/支持方法?
public ActionResult UpgradeAccountPackage(PackageType packageType, int accountId)
{
// account service upgrades account then calls the BillingService and InvoicService
// methods called above within this method
_accountService.UpgradeAccountPackage(packageType, accountId);
}
我倾向于在这里使用第二个示例,因为最初似乎第一个方法会以某种方式构成逻辑,并且意味着 acion 方法必须本质上了解帐户升级过程在我的应用程序中如何工作,这看起来像一件坏事。
然而,现在我的应用程序几乎完成了,它有一个很大的服务层,这种方法导致几乎每个服务都强烈依赖于许多其他服务,并且没有集中的地方来决定业务交易的流程,例如上面提到的那个如上所述,您必须深入研究服务方法才能发现流程。
我正在考虑重构以更类似于上面的第二种方法,或者在控制器和服务层之间引入一个新层来控制流程。
人们倾向于使用第一种方法还是第二种方法?民众的意见是什么?
I am near the end of a new ASP.NET MVC application I have been developing, and I have realised that I am not 100% on what should be goning on in my controller methods.
Is it better for an action method to decide which services/methods are called and in what order like so:
AccountService _accountService;
BillingService _billingService;
InvoiceService _invoiceService;
...
public ActionResult UpgradeAccountPackage(PackageType packageType, int accountId)
{
_accountService.UpgradeAccountPackage(packageType, accountId);
_billingService.BillForAccountUpgrade(packageType, accountId);
_invoiceService.CreateAccountUpgradeInvoice(packageType, accountId);
}
Or is it better to stick to a single method call to one service and allow this method to call the other services/support method it needs?
public ActionResult UpgradeAccountPackage(PackageType packageType, int accountId)
{
// account service upgrades account then calls the BillingService and InvoicService
// methods called above within this method
_accountService.UpgradeAccountPackage(packageType, accountId);
}
I have tended to go for the second example here, as it seemed originally like the first method would constitute logic in some way, and means the acion method would have to intrinsically know about how the account upgrade process works within my application, which seems like a bad thing.
However, now my application is almost finished it has a large service layer and this approach has led to almost every service having a strong dependency on numerous other services, and there is no centralised place which decides the flow of business transactions such as the one mentioned above, you have to dig around a bit in service methods to discover the processes.
I am considering refactoring to more closesly resemble the second method above, or introducing a new layer in between the controller and service layer which controls the flow of processes.
Do people tend to use the first or second method? What are peoples opinions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我更喜欢第二种方法 - 更容易测试(使用模拟),并且逻辑可供重用。您最终会得到实际业务逻辑的外观,但这并不是坏事。
我不明白为什么你的服务层充满了具体的依赖关系......
要记住的是你希望类依赖于接口,而不是实现。 (然后使用依赖注入工具将其全部串在一起)
在 C# 中,我们可以让一个类实现多个接口。因此,您的服务实现可以实现许多接口,而调用者只需要知道他们需要的部分。
例如,您可能有一个实现
IDepositor
和IWithdrawer
的AccountTransactionService
。如果您实现复式记账,那么这可能取决于IDepositor
和IWithdrawer
,实际上,它们仅使用相同的AccountTransactionService
实例>,但不是必须的,并且实现细节可以在之后更改。一般来说,一个类对系统中其他类的了解越少越好。
I prefer the second method - much easier to test (using mocks), and the logic is there for reuse. You end up with Facades to your actual business logic, but that's not bad thing.
I don't understand why your service layer is full of concrete dependencies though...
The thing to remember is that you want classes to rely on interfaces, not implementation. (and then string it all together with a Dependancy Injection tool)
In C#, we can have one class implement many interfaces. So your service implementations can implement many interface, and yet the caller need only know about the part they need.
For example, you might have an
AccountTransactionService
that imlpementsIDepositor
andIWithdrawer
. If you implement double-entry accounting, then that could depend onIDepositor
andIWithdrawer
, which, in actual fact, just uses the same instance ofAccountTransactionService
, but it doesn't have to, and the implementation details could be changed afterwards.In general, the less one class knows about the other classes in the system, the better.
我更密切地使用第一种方法。让控制器控制发生的事情。让服务来决定如何发生。
如果您添加第二层来控制流程流,您的 ActionMethods 是否只会进行一次调用?如果是这样,那么此时看来就没有必要了。
I more closely use the first method. Let the controller control what happens. Let the services decide how that happens.
If you add a second layer to control the flow of processes would that leave your ActionMethods only making the one call? If so, it seems unnecessary at that point.
您可以拥有一个依赖于多个存储库(而不是其他服务)并定义业务操作的服务层:
然后让您的控制器将
IMyService
作为依赖项:我使用存储库和服务将这些多个操作聚合到一个业务事务中。
You could have a service layer which depends on multiple repositories (not other services) and which defines the business operations:
and then have your controller take
IMyService
as dependency:I define simple CRUD operations with the entities on the repositories and the service aggregates those multiple operations into one business transaction.