-
Notifications
You must be signed in to change notification settings - Fork 3
/
Startup.cs
105 lines (93 loc) · 4.1 KB
/
Startup.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using MvcInMiddleware.Controllers;
namespace MvcInMiddleware
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews().AddNewtonsoftJson();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app = env.IsDevelopment() ? app.UseDeveloperExceptionPage() : app.UseExceptionHandler("/Home/Error");
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
var routeData = new RouteData();
routeData.Values.Add("message", "Hello World!");
await DriveControllerAction(context, routeData, app);
});
});
}
private static async Task DriveControllerAction(HttpContext context , RouteData routeData, IApplicationBuilder app)
{
var actionDesciptor = CreateActionDescriptor<HomeController>(nameof(HomeController.Index), routeData);
var actionContext = new ActionContext(context, routeData, actionDesciptor);
var actionInvokerFactory = app.ApplicationServices.GetRequiredService<IActionInvokerFactory>(); //ActionInvokerFactory
var invoker = actionInvokerFactory.CreateInvoker(actionContext); //ControllerActionInvoker
await invoker.InvokeAsync();
}
private static ActionDescriptor CreateActionDescriptor<TController>(string actionName, RouteData routeData)
{
var controllerType = typeof(TController);
var actionDesciptor = new ControllerActionDescriptor()
{
ControllerName = controllerType.Name,
ActionName = actionName,
FilterDescriptors = new List<FilterDescriptor>(),
MethodInfo = controllerType.GetMethod(actionName, BindingFlags.Public | BindingFlags.Instance),
ControllerTypeInfo = controllerType.GetTypeInfo(),
Parameters = new List<ParameterDescriptor>(),
Properties = new Dictionary<object, object>(),
BoundProperties = new List<ParameterDescriptor>()
};
if (actionDesciptor.MethodInfo == null)
{
throw new ArgumentNullException($"actionDesciptor.MethodInfo for '{actionName}'");
}
//For searching View
routeData.Values.Add("controller", actionDesciptor.ControllerName.Replace("Controller", ""));
routeData.Values.Add("action", actionDesciptor.ActionName);
//For binding action parameters
foreach (var routeValue in routeData.Values)
{
var parameter = new ParameterDescriptor();
parameter.Name = routeValue.Key;
var attributes = new object[]
{
new FromRouteAttribute { Name = parameter.Name },
};
parameter.BindingInfo = BindingInfo.GetBindingInfo(attributes);
parameter.ParameterType = routeValue.Value.GetType();
actionDesciptor.Parameters.Add(parameter);
}
return actionDesciptor;
}
}
}