How to get an 'MvcApplication' instance in ASP.NET controller?

后端 未结 3 1581
夕颜
夕颜 2021-02-02 10:52

I think MvcApplication is a global singleton. I want to get the instance of MvcApplication in the controller. Then I put the following code in controll

相关标签:
3条回答
  • 2021-02-02 11:29

    Try this:

    var app = HttpContext.Current.ApplicationInstance as MvcApplication;
    
    0 讨论(0)
  • 2021-02-02 11:32

    I believe the reason why the original code didn't work is because HttpContext is both a property of Controller and its own class. Within a subclass of Controller, HttpContext will resolve to the property and produce the error mentioned. To get around it, explicitly reference the HttpContext class with it's fully qualified name:

    System.Web.HttpContext.Current.Application
    

    Or, since the HttpContext property already returns the current HttpContext instance, you could use:

    HttpContext.Application
    
    0 讨论(0)
  • 2021-02-02 11:50

    MvcApplication != singleton

    which means that all answers above miss the point and will get you into serious trouble if you wrongly believe to access the same instance while in fact there will be several.

    Your very first assumption is not valid: Contrary to (very - just see the other answers here as a proof) widespread belief, MvcApplication is NOT a global singleton. The class is instantiated several times, one instance per "pipeline", so the performance counter "pipeline instance count" tells you how many instances of MvcApplication are currently consdidered alive. Add a default ctor and prove this yourself:

    public MvcApplication()
    {
        Trace.WriteLine(this.GetHashCode());
    }
    

    Debug break the line or watch the various hash codes in DebugViewer. To force pipeline instance count going up create a method with Thread.Sleep(5000), Asp.Net will then fire up a new instance once you make another http request in parallel.

    Solution - How to instantiate singletons in Asp.Net applications (MVC or WebForms)

    If your MvcApplication class however has an Application_Start() method then this method is called in fact only once, process wide. You can set static fields there. Simply put them to any class, typically MvcApplication is a good conventional choice, and access them. Like

    MvcApplication.MySingleValue = 72;
    MvcApplication.ActivePlayersCount = 3400;
    var n = MvcApplication.ActivePlayersCount;
    ...
    

    HttpApplication weirdness

    The design of the HttpApplication class and its events is quite strange, which presumably has its reason in some loose sort of backwards design compatibility to very old COM based ASP pages. There the application object was in fact created only once, which is surely the origin of the wrong belief related to Asp.Net. An example of the HttpApplication strangeness:

    protected void Application_Start()
    {
    }
    

    Note that there is no override involved!

    In summary, the application instances might be of minor interest most of the time, I can see no scenario were it could become relevant to hold state, as its state would be shared by an arbitrary subset of requests handled. So accessing it in the completely fine way as mentioned by Matt might not be required too often.

    0 讨论(0)
提交回复
热议问题