真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

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

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

創(chuàng)新互聯(lián)于2013年成立,是專(zhuān)業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站建設(shè)、成都做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,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è)通過(guò)Spring.Net依賴(lài)注入的UserInfoService屬性時(shí),突然有些疑問(wèn),注入的前提是控制反轉(zhuǎn),這么說(shuō)我的Controller是從IoC容器中來(lái)的了?但是我不記得在哪個(gè)地方有配置額,對(duì)此我展開(kāi)了深入的研究。

從MVC本身開(kāi)始

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

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

簡(jiǎn)單看下IControllerFactory

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

一個(gè)Http請(qǐng)求過(guò)來(lái),選擇哪個(gè)控制器是通過(guò)MvcHandler來(lái)處理的

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

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

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 <>9__20_0;
    public static EndInvokeVoidDelegate <>9__20_1;
    public static Func, bool> <>9__26_0;

    // Methods
    static <>c();
    public <>c();
    internal IAsyncResult b__20_0(AsyncCallback asyncCallback, object asyncState, MvcHandler.ProcessRequestState innerState);
    internal void b__20_1(IAsyncResult asyncResult, MvcHandler.ProcessRequestState innerState);
    internal bool b__26_0(KeyValuePair 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類(lèi)型的對(duì)象,以提供處理請(qǐng)求。

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

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

    //
    // 摘要:
    //   使用指定的請(qǐng)求上下文來(lái)創(chuàng)建指定的控制器。
    //
    // 參數(shù):
    //  requestContext:
    //   HTTP 請(qǐng)求的上下文,其中包括 HTTP 上下文和路由數(shù)據(jù)。
    //
    //  controllerName:
    //   控制器的名稱(chēng)。
    //
    // 返回結(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);
    //
    // 摘要:
    //   檢索指定請(qǐng)求上下文和控制器類(lèi)型的控制器實(shí)例。
    //
    // 參數(shù):
    //  requestContext:
    //   HTTP 請(qǐng)求的上下文,其中包括 HTTP 上下文和路由數(shù)據(jù)。
    //
    //  controllerType:
    //   控制器的類(lèi)型。
    //
    // 返回結(jié)果:
    //   控制器實(shí)例。
    //
    // 異常:
    //  T:System.Web.HttpException:
    //   controllerType 為 null。
    //
    //  T:System.ArgumentException:
    //   無(wú)法分配 controllerType。
    //
    //  T:System.InvalidOperationException:
    //   無(wú)法創(chuàng)建 controllerType 的實(shí)例。
    protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType);
    //
    // 摘要:
    //   返回控制器的會(huì)話行為。
    //
    // 參數(shù):
    //  requestContext:
    //   請(qǐng)求上下文。
    //
    //  controllerType:
    //   控制器的類(lèi)型。
    //
    // 返回結(jié)果:
    //   控制器的會(huì)話行為。
    protected internal virtual SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType);
    //
    // 摘要:
    //   檢索指定名稱(chēng)和請(qǐng)求上下文的控制器類(lèi)型。
    //
    // 參數(shù):
    //  requestContext:
    //   HTTP 請(qǐng)求的上下文,其中包括 HTTP 上下文和路由數(shù)據(jù)。
    //
    //  controllerName:
    //   控制器的名稱(chēng)。
    //
    // 返回結(jié)果:
    //   控制器類(lèi)型。
    protected internal virtual Type GetControllerType(RequestContext requestContext, string controllerName);
  }

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

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

自定義控制器工廠

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

說(shuō)了這么多就是為了后面可以更容易的理解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è)很簡(jiǎn)陋的測(cè)試類(lèi),只有一個(gè)GetName()方法用來(lái)返回“小明”。

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

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

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

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

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

3.在Global.asax中注冊(cè)

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

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

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

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

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

Spring.Net注入原理

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

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

答案如下

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

    /// 
    /// Gets the application context.
    /// 
    /// The application context.
    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;
      }
    }

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

    /// 
    /// Creates the specified controller by using the specified request context.
    /// 
    /// The context of the HTTP request, which includes the HTTP context and route data.
    /// The name of the controller.
    /// A reference to the controller.
    /// The  parameter is null.
    /// The  parameter is null or empty.
    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;
    }

    /// 
    /// Retrieves the controller instance for the specified request context and controller type.
    /// 
    /// The context of the HTTP request, which includes the HTTP context and route data.
    /// The type of the controller.
    /// The controller instance.
    /// 
    ///    is null.
    /// 
    ///    cannot be assigned.
    /// An instance of  cannot be created.
    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;
    }

    /// 
    /// Adds the action invoker to the controller instance.
    /// 
    /// The controller.
    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é)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


標(biāo)題名稱(chēng):使用Spring.Net怎么在MVC中實(shí)現(xiàn)注入
轉(zhuǎn)載來(lái)于:http://weahome.cn/article/jiicpc.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部