Merge pull request #569 from knocte/fix_cairo_profile_versions_problem
[mono.git] / mcs / class / System.Web.Mvc / System.Web.Mvc / ControllerContext.cs
1 /* ****************************************************************************\r
2  *\r
3  * Copyright (c) Microsoft Corporation. All rights reserved.\r
4  *\r
5  * This software is subject to the Microsoft Public License (Ms-PL). \r
6  * A copy of the license can be found in the license.htm file included \r
7  * in this distribution.\r
8  *\r
9  * You must not remove this notice, or any other, from this software.\r
10  *\r
11  * ***************************************************************************/\r
12 \r
13 namespace System.Web.Mvc {\r
14     using System;\r
15     using System.Diagnostics.CodeAnalysis;\r
16     using System.Web;\r
17     using System.Web.Routing;\r
18 \r
19     // Though many of the properties on ControllerContext and its subclassed types are virtual, there are still sealed\r
20     // properties (like ControllerContext.RequestContext, ActionExecutingContext.Result, etc.). If these properties\r
21     // were virtual, a mocking framework might override them with incorrect behavior (property getters would return\r
22     // null, property setters would be no-ops). By sealing these properties, we are forcing them to have the default\r
23     // "get or store a value" semantics that they were intended to have.\r
24 \r
25     public class ControllerContext {\r
26 \r
27         private HttpContextBase _httpContext;\r
28         private RequestContext _requestContext;\r
29         private RouteData _routeData;\r
30 \r
31         // parameterless constructor used for mocking\r
32         public ControllerContext() {\r
33         }\r
34 \r
35         // copy constructor - allows for subclassed types to take an existing ControllerContext as a parameter\r
36         // and we'll automatically set the appropriate properties\r
37         [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",\r
38             Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]\r
39         protected ControllerContext(ControllerContext controllerContext) {\r
40             if (controllerContext == null) {\r
41                 throw new ArgumentNullException("controllerContext");\r
42             }\r
43 \r
44             Controller = controllerContext.Controller;\r
45             RequestContext = controllerContext.RequestContext;\r
46         }\r
47 \r
48         public ControllerContext(HttpContextBase httpContext, RouteData routeData, ControllerBase controller)\r
49             : this(new RequestContext(httpContext, routeData), controller) {\r
50         }\r
51 \r
52         [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",\r
53             Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]\r
54         public ControllerContext(RequestContext requestContext, ControllerBase controller) {\r
55             if (requestContext == null) {\r
56                 throw new ArgumentNullException("requestContext");\r
57             }\r
58             if (controller == null) {\r
59                 throw new ArgumentNullException("controller");\r
60             }\r
61 \r
62             RequestContext = requestContext;\r
63             Controller = controller;\r
64         }\r
65 \r
66         public virtual ControllerBase Controller {\r
67             get;\r
68             set;\r
69         }\r
70 \r
71         public virtual HttpContextBase HttpContext {\r
72             get {\r
73                 if (_httpContext == null) {\r
74                     _httpContext = (_requestContext != null) ? _requestContext.HttpContext : new EmptyHttpContext();\r
75                 }\r
76                 return _httpContext;\r
77             }\r
78             set {\r
79                 _httpContext = value;\r
80             }\r
81         }\r
82 \r
83         public RequestContext RequestContext {\r
84             get {\r
85                 if (_requestContext == null) {\r
86                     // still need explicit calls to constructors since the property getters are virtual and might return null\r
87                     HttpContextBase httpContext = HttpContext ?? new EmptyHttpContext();\r
88                     RouteData routeData = RouteData ?? new RouteData();\r
89 \r
90                     _requestContext = new RequestContext(httpContext, routeData);\r
91                 }\r
92                 return _requestContext;\r
93             }\r
94             set {\r
95                 _requestContext = value;\r
96             }\r
97         }\r
98 \r
99         public virtual RouteData RouteData {\r
100             get {\r
101                 if (_routeData == null) {\r
102                     _routeData = (_requestContext != null) ? _requestContext.RouteData : new RouteData();\r
103                 }\r
104                 return _routeData;\r
105             }\r
106             set {\r
107                 _routeData = value;\r
108             }\r
109         }\r
110 \r
111         private sealed class EmptyHttpContext : HttpContextBase {\r
112         }\r
113 \r
114     }\r
115 }\r