Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Commit

Permalink
[Fixes #5166] Support passing instance directly when invoking ViewCom…
Browse files Browse the repository at this point in the history
…ponents with single parameter
  • Loading branch information
ajaybhargavb committed Aug 26, 2016
1 parent 9ed7532 commit a6a4b53
Show file tree
Hide file tree
Showing 7 changed files with 266 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,14 @@ protected virtual IEnumerable<TypeInfo> GetCandidateTypes()

private static ViewComponentDescriptor CreateDescriptor(TypeInfo typeInfo)
{
var methodInfo = FindMethod(typeInfo.AsType());
var candidate = new ViewComponentDescriptor
{
FullName = ViewComponentConventions.GetComponentFullName(typeInfo),
ShortName = ViewComponentConventions.GetComponentName(typeInfo),
TypeInfo = typeInfo,
MethodInfo = FindMethod(typeInfo.AsType())
MethodInfo = methodInfo,
Parameters = methodInfo.GetParameters()
};

return candidate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Html;
Expand Down Expand Up @@ -130,19 +132,28 @@ private ViewComponentDescriptor SelectComponent(Type componentType)
componentType.FullName));
}

private async Task<IHtmlContent> InvokeCoreAsync(
ViewComponentDescriptor descriptor,
object arguments)
// Internal for testing
internal IDictionary<string, object> GetArgumentDictionary(ViewComponentDescriptor descriptor, object arguments)
{
if (descriptor.Parameters.Count == 1 && descriptor.Parameters[0].ParameterType.IsAssignableFrom(arguments.GetType()))
{
return new Dictionary<string, object>(capacity: 1, comparer: StringComparer.OrdinalIgnoreCase)
{
{ descriptor.Parameters[0].Name, arguments }
};
}

return PropertyHelper.ObjectToDictionary(arguments);
}

private async Task<IHtmlContent> InvokeCoreAsync(ViewComponentDescriptor descriptor, object arguments)
{
var argumentDictionary = GetArgumentDictionary(descriptor, arguments);

var viewBuffer = new ViewBuffer(_viewBufferScope, descriptor.FullName, ViewBuffer.ViewComponentPageSize);
using (var writer = new ViewBufferTextWriter(viewBuffer, _viewContext.Writer.Encoding))
{
var context = new ViewComponentContext(
descriptor,
PropertyHelper.ObjectToDictionary(arguments),
_htmlEncoder,
_viewContext,
writer);
var context = new ViewComponentContext(descriptor, argumentDictionary, _htmlEncoder, _viewContext, writer);

var invoker = _invokerFactory.CreateInstance(context);
if (invoker == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;

Expand Down Expand Up @@ -124,5 +126,10 @@ public string DisplayName
/// Gets or sets the <see cref="System.Reflection.MethodInfo"/> to invoke.
/// </summary>
public MethodInfo MethodInfo { get; set; }

/// <summary>
/// Gets or sets the parameters associated with the method described by <see cref="MethodInfo"/>.
/// </summary>
public IReadOnlyList<ParameterInfo> Parameters { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,14 @@ public void Model_ExposesViewDataModel()
public async Task ExecuteAsync_ViewComponentResult_AllowsNullViewDataAndTempData()
{
// Arrange
var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
var descriptor = new ViewComponentDescriptor()
{
FullName = "Full.Name.Text",
ShortName = "Text",
TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
MethodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke)),
MethodInfo = methodInfo,
Parameters = methodInfo.GetParameters(),
};

var actionContext = CreateActionContext(descriptor);
Expand Down Expand Up @@ -146,12 +148,14 @@ public async Task ExecuteResultAsync_Throws_IfViewComponentCouldNotBeFound_ByTyp
public async Task ExecuteResultAsync_ExecutesSyncViewComponent()
{
// Arrange
var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
var descriptor = new ViewComponentDescriptor()
{
FullName = "Full.Name.Text",
ShortName = "Text",
TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
MethodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke)),
MethodInfo = methodInfo,
Parameters = methodInfo.GetParameters(),
};

var actionContext = CreateActionContext(descriptor);
Expand All @@ -175,12 +179,14 @@ public async Task ExecuteResultAsync_ExecutesSyncViewComponent()
public async Task ExecuteResultAsync_UsesDictionaryArguments()
{
// Arrange
var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
var descriptor = new ViewComponentDescriptor()
{
FullName = "Full.Name.Text",
ShortName = "Text",
TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
MethodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke)),
MethodInfo = methodInfo,
Parameters = methodInfo.GetParameters(),
};

var actionContext = CreateActionContext(descriptor);
Expand All @@ -204,12 +210,14 @@ public async Task ExecuteResultAsync_UsesDictionaryArguments()
public async Task ExecuteResultAsync_ExecutesAsyncViewComponent()
{
// Arrange
var methodInfo = typeof(AsyncTextViewComponent).GetMethod(nameof(AsyncTextViewComponent.InvokeAsync));
var descriptor = new ViewComponentDescriptor()
{
FullName = "Full.Name.AsyncText",
ShortName = "AsyncText",
TypeInfo = typeof(AsyncTextViewComponent).GetTypeInfo(),
MethodInfo = typeof(AsyncTextViewComponent).GetMethod(nameof(AsyncTextViewComponent.InvokeAsync)),
MethodInfo = methodInfo,
Parameters = methodInfo.GetParameters(),
};

var actionContext = CreateActionContext(descriptor);
Expand All @@ -233,12 +241,14 @@ public async Task ExecuteResultAsync_ExecutesAsyncViewComponent()
public async Task ExecuteResultAsync_ExecutesViewComponent_AndWritesDiagnosticSource()
{
// Arrange
var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
var descriptor = new ViewComponentDescriptor()
{
FullName = "Full.Name.Text",
ShortName = "Text",
TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
MethodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke)),
MethodInfo = methodInfo,
Parameters = methodInfo.GetParameters(),
};

var adapter = new TestDiagnosticListener();
Expand Down Expand Up @@ -272,12 +282,14 @@ public async Task ExecuteResultAsync_ExecutesViewComponent_AndWritesDiagnosticSo
public async Task ExecuteResultAsync_ExecutesViewComponent_ByShortName()
{
// Arrange
var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
var descriptor = new ViewComponentDescriptor()
{
FullName = "Full.Name.Text",
ShortName = "Text",
TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
MethodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke)),
MethodInfo = methodInfo,
Parameters = methodInfo.GetParameters(),
};

var actionContext = CreateActionContext(descriptor);
Expand All @@ -301,12 +313,14 @@ public async Task ExecuteResultAsync_ExecutesViewComponent_ByShortName()
public async Task ExecuteResultAsync_ExecutesViewComponent_ByFullName()
{
// Arrange
var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
var descriptor = new ViewComponentDescriptor()
{
FullName = "Full.Name.Text",
ShortName = "Text",
TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
MethodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke)),
MethodInfo = methodInfo,
Parameters = methodInfo.GetParameters(),
};

var actionContext = CreateActionContext(descriptor);
Expand All @@ -330,12 +344,14 @@ public async Task ExecuteResultAsync_ExecutesViewComponent_ByFullName()
public async Task ExecuteResultAsync_ExecutesViewComponent_ByType()
{
// Arrange
var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
var descriptor = new ViewComponentDescriptor()
{
FullName = "Full.Name.Text",
ShortName = "Text",
TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
MethodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke)),
MethodInfo = methodInfo,
Parameters = methodInfo.GetParameters(),
};

var actionContext = CreateActionContext(descriptor);
Expand All @@ -359,12 +375,14 @@ public async Task ExecuteResultAsync_ExecutesViewComponent_ByType()
public async Task ExecuteResultAsync_SetsStatusCode()
{
// Arrange
var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
var descriptor = new ViewComponentDescriptor()
{
FullName = "Full.Name.Text",
ShortName = "Text",
TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
MethodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke))
MethodInfo = methodInfo,
Parameters = methodInfo.GetParameters(),
};

var actionContext = CreateActionContext(descriptor);
Expand Down Expand Up @@ -417,12 +435,14 @@ public async Task ViewComponentResult_SetsContentTypeHeader(
string expectedContentType)
{
// Arrange
var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
var descriptor = new ViewComponentDescriptor()
{
FullName = "Full.Name.Text",
ShortName = "Text",
TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
MethodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke)),
MethodInfo = methodInfo,
Parameters = methodInfo.GetParameters(),
};

var actionContext = CreateActionContext(descriptor);
Expand Down Expand Up @@ -455,12 +475,14 @@ public async Task ViewComponentResult_SetsContentTypeHeader(
public async Task ViewComponentResult_SetsContentTypeHeader_OverrideResponseContentType()
{
// Arrange
var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
var descriptor = new ViewComponentDescriptor()
{
FullName = "Full.Name.Text",
ShortName = "Text",
TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
MethodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke)),
MethodInfo = methodInfo,
Parameters = methodInfo.GetParameters(),
};

var actionContext = CreateActionContext(descriptor);
Expand Down Expand Up @@ -492,12 +514,14 @@ public async Task ViewComponentResult_NoContentTypeSet_PreservesResponseContentT
string expectedContentType)
{
// Arrange
var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
var descriptor = new ViewComponentDescriptor()
{
FullName = "Full.Name.Text",
ShortName = "Text",
TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
MethodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke)),
MethodInfo = methodInfo,
Parameters = methodInfo.GetParameters(),
};

var actionContext = CreateActionContext(descriptor);
Expand Down
Loading

0 comments on commit a6a4b53

Please sign in to comment.