Adding support for ActivateAttribute via IControllerActivator
This mechanism replaces code in Inject that activated properties by looking them up by names.
This commit is contained in:
parent
6ae02b0321
commit
cca78bb055
13
Mvc.sln
13
Mvc.sln
|
|
@ -37,6 +37,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Functi
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "BasicWebSite", "test\WebSites\BasicWebSite\BasicWebSite.kproj", "{34DF1487-12C6-476C-BE0A-F31DF1939AE5}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ActivatorWebSite", "test\WebSites\ActivatorWebSite\ActivatorWebSite.kproj", "{DB79BCBA-9538-4A53-87D9-77728E2BAA39}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "InlineConstraintsWebSite", "test\WebSites\InlineConstraintsWebSite\InlineConstraintsWebSite.kproj", "{EA34877F-1AC1-42B7-B4E6-15A093F40CAE}"
|
||||
EndProject
|
||||
Global
|
||||
|
|
@ -179,6 +181,16 @@ Global
|
|||
{34DF1487-12C6-476C-BE0A-F31DF1939AE5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{34DF1487-12C6-476C-BE0A-F31DF1939AE5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{34DF1487-12C6-476C-BE0A-F31DF1939AE5}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{DB79BCBA-9538-4A53-87D9-77728E2BAA39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DB79BCBA-9538-4A53-87D9-77728E2BAA39}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DB79BCBA-9538-4A53-87D9-77728E2BAA39}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{DB79BCBA-9538-4A53-87D9-77728E2BAA39}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{DB79BCBA-9538-4A53-87D9-77728E2BAA39}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{DB79BCBA-9538-4A53-87D9-77728E2BAA39}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DB79BCBA-9538-4A53-87D9-77728E2BAA39}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DB79BCBA-9538-4A53-87D9-77728E2BAA39}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{DB79BCBA-9538-4A53-87D9-77728E2BAA39}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{DB79BCBA-9538-4A53-87D9-77728E2BAA39}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{EA34877F-1AC1-42B7-B4E6-15A093F40CAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EA34877F-1AC1-42B7-B4E6-15A093F40CAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EA34877F-1AC1-42B7-B4E6-15A093F40CAE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
|
|
@ -208,6 +220,7 @@ Global
|
|||
{16703B76-C9F7-4C75-AE6C-53D92E308E3C} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||
{323D0C04-B518-4A8F-8A8E-3546AD153D34} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||
{34DF1487-12C6-476C-BE0A-F31DF1939AE5} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{DB79BCBA-9538-4A53-87D9-77728E2BAA39} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{EA34877F-1AC1-42B7-B4E6-15A093F40CAE} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -8,15 +8,12 @@ namespace MvcSample.Web.RandomNameSpace
|
|||
{
|
||||
private User _user = new User() { Name = "User Name", Address = "Home Address" };
|
||||
|
||||
public HttpContext Context
|
||||
[Activate]
|
||||
public HttpResponse Response
|
||||
{
|
||||
get
|
||||
{
|
||||
return ActionContext.HttpContext;
|
||||
}
|
||||
get; set;
|
||||
}
|
||||
|
||||
// The property ActionContext gets injected by InitializeController from DefaultControllerFactory.
|
||||
public ActionContext ActionContext { get; set; }
|
||||
|
||||
public string Index()
|
||||
|
|
@ -42,7 +39,7 @@ namespace MvcSample.Web.RandomNameSpace
|
|||
|
||||
public void Raw()
|
||||
{
|
||||
Context.Response.WriteAsync("Hello World raw");
|
||||
Response.WriteAsync("Hello World raw");
|
||||
}
|
||||
|
||||
public ActionResult UserJson()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies that a property or parameter value should be initialized via the dependency injection
|
||||
/// container for activated types.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false)]
|
||||
public sealed class ActivateAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -15,15 +15,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
public class Controller : IActionFilter, IAsyncActionFilter
|
||||
{
|
||||
private DynamicViewData _viewBag;
|
||||
private IServiceProvider _serviceProvider;
|
||||
private IViewEngine _viewEngine;
|
||||
|
||||
[NonAction]
|
||||
public virtual void Initialize(IServiceProvider serviceProvider, IViewEngine viewEngine)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_viewEngine = viewEngine;
|
||||
}
|
||||
|
||||
public HttpContext Context
|
||||
{
|
||||
|
|
@ -41,8 +32,16 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
[Activate]
|
||||
public ActionContext ActionContext { get; set; }
|
||||
|
||||
[Activate]
|
||||
public IServiceProvider ServiceProvider { get; set; }
|
||||
|
||||
[Activate]
|
||||
public IViewEngine ViewEngine { get; set; }
|
||||
|
||||
[Activate]
|
||||
public IUrlHelper Url { get; set; }
|
||||
|
||||
public IPrincipal User
|
||||
|
|
@ -58,6 +57,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
[Activate]
|
||||
public ViewDataDictionary ViewData { get; set; }
|
||||
|
||||
public dynamic ViewBag
|
||||
|
|
@ -122,7 +122,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
ViewData.Model = model;
|
||||
}
|
||||
|
||||
return new ViewResult(_serviceProvider, _viewEngine)
|
||||
return new ViewResult(ServiceProvider, ViewEngine)
|
||||
{
|
||||
ViewName = viewName,
|
||||
ViewData = ViewData,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.Core;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the <see cref="IControllerActivator"/> that is registered by default.
|
||||
/// </summary>
|
||||
public class DefaultControllerActivator : IControllerActivator
|
||||
{
|
||||
private readonly Func<Type, PropertyActivator[]> _getPropertiesToActivate;
|
||||
private readonly Func<PropertyInfo, PropertyActivator> _createActivateInfo;
|
||||
private readonly ReadOnlyDictionary<Type, Func<ActionContext, object>> _valueAccessorLookup;
|
||||
private readonly ConcurrentDictionary<Type, PropertyActivator[]> _injectActions;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the DefaultControllerActivator class.
|
||||
/// </summary>
|
||||
public DefaultControllerActivator()
|
||||
{
|
||||
_valueAccessorLookup = CreateValueAccessorLookup();
|
||||
_getPropertiesToActivate = GetPropertiesToActivate;
|
||||
_createActivateInfo = CreateActivateInfo;
|
||||
_injectActions = new ConcurrentDictionary<Type, PropertyActivator[]>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Activates the specified controller by using the specified action context.
|
||||
/// </summary>
|
||||
/// <param name="controller">The controller to activate.</param>
|
||||
/// <param name="context">The context of the executing action.</param>
|
||||
public void Activate([NotNull] object controller, [NotNull] ActionContext context)
|
||||
{
|
||||
var controllerType = controller.GetType();
|
||||
var controllerTypeInfo = controllerType.GetTypeInfo();
|
||||
if (controllerTypeInfo.IsValueType)
|
||||
{
|
||||
var message = Resources.FormatValueTypesCannotBeActivated(GetType().FullName);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
var propertiesToActivate = _injectActions.GetOrAdd(controllerType,
|
||||
_getPropertiesToActivate);
|
||||
|
||||
for (var i = 0; i < propertiesToActivate.Length; i++)
|
||||
{
|
||||
var activateInfo = propertiesToActivate[i];
|
||||
activateInfo.Activate(controller, context);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual ReadOnlyDictionary<Type, Func<ActionContext, object>> CreateValueAccessorLookup()
|
||||
{
|
||||
var dictionary = new Dictionary<Type, Func<ActionContext, object>>
|
||||
{
|
||||
{ typeof(ActionContext), (context) => context },
|
||||
{ typeof(HttpContext), (context) => context.HttpContext },
|
||||
{ typeof(HttpRequest), (context) => context.HttpContext.Request },
|
||||
{ typeof(HttpResponse), (context) => context.HttpContext.Response },
|
||||
{
|
||||
typeof(ViewDataDictionary),
|
||||
(context) =>
|
||||
{
|
||||
var serviceProvider = context.HttpContext.RequestServices;
|
||||
return new ViewDataDictionary(
|
||||
serviceProvider.GetService<IModelMetadataProvider>(),
|
||||
context.ModelState);
|
||||
}
|
||||
}
|
||||
};
|
||||
return new ReadOnlyDictionary<Type, Func<ActionContext, object>>(dictionary);
|
||||
}
|
||||
|
||||
private PropertyActivator[] GetPropertiesToActivate(Type controllerType)
|
||||
{
|
||||
var bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
|
||||
return controllerType.GetProperties(bindingFlags)
|
||||
.Where(property => property.IsDefined(typeof(ActivateAttribute)) &&
|
||||
property.GetSetMethod(nonPublic: true) != null)
|
||||
.Select(_createActivateInfo)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private PropertyActivator CreateActivateInfo(PropertyInfo property)
|
||||
{
|
||||
Func<ActionContext, object> valueAccessor;
|
||||
if (!_valueAccessorLookup.TryGetValue(property.PropertyType, out valueAccessor))
|
||||
{
|
||||
valueAccessor = (actionContext) =>
|
||||
{
|
||||
var serviceProvider = actionContext.HttpContext.RequestServices;
|
||||
return serviceProvider.GetService(property.PropertyType);
|
||||
};
|
||||
}
|
||||
|
||||
return new PropertyActivator(property,
|
||||
valueAccessor);
|
||||
}
|
||||
|
||||
private sealed class PropertyActivator
|
||||
{
|
||||
private readonly PropertyInfo _propertyInfo;
|
||||
private readonly Func<ActionContext, object> _valueAccessor;
|
||||
private readonly Action<object, object> _fastPropertySetter;
|
||||
|
||||
public PropertyActivator(PropertyInfo propertyInfo,
|
||||
Func<ActionContext, object> valueAccessor)
|
||||
{
|
||||
_propertyInfo = propertyInfo;
|
||||
_valueAccessor = valueAccessor;
|
||||
_fastPropertySetter = PropertyHelper.MakeFastPropertySetter(propertyInfo);
|
||||
}
|
||||
|
||||
public void Activate(object instance, ActionContext context)
|
||||
{
|
||||
var value = _valueAccessor(context);
|
||||
_fastPropertySetter(instance, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,20 +3,23 @@
|
|||
|
||||
using System;
|
||||
using Microsoft.AspNet.Mvc.Core;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public class DefaultControllerFactory : IControllerFactory
|
||||
{
|
||||
private readonly ITypeActivator _activator;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ITypeActivator _typeActivator;
|
||||
private readonly IControllerActivator _controllerActivator;
|
||||
|
||||
public DefaultControllerFactory(IServiceProvider serviceProvider, ITypeActivator activator)
|
||||
public DefaultControllerFactory(IServiceProvider serviceProvider,
|
||||
ITypeActivator typeActivator,
|
||||
IControllerActivator controllerActivator)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_activator = activator;
|
||||
_typeActivator = typeActivator;
|
||||
_controllerActivator = controllerActivator;
|
||||
}
|
||||
|
||||
public object CreateController(ActionContext actionContext)
|
||||
|
|
@ -30,11 +33,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
"actionContext");
|
||||
}
|
||||
|
||||
var controller = _activator.CreateInstance(
|
||||
var controller = _typeActivator.CreateInstance(
|
||||
_serviceProvider,
|
||||
actionDescriptor.ControllerDescriptor.ControllerTypeInfo.AsType());
|
||||
|
||||
InitializeController(controller, actionContext);
|
||||
actionContext.Controller = controller;
|
||||
_controllerActivator.Activate(controller, actionContext);
|
||||
|
||||
return controller;
|
||||
}
|
||||
|
|
@ -48,20 +52,5 @@ namespace Microsoft.AspNet.Mvc
|
|||
disposableController.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeController(object controller, ActionContext actionContext)
|
||||
{
|
||||
Injector.InjectProperty(controller, "ActionContext", actionContext);
|
||||
|
||||
var viewData = new ViewDataDictionary(
|
||||
_serviceProvider.GetService<IModelMetadataProvider>(),
|
||||
actionContext.ModelState);
|
||||
Injector.InjectProperty(controller, "ViewData", viewData);
|
||||
|
||||
var urlHelper = _serviceProvider.GetService<IUrlHelper>();
|
||||
Injector.InjectProperty(controller, "Url", urlHelper);
|
||||
|
||||
Injector.CallInitializer(controller, _serviceProvider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods to activate an instantiated controller.
|
||||
/// </summary>
|
||||
public interface IControllerActivator
|
||||
{
|
||||
/// <summary>
|
||||
/// When implemented in a type, activates an instantiated controller.
|
||||
/// </summary>
|
||||
/// <param name="controller">The controller to activate.</param>
|
||||
/// <param name="context">The <see cref="ActionContext"/> for the executing action.</param>
|
||||
void Activate(object controller, ActionContext context);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
|
@ -21,6 +20,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
private static readonly MethodInfo CallPropertyGetterByReferenceOpenGenericMethod =
|
||||
typeof(PropertyHelper).GetTypeInfo().GetDeclaredMethod("CallPropertyGetterByReference");
|
||||
|
||||
private static readonly MethodInfo CallPropertySetterOpenGenericMethod =
|
||||
typeof(PropertyHelper).GetTypeInfo().GetDeclaredMethod("CallPropertySetter");
|
||||
|
||||
private static readonly ConcurrentDictionary<Type, PropertyHelper[]> ReflectionCache =
|
||||
new ConcurrentDictionary<Type, PropertyHelper[]>();
|
||||
|
||||
|
|
@ -109,6 +111,45 @@ namespace Microsoft.AspNet.Mvc
|
|||
return (Func<object, object>)callPropertyGetterDelegate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a single fast property setter for reference types. The result is not cached.
|
||||
/// </summary>
|
||||
/// <param name="propertyInfo">propertyInfo to extract the setter for.</param>
|
||||
/// <returns>a fast getter.</returns>
|
||||
/// <remarks>
|
||||
/// This method is more memory efficient than a dynamically compiled lambda, and about the
|
||||
/// same speed. This only works for reference types.
|
||||
/// </remarks>
|
||||
public static Action<object, object> MakeFastPropertySetter(PropertyInfo propertyInfo)
|
||||
{
|
||||
Contract.Assert(propertyInfo != null);
|
||||
Contract.Assert(!propertyInfo.DeclaringType.GetTypeInfo().IsValueType);
|
||||
|
||||
var setMethod = propertyInfo.SetMethod;
|
||||
Contract.Assert(setMethod != null);
|
||||
Contract.Assert(!setMethod.IsStatic);
|
||||
Contract.Assert(setMethod.ReturnType == typeof(void));
|
||||
var parameters = setMethod.GetParameters();
|
||||
Contract.Assert(parameters.Length == 1);
|
||||
|
||||
// Instance methods in the CLR can be turned into static methods where the first parameter
|
||||
// is open over "target". This parameter is always passed by reference, so we have a code
|
||||
// path for value types and a code path for reference types.
|
||||
var typeInput = setMethod.DeclaringType;
|
||||
var parameterType = parameters[0].ParameterType;
|
||||
|
||||
// Create a delegate TDeclaringType -> { TDeclaringType.Property = TValue; }
|
||||
var propertySetterAsAction =
|
||||
setMethod.CreateDelegate(typeof(Action<,>).MakeGenericType(typeInput, parameterType));
|
||||
var callPropertySetterClosedGenericMethod =
|
||||
CallPropertySetterOpenGenericMethod.MakeGenericMethod(typeInput, parameterType);
|
||||
var callPropertySetterDelegate =
|
||||
callPropertySetterClosedGenericMethod.CreateDelegate(
|
||||
typeof(Action<object, object>), propertySetterAsAction);
|
||||
|
||||
return (Action<object, object>)callPropertySetterDelegate;
|
||||
}
|
||||
|
||||
private static PropertyHelper CreateInstance(PropertyInfo property)
|
||||
{
|
||||
return new PropertyHelper(property);
|
||||
|
|
@ -131,6 +172,14 @@ namespace Microsoft.AspNet.Mvc
|
|||
return getter(ref unboxed);
|
||||
}
|
||||
|
||||
private static void CallPropertySetter<TDeclaringType, TValue>(
|
||||
Action<TDeclaringType, TValue> setter,
|
||||
object target,
|
||||
object value)
|
||||
{
|
||||
setter((TDeclaringType)target, (TValue)value);
|
||||
}
|
||||
|
||||
protected static PropertyHelper[] GetProperties(
|
||||
object instance,
|
||||
Func<PropertyInfo, PropertyHelper> createPropertyHelper,
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
<Compile Include="ActionResults\RedirectToActionResult.cs" />
|
||||
<Compile Include="ActionResults\RedirectToRouteResult.cs" />
|
||||
<Compile Include="ActionResults\ViewResult.cs" />
|
||||
<Compile Include="ActivateAttribute.cs" />
|
||||
<Compile Include="AntiForgery\AntiForgery.cs" />
|
||||
<Compile Include="AntiForgery\AntiForgeryOptions.cs" />
|
||||
<Compile Include="AntiForgery\AntiForgeryToken.cs" />
|
||||
|
|
@ -130,7 +131,9 @@
|
|||
<Compile Include="IActionInvokerProvider.cs" />
|
||||
<Compile Include="IActionResult.cs" />
|
||||
<Compile Include="IActionSelector.cs" />
|
||||
<Compile Include="IControllerActivator.cs" />
|
||||
<Compile Include="IControllerAssemblyProvider.cs" />
|
||||
<Compile Include="DefaultControllerActivator.cs" />
|
||||
<Compile Include="IControllerFactory.cs" />
|
||||
<Compile Include="Injector.cs" />
|
||||
<Compile Include="Internal\PropertyHelper.cs" />
|
||||
|
|
|
|||
|
|
@ -1018,6 +1018,22 @@ namespace Microsoft.AspNet.Mvc.Core
|
|||
return string.Format(CultureInfo.CurrentCulture, GetString("ActionResult_ActionReturnValueCannotBeNull"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Value types cannot be activated by '{0}'.
|
||||
/// </summary>
|
||||
internal static string ValueTypesCannotBeActivated
|
||||
{
|
||||
get { return GetString("ValueTypesCannotBeActivated"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Value types cannot be activated by '{0}'.
|
||||
/// </summary>
|
||||
internal static string FormatValueTypesCannotBeActivated(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("ValueTypesCannotBeActivated"), p0);
|
||||
}
|
||||
|
||||
private static string GetString(string name, params string[] formatterNames)
|
||||
{
|
||||
var value = _resourceManager.GetString(name);
|
||||
|
|
|
|||
|
|
@ -8,20 +8,17 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
public class ReflectedActionInvokerProvider : IActionInvokerProvider
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IControllerFactory _controllerFactory;
|
||||
private readonly IActionBindingContextProvider _bindingProvider;
|
||||
private readonly INestedProviderManager<FilterProviderContext> _filterProvider;
|
||||
|
||||
public ReflectedActionInvokerProvider(IControllerFactory controllerFactory,
|
||||
IActionBindingContextProvider bindingProvider,
|
||||
INestedProviderManager<FilterProviderContext> filterProvider,
|
||||
IServiceProvider serviceProvider)
|
||||
INestedProviderManager<FilterProviderContext> filterProvider)
|
||||
{
|
||||
_controllerFactory = controllerFactory;
|
||||
_bindingProvider = bindingProvider;
|
||||
_filterProvider = filterProvider;
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public int Order
|
||||
|
|
|
|||
|
|
@ -306,4 +306,7 @@
|
|||
<data name="ActionResult_ActionReturnValueCannotBeNull" xml:space="preserve">
|
||||
<value>Cannot return null from an action method with a return type of '{0}'.</value>
|
||||
</data>
|
||||
<data name="ValueTypesCannotBeActivated" xml:space="preserve">
|
||||
<value>Value types cannot be activated by '{0}'.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -26,6 +26,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var describe = new ServiceDescriber(configuration);
|
||||
|
||||
yield return describe.Transient<IControllerFactory, DefaultControllerFactory>();
|
||||
yield return describe.Singleton<IControllerActivator, DefaultControllerActivator>();
|
||||
yield return describe.Scoped<IActionSelector, DefaultActionSelector>();
|
||||
yield return describe.Transient<IActionInvokerFactory, ActionInvokerFactory>();
|
||||
yield return describe.Transient<IControllerAssemblyProvider, DefaultControllerAssemblyProvider>();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,151 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#if NET45
|
||||
using System;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Core.Test
|
||||
{
|
||||
public class DefaultControllerActivatorTest
|
||||
{
|
||||
[Fact]
|
||||
public void Activate_SetsPropertiesFromActionContextHierarchy()
|
||||
{
|
||||
// Arrange
|
||||
var httpRequest = Mock.Of<HttpRequest>();
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
httpContext.SetupGet(c => c.Request)
|
||||
.Returns(httpRequest);
|
||||
httpContext.SetupGet(c => c.RequestServices)
|
||||
.Returns(Mock.Of<IServiceProvider>());
|
||||
var routeContext = new RouteContext(httpContext.Object);
|
||||
var controller = new TestController();
|
||||
var context = new ActionContext(routeContext, new ActionDescriptor())
|
||||
{
|
||||
Controller = controller
|
||||
};
|
||||
var activator = new DefaultControllerActivator();
|
||||
|
||||
// Act
|
||||
activator.Activate(controller, context);
|
||||
|
||||
// Assert
|
||||
Assert.Same(context, controller.ActionContext);
|
||||
Assert.Same(httpContext.Object, controller.HttpContext);
|
||||
Assert.Same(httpRequest, controller.GetHttpRequest());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Activate_SetsViewDatDictionary()
|
||||
{
|
||||
// Arrange
|
||||
var service = new Mock<IServiceProvider>();
|
||||
service.Setup(s => s.GetService(typeof(IModelMetadataProvider)))
|
||||
.Returns(Mock.Of<IModelMetadataProvider>());
|
||||
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
httpContext.SetupGet(c => c.RequestServices)
|
||||
.Returns(service.Object);
|
||||
var routeContext = new RouteContext(httpContext.Object);
|
||||
var controller = new TestController();
|
||||
var context = new ActionContext(routeContext, new ActionDescriptor())
|
||||
{
|
||||
Controller = controller
|
||||
};
|
||||
var activator = new DefaultControllerActivator();
|
||||
|
||||
// Act
|
||||
activator.Activate(controller, context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(controller.GetViewData());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Activate_PopulatesServicesFromServiceContainer()
|
||||
{
|
||||
// Arrange
|
||||
var urlHelper = Mock.Of<IUrlHelper>();
|
||||
var service = new Mock<IServiceProvider>();
|
||||
service.Setup(s => s.GetService(typeof(IUrlHelper)))
|
||||
.Returns(urlHelper);
|
||||
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
httpContext.SetupGet(c => c.RequestServices)
|
||||
.Returns(service.Object);
|
||||
var routeContext = new RouteContext(httpContext.Object);
|
||||
var controller = new TestController();
|
||||
var context = new ActionContext(routeContext, new ActionDescriptor())
|
||||
{
|
||||
Controller = controller
|
||||
};
|
||||
var activator = new DefaultControllerActivator();
|
||||
|
||||
// Act
|
||||
activator.Activate(controller, context);
|
||||
|
||||
// Assert
|
||||
Assert.Same(urlHelper, controller.Helper);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Activate_IgnoresPropertiesThatAreNotDecoratedWithActivateAttribute()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
httpContext.SetupGet(c => c.Response)
|
||||
.Returns(Mock.Of<HttpResponse>());
|
||||
httpContext.SetupGet(c => c.RequestServices)
|
||||
.Returns(Mock.Of<IServiceProvider>());
|
||||
var routeContext = new RouteContext(httpContext.Object);
|
||||
var controller = new TestController();
|
||||
var context = new ActionContext(routeContext, new ActionDescriptor())
|
||||
{
|
||||
Controller = controller
|
||||
};
|
||||
var activator = new DefaultControllerActivator();
|
||||
|
||||
// Act
|
||||
activator.Activate(controller, context);
|
||||
|
||||
// Assert
|
||||
Assert.Null(controller.Response);
|
||||
}
|
||||
|
||||
public class TestController
|
||||
{
|
||||
[Activate]
|
||||
public ActionContext ActionContext { get; set; }
|
||||
|
||||
[Activate]
|
||||
public HttpContext HttpContext { get; set; }
|
||||
|
||||
[Activate]
|
||||
protected HttpRequest Request { get; set; }
|
||||
|
||||
[Activate]
|
||||
private ViewDataDictionary ViewData { get; set; }
|
||||
|
||||
[Activate]
|
||||
public IUrlHelper Helper { get; set; }
|
||||
|
||||
public HttpResponse Response { get; set; }
|
||||
|
||||
public ViewDataDictionary GetViewData()
|
||||
{
|
||||
return ViewData;
|
||||
}
|
||||
|
||||
public HttpRequest GetHttpRequest()
|
||||
{
|
||||
return Request;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -15,8 +15,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
{
|
||||
// Arrange
|
||||
var factory = new DefaultControllerFactory(
|
||||
new Mock<IServiceProvider>().Object,
|
||||
new Mock<ITypeActivator>().Object);
|
||||
Mock.Of<IServiceProvider>(),
|
||||
Mock.Of<ITypeActivator>(),
|
||||
Mock.Of<IControllerActivator>());
|
||||
|
||||
var controller = new MyController();
|
||||
|
||||
|
|
@ -33,8 +34,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
|||
{
|
||||
// Arrange
|
||||
var factory = new DefaultControllerFactory(
|
||||
new Mock<IServiceProvider>().Object,
|
||||
new Mock<ITypeActivator>().Object);
|
||||
Mock.Of<IServiceProvider>(),
|
||||
Mock.Of<ITypeActivator>(),
|
||||
Mock.Of<IControllerActivator>());
|
||||
|
||||
var controller = new Object();
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
<Compile Include="AntiXsrf\AntiForgeryTokenSerializerTest.cs" />
|
||||
<Compile Include="AntiXsrf\ITokenProvider.cs" />
|
||||
<Compile Include="AntiXsrf\ValidateAntiForgeryTokenAttributeTest.cs" />
|
||||
<Compile Include="DefaultControllerActivatorTest.cs" />
|
||||
<Compile Include="Filters\ActionFilterAttributeTests.cs" />
|
||||
<Compile Include="Filters\AuthorizeAttributeTests.cs" />
|
||||
<Compile Include="Filters\AuthorizeAttributeTestsBase.cs" />
|
||||
|
|
|
|||
|
|
@ -186,10 +186,62 @@ namespace Microsoft.AspNet.Mvc
|
|||
var propAHelper = Assert.Single(helpers.Where(h => h.Name == "PropA"));
|
||||
var propBHelper = Assert.Single(helpers.Where(h => h.Name == "PropB"));
|
||||
|
||||
Assert.Equal("Overriden", propAHelper.GetValue(derived));
|
||||
Assert.Equal("OverridenpropAValue", propAHelper.GetValue(derived));
|
||||
Assert.Equal("propBValue", propBHelper.GetValue(derived));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MakeFastPropertySetter_SetsPropertyValues_ForPublicAndNobPublicProperties()
|
||||
{
|
||||
// Arrange
|
||||
var instance = new BaseClass();
|
||||
var typeInfo = instance.GetType().GetTypeInfo();
|
||||
var publicProperty = typeInfo.GetDeclaredProperty("PropA");
|
||||
var protectedProperty = typeInfo.GetDeclaredProperty("PropProtected");
|
||||
var publicPropertySetter = PropertyHelper.MakeFastPropertySetter(publicProperty);
|
||||
var protectedPropertySetter = PropertyHelper.MakeFastPropertySetter(protectedProperty);
|
||||
|
||||
// Act
|
||||
publicPropertySetter(instance, "TestPublic");
|
||||
protectedPropertySetter(instance, "TestProtected");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("TestPublic", instance.PropA);
|
||||
Assert.Equal("TestProtected", instance.GetPropProtected());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MakeFastPropertySetter_SetsPropertyValues_ForOverridenProperties()
|
||||
{
|
||||
// Arrange
|
||||
var instance = new DerivedClassWithOverride();
|
||||
var typeInfo = instance.GetType().GetTypeInfo();
|
||||
var property = typeInfo.GetDeclaredProperty("PropA");
|
||||
var propertySetter = PropertyHelper.MakeFastPropertySetter(property);
|
||||
|
||||
// Act
|
||||
propertySetter(instance, "Test value");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("OverridenTest value", instance.PropA);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MakeFastPropertySetter_SetsPropertyValues_ForNewedProperties()
|
||||
{
|
||||
// Arrange
|
||||
var instance = new DerivedClassWithNew();
|
||||
var typeInfo = instance.GetType().GetTypeInfo();
|
||||
var property = typeInfo.GetDeclaredProperty("PropB");
|
||||
var propertySetter = PropertyHelper.MakeFastPropertySetter(property);
|
||||
|
||||
// Act
|
||||
propertySetter(instance, "Test value");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("NewedTest value", instance.PropB);
|
||||
}
|
||||
|
||||
private class Static
|
||||
{
|
||||
public static int Prop2 { get; set; }
|
||||
|
|
@ -220,6 +272,11 @@ namespace Microsoft.AspNet.Mvc
|
|||
public string PropA { get; set; }
|
||||
|
||||
protected string PropProtected { get; set; }
|
||||
|
||||
public string GetPropProtected()
|
||||
{
|
||||
return PropProtected;
|
||||
}
|
||||
}
|
||||
|
||||
public class DerivedClass : BaseClass
|
||||
|
|
@ -235,12 +292,24 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
public class DerivedClassWithNew : BaseClassWithVirtual
|
||||
{
|
||||
public new string PropB { get { return "Newed"; } }
|
||||
private string _value = "Newed";
|
||||
|
||||
public new string PropB
|
||||
{
|
||||
get { return _value; }
|
||||
set { _value = "Newed" + value; }
|
||||
}
|
||||
}
|
||||
|
||||
public class DerivedClassWithOverride : BaseClassWithVirtual
|
||||
{
|
||||
public override string PropA { get { return "Overriden"; } }
|
||||
private string _value = "Overriden";
|
||||
|
||||
public override string PropA
|
||||
{
|
||||
get { return _value; }
|
||||
set { _value = "Overriden" + value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1297,7 +1297,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
routeData: new RouteData(),
|
||||
actionDescriptor: actionDescriptor);
|
||||
|
||||
var controllerFactory = new Mock<IControllerFactory>(MockBehavior.Strict);
|
||||
var controllerFactory = new Mock<IControllerFactory>();
|
||||
controllerFactory.Setup(c => c.CreateController(It.IsAny<ActionContext>())).Returns(this);
|
||||
|
||||
var actionBindingContextProvider = new Mock<IActionBindingContextProvider>(MockBehavior.Strict);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ActivatorWebSite;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.TestHost;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||
{
|
||||
public class ActivatorTests
|
||||
{
|
||||
private readonly IServiceProvider _provider = TestHelper.CreateServices("ActivatorWebSite");
|
||||
private readonly Action<IBuilder> _app = new Startup().Configure;
|
||||
|
||||
[Fact]
|
||||
public async Task ControllerThatCannotBeActivated_ThrowsWhenAttemptedToBeInvoked()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.Handler;
|
||||
var expectedMessage = "TODO: No service for type 'ActivatorWebSite.CannotBeActivatedController+FakeType' " +
|
||||
"has been registered.";
|
||||
|
||||
// Act & Assert
|
||||
var ex = await Assert.ThrowsAsync<Exception>(() => client.GetAsync("http://localhost/CannotBeActivated/Index"));
|
||||
Assert.Equal(expectedMessage, ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PropertiesForPocoControllersAreInitialized()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.Handler;
|
||||
var expected = "4|some-text";
|
||||
|
||||
// Act
|
||||
var result = await client.GetAsync("http://localhost/Plain?foo=some-text");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Fake-Value", result.HttpContext.Response.Headers["X-Fake-Header"]);
|
||||
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||
Assert.Equal(expected, body);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PropertiesForTypesDerivingFromControllerAreInitialized()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.Handler;
|
||||
var expected = "Hello world";
|
||||
|
||||
// Act
|
||||
var result = await client.GetAsync("http://localhost/Regular");
|
||||
|
||||
// Assert
|
||||
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||
Assert.Equal(expected, body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
<Content Include="project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ActivatorTests.cs" />
|
||||
<Compile Include="InlineConstraintTests.cs" />
|
||||
<Compile Include="TestHelper.cs" />
|
||||
<Compile Include="BasicTests.cs" />
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"BasicWebSite": "",
|
||||
"ActivatorWebSite": "",
|
||||
"InlineConstraintsWebSite": "",
|
||||
"Microsoft.AspNet.TestHost": "1.0.0-*",
|
||||
"Microsoft.Framework.Runtime.Interfaces": "1.0.0-*",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="__ToolsVersion__" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">12.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>db79bcba-9538-4a53-87d9-77728e2baa39</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(OutputType) == 'Console'">
|
||||
<DebuggerFlavor>ConsoleDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(OutputType) == 'Web'">
|
||||
<DebuggerFlavor>WebDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Controllers\CannotBeActivatedController.cs" />
|
||||
<Compile Include="Controllers\PlainController.cs" />
|
||||
<Compile Include="Controllers\RegularController.cs" />
|
||||
<Compile Include="Services\MyService.cs" />
|
||||
<Compile Include="Startup.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace ActivatorWebSite
|
||||
{
|
||||
public class CannotBeActivatedController
|
||||
{
|
||||
[Activate]
|
||||
private FakeType Service { get; set; }
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
return new NoContentResult();
|
||||
}
|
||||
|
||||
private sealed class FakeType
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace ActivatorWebSite
|
||||
{
|
||||
public class PlainController
|
||||
{
|
||||
[Activate]
|
||||
public MyService Service { get; set; }
|
||||
|
||||
[Activate]
|
||||
public HttpRequest Request { get; set; }
|
||||
|
||||
[Activate]
|
||||
public HttpResponse Response { get; set; }
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
Response.Headers["X-Fake-Header"] = "Fake-Value";
|
||||
|
||||
var value = Request.Query["foo"];
|
||||
return new ContentResult { Content = Service.Random + "|" + value };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace ActivatorWebSite
|
||||
{
|
||||
public class RegularController : Controller
|
||||
{
|
||||
public void Index()
|
||||
{
|
||||
// This verifies that ModelState and Context are activated.
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
Context.Response.WriteAsync("Hello world").Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace ActivatorWebSite
|
||||
{
|
||||
public class MyService
|
||||
{
|
||||
public int Random
|
||||
{
|
||||
get { return 4; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
namespace ActivatorWebSite
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public void Configure(IBuilder app)
|
||||
{
|
||||
// Set up application services
|
||||
app.UseServices(services =>
|
||||
{
|
||||
// Add MVC services to the services container
|
||||
services.AddMvc();
|
||||
services.AddInstance(new MyService());
|
||||
});
|
||||
|
||||
// Add MVC to the request pipeline
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute("ActionAsMethod", "{controller}/{action}",
|
||||
defaults: new { controller = "Home", action = "Index" });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"Helios": "0.1-alpha-*",
|
||||
"Microsoft.AspNet.Mvc": ""
|
||||
},
|
||||
"configurations": {
|
||||
"net45": { },
|
||||
"k10": { }
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue