c# - 我应该将服务注入(inject)到我的 MVC View 中吗?

标签 c# asp.net-mvc dependency-injection

我们正在使用 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/

相关文章:

c# - 如何在窗口标题栏顶部显示菜单

c# - 何时在 UI 应用程序中调用 SynchronizationContext.SetSynchronizationContext()?

c# - 从分钟转换为毫秒,然后转换为 Int

c# - 从数据存储中检索 key (更新和删除实体)

javascript - 如何在下拉列表更改时自动点击ActionLink?

azure - 依赖注入(inject)容器是否在同一个包中的 azure 函数之间共享?

c# - Nexus 和为 .NET 应用程序上传工件

html - Resharper intellisense 建议 MVC 6 中的错误路径

javascript - 在初始化时运行程序

java - 如何让 Google Guice 自动检测绑定(bind)?