我在传统的webforms网站中启动MVC5应用程序,以帮助重构/替换一些非常旧的代码。在此过程中,我发现这是典型的旧webforms,它是一个巨大的类,用于管理会话中的值,SessionManager。显然这不是非常可测试的,所以我隐藏了服务背后所需的属性:
public class LegacySessionService : ISessionService
{
public IUser GetCurrentUser()
{
return SessionManager.CurrentIUser;
}
}
现在我的问题是,在另一项服务中,控制器是否可以访问会话服务并传入IUser,或让工作服务知道并访问会话服务是否更清晰?
public class MyController : Controller
{
/*skipping obvious dependency injection*/
public ActionResult DoStuff()
{
var viewModel = _someotherService.DoStuffWithIUser(_sessionService.GetCurrentUser())
return View("DoStuff", viewModel)
}
}
OR
public class SomeOtherService
{
/*skipping obvious dependency injection*/
public ViewModelClass DoStuffWithIUser()
{
var currentUser = _sessionService.GetUser();
//do more stuff, return ViewModel
}
}
哪个在架构上更正确,为什么?我不能告诉你。
答案 0 :(得分:1)
您的第二个选择是两个中的更好选择,在单一责任原则下,控制器应该关注协调模型和视图层,而不是模型层如何检索当前用户之类的信息。
你的第二个例子仍然可以改进。您的SomeOtherService假设应该从SessionService检索当前用户。如果您将来更改为从HttpContext或其他地方读取用户该怎么办?我建议创建一个ICurrentUser接口,并将其添加到SomeOtherService的构造函数中。然后,您可以创建一个名为CurrentUserFromSession的具体实现,它从SessionService读取并暂时注入。如果您更改当前用户的检索方式,则可以创建ICurrentUser的新实现,更改DI容器,而不必重新打开SomeOtherService。