我们正在使用 ASP.NET MVC 技术开发某种云 CMS,并且发现了一些障碍。用户可以通过我们需要在 View 中结束的控制面板更改许多参数。例如,用于初始化 Facebook JS API 的 Facebook 应用程序 ID。或要在页面上显示的其他文本。或者背景图片。现在我们不使用 DI 来传输这些参数,而是将它们添加到 ViewModel,但这破坏了 ASP.NET MVC 处理模型的方式(例如表单验证、绑定(bind)等)
看起来使用 DI 注入(inject)服务以提供参数、文本和图片可以使我的 View 减少对特定 Controller 的依赖,甚至有一些 Microsoft 技术可以做到这一点 http://www.asp.net/mvc/tutorials/hands-on-labs/aspnet-mvc-4-dependency-injection#Exercise2 .但是,论坛上有很多反对使用 DI 将服务注入(inject) View 的答案。
所以问题是:将某些服务注入(inject) View 的正确方法是什么?或者我根本不应该这样做并且应用程序设计有问题?
更新:一些真实的代码示例(现在我们使用模型来注入(inject)服务)
从数据库中注入(inject)文本(它们必须是用户可编辑的,因为它是 CMS):
<div class="steps">@Html.Raw(Model.Texts["Main", "Step2"]</div>
从数据库注入(inject)翻译(其实就是本地化):
<div class="gonfalon">@Model.Translations["Title_Winners"]</div>
注入(inject)参数(来自数据库,可以是特定于请求的;例如,如果站点有不同的域,facebook 应用程序应该是每个域):
Facebook.Initialize(Model.Parameters["FbApplicationId"], Model.Parameters["FbApplicationSecret"]);
当前方法的问题在于此代码取自竞赛机制。处理自定义文本、翻译或 Facebook 应用程序 ID 绝对不在竞赛业务范围内。它还破坏了模型,因为模型模型不是实际的业务领域,而是处理很多实际上属于 View 的事情(比如翻译和自定义文本)
更新 2:修改了以下答案的片段,使其更通用:
public static class WebViewPageExtensions
{
public static I ResolveService<I>(this WebViewPage page)
{
return DependencyResolver.Current.GetService<I>();
}
}
最佳答案
不,您不应该将服务注入(inject) View ,但是...
对于主题化等场景,您希望为主题开发者提供更多权力,仅一种模型是不够的。例如,如果您的模型包含当前帖子,主题设计者如何要求侧边栏的类别列表?还是一个小部件?
在 asp.net mvc 中,您可以使用扩展方法来提供该功能。扩展方法将使用依赖项解析器来获取服务。这样,您可以在 View 中拥有所需的功能,而无需实际注入(inject)服务。
请注意,调用业务层更新模型仍然违反了关注点分离。 View 可用的服务应仅包含读取模型或通用实用程序功能。
一个例子
public static IMyViewServices MyServices(this WebViewPage view)
{
return DependencyResolver.Current.GetService<IMyViewServices>();
}
IMyViewServices 在 DI 容器中配置的生命周期应该是每个 http(范围)请求
关于c# - 我应该将服务注入(inject)到我的 MVC View 中吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16100917/