欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

使用Spring.Net怎么在MVC中實(shí)現(xiàn)注入

本篇文章為大家展示了使用Spring.Net怎么在MVC中實(shí)現(xiàn)注入,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

創(chuàng)新互聯(lián)于2013年成立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站建設(shè)、成都做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢想脫穎而出為使命,1280元邊壩做網(wǎng)站,已為上家服務(wù),為邊壩各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18980820575

情景

public class HomeController : Controller
  {
    //這是一個(gè)很神奇的注入
    private IBLL.IUserInfoService UserInfoService { get; set; }
    public ActionResult Index()
    {
      return Content(UserInfoService.GetName());
    }
  }

每次看代碼都有不一樣的理解,今天我在看MVC控制器中一個(gè)通過Spring.Net依賴注入的UserInfoService屬性時(shí),突然有些疑問,注入的前提是控制反轉(zhuǎn),這么說我的Controller是從IoC容器中來的了?但是我不記得在哪個(gè)地方有配置額,對此我展開了深入的研究。

從MVC本身開始

首先我們要搞懂MVC本身是通過什么方式獲取控制器對象的,本質(zhì)如果都沒有搞懂,又何來擴(kuò)展呢?

在MVC模式下,通過實(shí)現(xiàn)IControllerFactory接口的對象來獲取當(dāng)前請求的控制器對象,實(shí)現(xiàn)IControllerFactory接口的對象也就是控制器的創(chuàng)建工廠。

簡單看下IControllerFactory

//
  // 摘要:
  //   定義控制器工廠所需的方法。
  public interface IControllerFactory
  {
    //
    // 摘要:
    //   使用指定的請求上下文來創(chuàng)建指定的控制器。
    //
    // 參數(shù):
    //  requestContext:
    //   請求上下文。
    //
    //  controllerName:
    //   控制器的名稱。
    //
    // 返回結(jié)果:
    //   控制器。
    IController CreateController(RequestContext requestContext, string controllerName);
    //
    // 摘要:
    //   獲取控制器的會(huì)話行為。
    //
    // 參數(shù):
    //  requestContext:
    //   請求上下文。
    //
    //  controllerName:
    //   你想要獲取器其會(huì)話行為的控制器的名稱。
    //
    // 返回結(jié)果:
    //   控制器的會(huì)話行為。
    SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName);
    //
    // 摘要:
    //   釋放指定的控制器。
    //
    // 參數(shù):
    //  controller:
    //   控制器。
    void ReleaseController(IController controller);
  }

一個(gè)Http請求過來,選擇哪個(gè)控制器是通過MvcHandler來處理的

控制器工廠是通過ControllerBuilder的Current屬性提供給MvcHandler使用的

下面的代碼是反編譯過來的,簡單看下即可(因?yàn)槲乙獦?biāo)記黃色高亮部分,所以沒有折疊)

internal ControllerBuilder ControllerBuilder
{
  get
  {
    if (this._controllerBuilder == null)
    {
      this._controllerBuilder = ControllerBuilder.Current;
    }
    return this._controllerBuilder;
  }
  set
  {
    this._controllerBuilder = value;
  }
}
public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState
{
  // Fields
  private ControllerBuilder _controllerBuilder;
  private static readonly object _processRequestTag;
  internal static readonly string MvcVersion;
  public static readonly string MvcVersionHeaderName;

  // Methods
  static MvcHandler();
  public MvcHandler(RequestContext requestContext);
  protected internal virtual void AddVersionHeader(HttpContextBase httpContext);
  protected virtual IAsyncResult BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, object state);
  protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state);
  protected internal virtual void EndProcessRequest(IAsyncResult asyncResult);
  private static string GetMvcVersionString();
  protected virtual void ProcessRequest(HttpContext httpContext);
  protected internal virtual void ProcessRequest(HttpContextBase httpContext);
  private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory);
  private void RemoveOptionalRoutingParameters();
  IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData);
  void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result);
  void IHttpHandler.ProcessRequest(HttpContext httpContext);

  // Properties
  internal ControllerBuilder ControllerBuilder { get; set; }
  public static bool DisableMvcResponseHeader { get; [CompilerGenerated] set; }
  protected virtual bool IsReusable { get; }
  public RequestContext RequestContext { get; [CompilerGenerated] private set; }
  bool IHttpHandler.IsReusable { get; }

  // Nested Types
  [Serializable, CompilerGenerated]
  private sealed class <>c
  {
    // Fields
    public static readonly MvcHandler.<>c <>9;
    public static BeginInvokeDelegate<MvcHandler.ProcessRequestState> <>9__20_0;
    public static EndInvokeVoidDelegate<MvcHandler.ProcessRequestState> <>9__20_1;
    public static Func<KeyValuePair<string, object>, bool> <>9__26_0;

    // Methods
    static <>c();
    public <>c();
    internal IAsyncResult <BeginProcessRequest>b__20_0(AsyncCallback asyncCallback, object asyncState, MvcHandler.ProcessRequestState innerState);
    internal void <BeginProcessRequest>b__20_1(IAsyncResult asyncResult, MvcHandler.ProcessRequestState innerState);
    internal bool <RemoveOptionalRoutingParameters>b__26_0(KeyValuePair<string, object> entry);
  }

  [StructLayout(LayoutKind.Sequential)]
  private struct ProcessRequestState
  {
    internal IAsyncController AsyncController;
    internal IControllerFactory Factory;
    internal RequestContext RequestContext;
    internal void ReleaseController();
  }
}

默認(rèn)工廠

默認(rèn)情況下,在ControllerBuilder內(nèi)部會(huì)創(chuàng)建一個(gè)DefaultControllerFactory類型的對象,以提供處理請求。

DefaultControllerFactory是實(shí)現(xiàn)IControllerFactory接口的。

//
  // 摘要:
  //   表示默認(rèn)情況下已注冊的控制器工廠。
  public class DefaultControllerFactory : IControllerFactory
  {
    //
    // 摘要:
    //   初始化 System.Web.Mvc.DefaultControllerFactory 類的新實(shí)例。
    public DefaultControllerFactory();
    //
    // 摘要:
    //   使用控制器激活器來初始化 System.Web.Mvc.DefaultControllerFactory 類的新實(shí)例。
    //
    // 參數(shù):
    //  controllerActivator:
    //   實(shí)現(xiàn)控制器激活器接口的對象。
    public DefaultControllerFactory(IControllerActivator controllerActivator);

    //
    // 摘要:
    //   使用指定的請求上下文來創(chuàng)建指定的控制器。
    //
    // 參數(shù):
    //  requestContext:
    //   HTTP 請求的上下文,其中包括 HTTP 上下文和路由數(shù)據(jù)。
    //
    //  controllerName:
    //   控制器的名稱。
    //
    // 返回結(jié)果:
    //   控制器。
    //
    // 異常:
    //  T:System.ArgumentNullException:
    //   requestContext 參數(shù)為 null。
    //
    //  T:System.ArgumentException:
    //   controllerName 參數(shù)為 null 或?yàn)榭铡?
    public virtual IController CreateController(RequestContext requestContext, string controllerName);
    //
    // 摘要:
    //   釋放指定的控制器。
    //
    // 參數(shù):
    //  controller:
    //   要釋放的控制器。
    public virtual void ReleaseController(IController controller);
    //
    // 摘要:
    //   檢索指定請求上下文和控制器類型的控制器實(shí)例。
    //
    // 參數(shù):
    //  requestContext:
    //   HTTP 請求的上下文,其中包括 HTTP 上下文和路由數(shù)據(jù)。
    //
    //  controllerType:
    //   控制器的類型。
    //
    // 返回結(jié)果:
    //   控制器實(shí)例。
    //
    // 異常:
    //  T:System.Web.HttpException:
    //   controllerType 為 null。
    //
    //  T:System.ArgumentException:
    //   無法分配 controllerType。
    //
    //  T:System.InvalidOperationException:
    //   無法創(chuàng)建 controllerType 的實(shí)例。
    protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType);
    //
    // 摘要:
    //   返回控制器的會(huì)話行為。
    //
    // 參數(shù):
    //  requestContext:
    //   請求上下文。
    //
    //  controllerType:
    //   控制器的類型。
    //
    // 返回結(jié)果:
    //   控制器的會(huì)話行為。
    protected internal virtual SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType);
    //
    // 摘要:
    //   檢索指定名稱和請求上下文的控制器類型。
    //
    // 參數(shù):
    //  requestContext:
    //   HTTP 請求的上下文,其中包括 HTTP 上下文和路由數(shù)據(jù)。
    //
    //  controllerName:
    //   控制器的名稱。
    //
    // 返回結(jié)果:
    //   控制器類型。
    protected internal virtual Type GetControllerType(RequestContext requestContext, string controllerName);
  }

默認(rèn)情況下,Controller類需要提供默認(rèn)的構(gòu)造函數(shù),因?yàn)镈efaultControllerFactory是通過反射來創(chuàng)建Controller對象實(shí)例的。

如果我們定義的Controller需要通過構(gòu)造函數(shù)創(chuàng)建,或者通過某個(gè)IoC容器管理Controller,可以通過自定義控制器工廠來實(shí)現(xiàn)。

自定義控制器工廠

為什么說這么多關(guān)于控制器工廠的東西呢,其實(shí)Spring.Net就是通過繼承DefaultControllerFactory創(chuàng)建SpringControllerFactory的。

說了這么多就是為了后面可以更容易的理解Spring.Net的控制器工廠源碼罷了。

回歸正題,接著創(chuàng)建自己的控制器工廠。

1.Home控制器內(nèi)容如下

public class HomeController : Controller
  {
    private IUserInfoService UserInfoService { get; set; }
    public HomeController(IUserInfoService userInfoService)
    {
      UserInfoService = userInfoService;
    }
    public ActionResult Index()
    {
      return Content(UserInfoService.GetName());
    }
  }

這里的UserInfoService只是一個(gè)很簡陋的測試類,只有一個(gè)GetName()方法用來返回“小明”。

接下來將通過自定義控制器工廠實(shí)現(xiàn)構(gòu)造注入U(xiǎn)serInfoService

2.創(chuàng)建控制器工廠MyControllerFactory

為了方便我直接繼承了DefaultControllerFactory,當(dāng)然也可以通過實(shí)現(xiàn)IControllerFactory來創(chuàng)建

public class MyControllerFactory : DefaultControllerFactory
  {
    private static readonly IBLL.IUserInfoService userInfoService = new BLL.UserInfoService();

    //重寫CreateController
    public override IController CreateController(RequestContext requestContext, string controllerName)
    {
      IController controller = null;
      if (controllerName == "Home")
      {
        //如果是我們制定的Home控制器則給其實(shí)例化,并通過構(gòu)造參數(shù)注入userInfoService
        controller = new HomeController(userInfoService);
      }
      else
      {
        //通過默認(rèn)控制器工廠創(chuàng)建控制器
        controller = base.CreateController(requestContext, controllerName);
      }
      return controller;
    }
  }

3.在Global.asax中注冊

protected void Application_Start()
    {
      MyControllerFactory myControllerFactory = new MyControllerFactory();
      //通過ControllerBuilder設(shè)置制定的控制器工廠
      ControllerBuilder.Current.SetControllerFactory(myControllerFactory);
      AreaRegistration.RegisterAllAreas();
      RouteConfig.RegisterRoutes(RouteTable.Routes);
    }

4.運(yùn)行測試(神奇不再神奇)

使用Spring.Net怎么在MVC中實(shí)現(xiàn)注入

意料之外,情理之中,我們并沒有在控制器中實(shí)例化,結(jié)果卻出來了

(實(shí)例化在工廠中完成了)

Spring.Net注入原理

說了這么多,回頭看看標(biāo)題“Spring.Net是怎么在MVC中實(shí)現(xiàn)注入的”,你倒是說啊,等的花都謝了,連Spring.Net的毛都沒看到.....

其實(shí),如果你是認(rèn)真讀過來的,答案在你心中應(yīng)該已經(jīng)有了。

答案如下

namespace Spring.Web.Mvc
{
  /// <summary>
  /// Controller Factory for ASP.NET MVC
  /// </summary>
  public class SpringControllerFactory : DefaultControllerFactory
  {
    private static IApplicationContext _context;

    /// <summary>
    /// Gets the application context.
    /// </summary>
    /// <value>The application context.</value>
    public static IApplicationContext ApplicationContext
    {
      get
      {
        if (_context == null || _context.Name != ApplicationContextName)
        {
          if (string.IsNullOrEmpty(ApplicationContextName))
          {
            _context = ContextRegistry.GetContext();
          }
          else
          {
            _context = ContextRegistry.GetContext(ApplicationContextName);
          }
        }

        return _context;
      }
    }

    /// <summary>
    /// Gets or sets the name of the application context.
    /// </summary>
    /// <remarks>
    /// Defaults to using the root (default) Application Context.
    /// </remarks>
    /// <value>The name of the application context.</value>
    public static string ApplicationContextName { get; set; }

    /// <summary>
    /// Creates the specified controller by using the specified request context.
    /// </summary>
    /// <param name="requestContext">The context of the HTTP request, which includes the HTTP context and route data.</param>
    /// <param name="controllerName">The name of the controller.</param>
    /// <returns>A reference to the controller.</returns>
    /// <exception cref="T:System.ArgumentNullException">The <paramref name="requestContext"/> parameter is null.</exception>
    /// <exception cref="T:System.ArgumentException">The <paramref name="controllerName"/> parameter is null or empty.</exception>
    public override IController CreateController(RequestContext requestContext, string controllerName)
    {
      IController controller;

      if (ApplicationContext.ContainsObjectDefinition(controllerName))
      {
        controller = ApplicationContext.GetObject(controllerName) as IController;
      }
      else
      {
        controller = base.CreateController(requestContext, controllerName);
      }

      AddActionInvokerTo(controller);

      return controller;
    }

    /// <summary>
    /// Retrieves the controller instance for the specified request context and controller type.
    /// </summary>
    /// <param name="requestContext">The context of the HTTP request, which includes the HTTP context and route data.</param>
    /// <param name="controllerType">The type of the controller.</param>
    /// <returns>The controller instance.</returns>
    /// <exception cref="T:System.Web.HttpException">
    ///   <paramref name="controllerType"/> is null.</exception>
    /// <exception cref="T:System.ArgumentException">
    ///   <paramref name="controllerType"/> cannot be assigned.</exception>
    /// <exception cref="T:System.InvalidOperationException">An instance of <paramref name="controllerType"/> cannot be created.</exception>
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
      IController controller = null;

      if (controllerType != null)
      {
        var controllers = ApplicationContext.GetObjectsOfType(controllerType);
        if (controllers.Count > 0)
        {
          controller = (IController)controllers.First().Value;
        }
      }

      if (controller == null)
      {
        //pass to base class for remainder of handling if can't find it in the context
        controller = base.GetControllerInstance(requestContext, controllerType);
      }
      
      AddActionInvokerTo(controller);

      return controller;
    }

    /// <summary>
    /// Adds the action invoker to the controller instance.
    /// </summary>
    /// <param name="controller">The controller.</param>
    protected virtual void AddActionInvokerTo(IController controller)
    {
      if (controller == null)
        return;

      if (typeof(Controller).IsAssignableFrom(controller.GetType()))
      {
        ((Controller)controller).ActionInvoker = new SpringActionInvoker(ApplicationContext);
      }
    }
  }
}

上述內(nèi)容就是使用Spring.Net怎么在MVC中實(shí)現(xiàn)注入,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

本文題目:使用Spring.Net怎么在MVC中實(shí)現(xiàn)注入
標(biāo)題路徑:http://chinadenli.net/article32/jiicpc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、品牌網(wǎng)站建設(shè)、定制網(wǎng)站、營銷型網(wǎng)站建設(shè)、品牌網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

綿陽服務(wù)器托管