#7024 Request: ServiceBasedPageModelActivatorProvider

This commit is contained in:
Nisha Kaushik 2018-05-21 21:11:29 +05:30 committed by Pranav K
parent 330b74f0ab
commit 0c795c4f33
3 changed files with 198 additions and 1 deletions

View File

@ -110,9 +110,11 @@ namespace Microsoft.Extensions.DependencyInjection
ServiceDescriptor.Singleton<IActionInvokerProvider, PageActionInvokerProvider>());
// Page and Page model creation and activation
services.TryAddSingleton<IPageModelActivatorProvider, DefaultPageModelActivatorProvider>();
services.TryAddSingleton<IPageModelActivatorProvider, DefaultPageModelActivatorProvider>();
services.TryAddSingleton<IPageModelFactoryProvider, DefaultPageModelFactoryProvider>();
services.TryAddSingleton<IPageModelActivatorProvider, ServiceBasedPageModelActivatorProvider>();
services.TryAddSingleton<IPageActivatorProvider, DefaultPageActivatorProvider>();
services.TryAddSingleton<IPageFactoryProvider, DefaultPageFactoryProvider>();

View File

@ -0,0 +1,43 @@
// Copyright (c) .NET Foundation. 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.Reflection;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
{
/// <summary>
/// <see cref="IPageActivatorProvider"/> that uses type activation to create Razor Page instances.
/// </summary>
public class ServiceBasedPageModelActivatorProvider : IPageModelActivatorProvider
{
public Func<PageContext, object> CreateActivator(CompiledPageActionDescriptor descriptor)
{
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
var modelTypeInfo = descriptor.ModelTypeInfo?.AsType();
if (modelTypeInfo == null)
{
throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull(
nameof(descriptor.ModelTypeInfo),
nameof(descriptor)),
nameof(descriptor));
}
return context =>
{
return context.HttpContext.RequestServices.GetRequiredService(modelTypeInfo);
};
}
public Action<PageContext, object> CreateReleaser(CompiledPageActionDescriptor descriptor)
{
return null;
}
}
}

View File

@ -0,0 +1,152 @@
// Copyright (c) .NET Foundation. 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.Reflection;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Testing;
using Moq;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
{
public class ServiceBasedPageModelActivatorProviderTest
{
[Fact]
public void CreateActivator_ThrowsIfModelTypeInfoOnActionDescriptorIsNull()
{
// Arrange
var activatorProvider = new ServiceBasedPageModelActivatorProvider();
var descriptor = new CompiledPageActionDescriptor();
// Act & Assert
ExceptionAssert.ThrowsArgument(
() => activatorProvider.CreateActivator(descriptor),
"descriptor",
"The 'ModelTypeInfo' property of 'descriptor' must not be null.");
}
[Fact]
public void Create_GetsServicesFromServiceProvider()
{
// Arrange
var simpleModel = new DISimpleModel();
var serviceProvider = new Mock<IServiceProvider>(MockBehavior.Strict);
serviceProvider.Setup(s => s.GetService(typeof(DISimpleModel)))
.Returns(simpleModel)
.Verifiable();
var activatorProvider = new ServiceBasedPageModelActivatorProvider();
var pageContext = new PageContext
{
HttpContext = new DefaultHttpContext
{
RequestServices = serviceProvider.Object,
},
ActionDescriptor = new CompiledPageActionDescriptor
{
ModelTypeInfo = typeof(DISimpleModel).GetTypeInfo(),
}
};
// Act
var activator = activatorProvider.CreateActivator(pageContext.ActionDescriptor);
var instance = activator(pageContext);
// Assert
Assert.Same(simpleModel, instance);
serviceProvider.Verify();
}
[Fact]
public void CreateActivator_CreatesModelInstance()
{
// Arrange
var controller = new DISimpleModel();
var serviceProvider = new Mock<IServiceProvider>(MockBehavior.Strict);
serviceProvider.Setup(s => s.GetService(typeof(DISimpleModel)))
.Returns(controller)
.Verifiable();
var activatorProvider = new ServiceBasedPageModelActivatorProvider();
var pageContext = new PageContext
{
HttpContext = new DefaultHttpContext
{
RequestServices = serviceProvider.Object,
},
ActionDescriptor = new CompiledPageActionDescriptor
{
ModelTypeInfo = typeof(DISimpleModel).GetTypeInfo(),
}
};
// Act
var activator = activatorProvider.CreateActivator(pageContext.ActionDescriptor);
var model = activator(pageContext);
// Assert
var simpleModel = Assert.IsType<DISimpleModel>(model);
Assert.NotNull(simpleModel);
}
[Fact]
public void Create_ThrowsIfModelIsNotRegisteredInServiceProvider()
{
// Arrange
var expected = "No service for type '" + typeof(DISimpleModel) + "' has been registered.";
var model = new DISimpleModel();
var httpContext = new DefaultHttpContext
{
RequestServices = Mock.Of<IServiceProvider>()
};
var activatorProvider = new ServiceBasedPageModelActivatorProvider();
var context = new PageContext
{
HttpContext = httpContext,
ActionDescriptor = new CompiledPageActionDescriptor
{
ModelTypeInfo = typeof(DISimpleModel).GetTypeInfo(),
}
};
// Act and Assert
var activator = activatorProvider.CreateActivator(context.ActionDescriptor);
var ex = Assert.Throws<InvalidOperationException>(
() => activator(context));
Assert.Equal(expected, ex.Message);
}
[Theory]
[InlineData(typeof(SimpleModel))]
[InlineData(typeof(object))]
public void CreateReleaser_ReturnsNullForPageModels(Type pageType)
{
// Arrange
var context = new PageContext();
var activator = new ServiceBasedPageModelActivatorProvider();
var actionDescriptor = new CompiledPageActionDescriptor
{
PageTypeInfo = pageType.GetTypeInfo(),
};
// Act
var releaser = activator.CreateReleaser(actionDescriptor);
// Assert
Assert.Null(releaser);
}
private class SimpleModel
{
}
private class DISimpleModel : SimpleModel
{
}
}
}