zoukankan      html  css  js  c++  java
  • 【转】ASP.NET MVC 3 Service Location, Part 3: View Engines/View Pages

    Important Update

    We've made significant changes to the IoC support in ASP.NET MVC 3 Beta. Please read Part 5 for more information.

    View Engine Registration and View Page Creation

    ASP.NET MVC 1.0 introduced View Engines (implementing IViewEngine and IView), shipping with the single WebForms-based view engine. Views, master pages, and partial views in WebForms view engine need to derive from ViewPage,ViewMasterPage, and ViewUserControl (respectively). In MVC 3, we've introduced new dependency injection points for all of these classes (plus the new base class for Razor views, WebViewPage).

    Update: (31 July 2010) I've added the source code for UnityMvcServiceLocator to the end of part 2.

    Disclaimer

    This blog post talks about ASP.NET MVC 3 Preview 1, which is a pre-release version. Specific technical details may change before the final release of MVC 3. This release is designed to elicit feedback on features with enough time to make meaningful changes before MVC 3 ships, so please comment on this blog post or contact me if you have comments.

    Location: View Engines

    This is a "multiply registered" style service introduced in MVC 1.0. A view engine is registered with theViewEngines.Engines static collection. Order is important with view engines, as the collection facade will ask each view engine in order to render the view; the first one that says it can render it will win.

    With MVC 3, we have updated the ViewEngineCollection facade methods (FindView and FindPartialView) to look in both the static registered view engines as well as the view engines it finds in the service locator. To find those view engines, it calls MvcServiceLocator.Current.GetAllInstance<IViewEngine>().

    The following is an example of registering a view engine, using Microsoft Unity as the dependency injection container:

    MyViewEngine.cs

    public class MyViewEngine : IViewEngine {
    
        // ... implementation of IViewEngine ...
    
    }

    Global.asax.cs

    protected void Application_Start() {
        // ...
    
        var container = new UnityContainer();
        container.RegisterType<IViewEngine, MyViewEngine>("MyViewEngine");
        MvcServiceLocator.SetCurrent(new UnityMvcServiceLocator(container));
    
        // ...
    }

    Now when the system resolves views by call FindView and FindPartialView, it will use your view engine. Any view engines the system finds in the service locator will come before any view engines registered with the static registration function. If your container supports explicit ordering, the view engines will be used in the order returned by the service locator.

    Location: View Pages

    View engines are ultimately responsible for rendering their views. In the case of the WebForms and Razor view engines, this takes the form of classes which are automatically generated from the source of the view (for example, an .aspx file or a .cshtml file). These classes implicit inherit base classes that the view engine is dependent upon (ViewPage, ViewMasterPage, ViewUserControl, or WebViewPage).

    Historically, these classes have not had access to dependency injection/service location functionality, because their creation was buried deep inside the implementation of the view engine. In MVC 3, we have updated the built-in view engines to attempt to create the view page classes via the service locator; if that fails, it will fall back to using Activator.CreateInstance, just like in previous versions of MVC.

    Again using Unity as our example container, let's presume we have the following code:

    InjectedViewPage.cs

    using System.Web.Mvc;
    using Microsoft.Practices.Unity;
    
    public abstract class InjectedWebViewPage : WebViewPage {
        [Dependency]
        public IMathService MathService { get; set; }
    }

    InjectedView.cshtml

    @inherits InjectedWebViewPage
    @{
        LayoutPage = "../Shared/_Layout.cshtml";
        View.Title = "Home Page";
    }
    <p>The page says 4 + 8 is @MathService.Add(4, 8).</p>

    This gives us a view page that has access to a service that's dynamically injected into the base class for the view page.

    Note that we're using property setter injection here rather than constructor injection, as we'd shown in our previous samples. The reason is a fairly technical one that has to do with the way the ASP.NET page compilation system works when it's converting your markup into a class. If you're curious about the specific details, please contact me. The important takeaway is that supporting dependency injection here means using some form other than constructor injection. Our example uses Unity's [Dependency] attribute to get property setter injection; the specific type of injection and how you accomplish it will depend on which service locator you're using.

    What's Next?

    The next area of service location in MVC 3 that we'll cover is Filters.

  • 相关阅读:
    个人管理:提高你的搜商
    敏捷个人:提供更多文档下载,并转载一篇敏捷个人读书笔记
    个人管理: 激励你的一句话
    敏捷个人 从Scrum实践来思考如何导入价值观
    信息系统开发平台OpenExpressApp 如何解决ComboBox.TextProperty绑定带来问题的来龙去脉
    敏捷个人 敏捷个人价值观,欢迎提出你的意见和你的价值观
    使用VS2010的CodedUI来做自己的自动化测试框架
    .Net4下的MEF(Managed Extensibility Framework) 架构简介
    IronRuby - 快速在半小时学习Ruby基础知识
    敏捷个人 项目网站文档页签增加blog链接
  • 原文地址:https://www.cnblogs.com/NickYao/p/1944802.html
Copyright © 2011-2022 走看看