Hosting#318 Add middleware analysis tools, sample.

This commit is contained in:
Chris R 2015-11-17 16:07:03 -08:00
parent c49547245b
commit c8990bcc29
15 changed files with 530 additions and 0 deletions

View File

@ -44,6 +44,12 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ElmPageSample", "samples\El
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "DatabaseErrorPageSample", "samples\DatabaseErrorPageSample\DatabaseErrorPageSample.xproj", "{FF7F11A1-14E7-4948-A853-2487D99DE0C6}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.MiddlewareAnalysis", "src\Microsoft.AspNet.MiddlewareAnalysis\Microsoft.AspNet.MiddlewareAnalysis.xproj", "{C2DEDD37-D1EB-4819-9A9C-475E37A52358}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MiddlewareAnalysisSample", "samples\MiddlewareAnalysisSample\MiddlewareAnalysisSample.xproj", "{95981429-F212-44E1-83AA-32DA9E2A517C}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.MiddlewareAnalysis.Tests", "test\Microsoft.AspNet.MiddlewareAnalysis.Tests\Microsoft.AspNet.MiddlewareAnalysis.Tests.xproj", "{B0166AED-738F-42EE-AF4D-C487C8B21521}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -220,6 +226,42 @@ Global
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|x86.ActiveCfg = Release|Any CPU
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|x86.Build.0 = Release|Any CPU
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|x86.ActiveCfg = Debug|Any CPU
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|x86.Build.0 = Debug|Any CPU
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Any CPU.Build.0 = Release|Any CPU
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|x86.ActiveCfg = Release|Any CPU
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|x86.Build.0 = Release|Any CPU
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|x86.ActiveCfg = Debug|Any CPU
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|x86.Build.0 = Debug|Any CPU
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Any CPU.Build.0 = Release|Any CPU
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|x86.ActiveCfg = Release|Any CPU
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|x86.Build.0 = Release|Any CPU
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|x86.ActiveCfg = Debug|Any CPU
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|x86.Build.0 = Debug|Any CPU
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Any CPU.Build.0 = Release|Any CPU
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|x86.ActiveCfg = Release|Any CPU
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -240,5 +282,8 @@ Global
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
{FF7F11A1-14E7-4948-A853-2487D99DE0C6} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
{C2DEDD37-D1EB-4819-9A9C-475E37A52358} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
{95981429-F212-44E1-83AA-32DA9E2A517C} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
{B0166AED-738F-42EE-AF4D-C487C8B21521} = {2AF90579-B118-4583-AE88-672EFACB5BC4}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>95981429-f212-44e1-83aa-32da9e2a517c</ProjectGuid>
<RootNamespace>MiddlewareAnalysisSample</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
<DevelopmentServerPort>2764</DevelopmentServerPort>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View File

@ -0,0 +1,106 @@
using System;
using System.Diagnostics;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DiagnosticAdapter;
using Microsoft.Extensions.Logging;
namespace MiddlewareAnaysisSample
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMiddlewareAnalysis();
}
public void Configure(IApplicationBuilder app, ILoggerFactory factory, DiagnosticListener diagnosticListener)
{
// Displays all log levels
factory.AddConsole(LogLevel.Verbose);
// Listen for middleware events and log them to the console.
var listener = new TestDiagnosticListener();
diagnosticListener.SubscribeWithAdapter(listener);
// Build our application pipeline
// Named via app.UseMiddleware<T>()
app.UseDeveloperExceptionPage();
app.UseIISPlatformHandler();
// Anonymous method inline middleware
app.Use((context, next) =>
{
// No-op
return next();
});
app.Map("/map", subApp =>
{
subApp.Run(context =>
{
return context.Response.WriteAsync("Hello World");
});
});
// Low level anonymous method inline middleware, named Diagnostics.Middleware.Analysis.Startup+<>c by default
app.Use(next =>
{
return context =>
{
return next(context);
};
});
app.Map("/throw", throwApp =>
{
throwApp.Run(context => { throw new Exception("Application Exception"); });
});
// The home page.
app.Properties["analysis.NextMiddlewareName"] = "HomePage";
app.Use(async (context, next) =>
{
if (context.Request.Path == "/")
{
context.Response.ContentType = "text/html";
await context.Response.WriteAsync("<html><body>Welcome to the sample<br><br>\r\n");
await context.Response.WriteAsync("Click here to take a side branch: <a href=\"/map/foo\">Map</a><br>\r\n");
await context.Response.WriteAsync("Click here to throw an exception: <a href=\"/throw\">Throw</a><br>\r\n");
await context.Response.WriteAsync("Click here to for a 404: <a href=\"/404\">404</a><br>\r\n");
await context.Response.WriteAsync("</body></html>\r\n");
return;
}
else
{
await next();
}
});
// Note there's always a default 404 middleware at the end of the pipeline.
}
public class TestDiagnosticListener
{
[DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareStarting")]
public virtual void OnMiddlewareStarting(HttpContext httpContext, string name)
{
Console.WriteLine($"MiddlewareStarting: {name}; {httpContext.Request.Path}");
}
[DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareException")]
public virtual void OnMiddlewareException(Exception exception, string name)
{
Console.WriteLine($"MiddlewareException: {name}; {exception.Message}");
}
[DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareFinished")]
public virtual void OnMiddlewareFinished(HttpContext httpContext, string name)
{
Console.WriteLine($"MiddlewareFinished: {name}; {httpContext.Response.StatusCode}");
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"dependencies": {
"Microsoft.AspNet.Diagnostics": "1.0.0-*",
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-*",
"Microsoft.AspNet.MiddlewareAnalysis": "1.0.0-*",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-*",
"Microsoft.AspNet.Server.WebListener": "1.0.0-*",
"Microsoft.Extensions.DiagnosticAdapter": "1.0.0-*",
"Microsoft.Extensions.Logging.Console": "1.0.0-*"
},
"commands": {
"web": "Microsoft.AspNet.Server.Kestrel",
"weblistener": "Microsoft.AspNet.Server.WebListener"
},
"frameworks": {
"dnx451": { },
"dnxcore50": { }
}
}

View File

@ -0,0 +1,65 @@
// 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.Collections.Generic;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Features;
namespace Microsoft.AspNet.MiddlewareAnalysis
{
public class AnalysisBuilder : IApplicationBuilder
{
private const string NextMiddlewareName = "analysis.NextMiddlewareName";
public AnalysisBuilder(IApplicationBuilder inner)
{
InnerBuilder = inner;
}
private IApplicationBuilder InnerBuilder { get; }
public IServiceProvider ApplicationServices
{
get { return InnerBuilder.ApplicationServices; }
set { InnerBuilder.ApplicationServices = value; }
}
public IDictionary<string, object> Properties
{
get { return InnerBuilder.Properties; }
}
public IFeatureCollection ServerFeatures
{
get { return InnerBuilder.ServerFeatures;}
}
public RequestDelegate Build()
{
// Add one maker at the end before the default 404 middleware (or any fancy Join middleware).
return InnerBuilder.UseMiddleware<AnalysisMiddleware>("EndOfPipeline")
.Build();
}
public IApplicationBuilder New()
{
return new AnalysisBuilder(InnerBuilder.New());
}
public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
{
string middlewareName = string.Empty; // UseMiddleware doesn't work with null params.
object middlewareNameObj;
if (Properties.TryGetValue(NextMiddlewareName, out middlewareNameObj))
{
middlewareName = middlewareNameObj?.ToString();
Properties.Remove(NextMiddlewareName);
}
return InnerBuilder.UseMiddleware<AnalysisMiddleware>(middlewareName)
.Use(middleware);
}
}
}

View File

@ -0,0 +1,54 @@
// 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.Diagnostics;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
namespace Microsoft.AspNet.MiddlewareAnalysis
{
public class AnalysisMiddleware
{
private readonly RequestDelegate _next;
private readonly DiagnosticSource _diagnostics;
private readonly string _middlewareName;
public AnalysisMiddleware(RequestDelegate next, DiagnosticSource diagnosticSource, string middlewareName)
{
_next = next;
_diagnostics = diagnosticSource;
if (string.IsNullOrEmpty(middlewareName))
{
middlewareName = next.Target.GetType().FullName;
}
_middlewareName = middlewareName;
}
public async Task Invoke(HttpContext httpContext)
{
if (_diagnostics.IsEnabled("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareStarting"))
{
_diagnostics.Write("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareStarting", new { name = _middlewareName, httpContext = httpContext });
}
try
{
await _next(httpContext);
if (_diagnostics.IsEnabled("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareFinished"))
{
_diagnostics.Write("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareFinished", new { name = _middlewareName, httpContext = httpContext });
}
}
catch (Exception ex)
{
if (_diagnostics.IsEnabled("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareException"))
{
_diagnostics.Write("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareException", new { name = _middlewareName, httpContext = httpContext, exception = ex });
}
throw;
}
}
}
}

View File

@ -0,0 +1,19 @@
// 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 Microsoft.AspNet.Hosting;
using Microsoft.AspNet.MiddlewareAnalysis;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Microsoft.Extensions.DependencyInjection
{
public static class AnalysisServiceCollectionExtensions
{
public static IServiceCollection AddMiddlewareAnalysis(this IServiceCollection services)
{
// This should prevent AnalysisStartupFilter from being registered more than once.
services.TryAddEnumerable(ServiceDescriptor.Transient<IStartupFilter, AnalysisStartupFilter>());
return services;
}
}
}

View File

@ -0,0 +1,27 @@
// 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 Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
namespace Microsoft.AspNet.MiddlewareAnalysis
{
public class AnalysisStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return builder =>
{
var wrappedBuilder = new AnalysisBuilder(builder);
next(wrappedBuilder);
// The caller doesn't call build on our new builder, they call it on the original. Add this
// default middleware to the end. Compare with AnalysisBuilder.Build();
// Add one maker at the end before the default 404 middleware (or any fancy Join middleware).
builder.UseMiddleware<AnalysisMiddleware>("EndOfPipeline");
};
}
}
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>c2dedd37-d1eb-4819-9a9c-475e37a52358</ProjectGuid>
<RootNamespace>Microsoft.AspNet.MiddlewareAnalysis</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View File

@ -0,0 +1,8 @@
// 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.Reflection;
using System.Resources;
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: NeutralResourcesLanguage("en-US")]

View File

@ -0,0 +1,22 @@
{
"version": "1.0.0-*",
"description": "ASP.NET 5 Middleware for analyzing middleware in the request pipeline.",
"compilationOptions": {
"warningsAsErrors": true,
"keyFile": "../../tools/Key.snk"
},
"repository": {
"type": "git",
"url": "git://github.com/aspnet/diagnostics"
},
"dependencies": {
"Microsoft.AspNet.Hosting.Abstractions": "1.0.0-*",
"Microsoft.Extensions.DependencyInjection.Abstractions": "1.0.0-*",
"System.Diagnostics.DiagnosticSource": "4.0.0-beta-*"
},
"frameworks": {
"net451": { },
"dotnet5.4": { }
}
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0.23107" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.23107</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>b0166aed-738f-42ee-af4d-c487c8b21521</ProjectGuid>
<RootNamespace>Microsoft.AspNet.MiddlewareAnalysis.Tests</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View File

@ -0,0 +1,49 @@
// 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.Diagnostics;
using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
namespace Microsoft.AspNet.MiddlewareAnalysis
{
public class MiddlewareAnalysisTests
{
[Fact]
public async Task ExceptionWrittenToDiagnostics()
{
DiagnosticListener diagnosticListener = null;
var server = TestServer.Create(app =>
{
diagnosticListener = app.ApplicationServices.GetRequiredService<DiagnosticListener>();
app.UseDeveloperExceptionPage();
app.Run(context =>
{
throw new Exception("Test exception");
});
}, services => services.AddMiddlewareAnalysis());
var listener = new TestDiagnosticListener();
diagnosticListener.SubscribeWithAdapter(listener);
await server.CreateClient().GetAsync(string.Empty);
// "Microsoft.AspnNet.Hosting.RequestServicesContainerMiddleware","Microsoft.AspnNet.Diagnostics.DeveloperExceptionPageMiddleware",
// "Microsoft.AspNet.MiddlewareAnalysis.MiddlewareAnalysisTests.+<>c"
Assert.Equal(3, listener.MiddlewareStarting.Count);
Assert.Equal("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareAnalysisTests+<>c", listener.MiddlewareStarting[2]);
// reversed "RunInlineMiddleware"
Assert.Equal(1, listener.MiddlewareException.Count);
Assert.Equal("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareAnalysisTests+<>c", listener.MiddlewareException[0]);
// reversed "Microsoft.AspnNet.Diagnostics.DeveloperExceptionPageMiddleware","Microsoft.AspnNet.Hosting.RequestServicesContainerMiddleware"
Assert.Equal(2, listener.MiddlewareFinished.Count);
Assert.Equal("Microsoft.AspNet.Diagnostics.DeveloperExceptionPageMiddleware", listener.MiddlewareFinished[0]);
}
}
}

View File

@ -0,0 +1,35 @@
// 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.Collections.Generic;
using Microsoft.AspNet.Http;
using Microsoft.Extensions.DiagnosticAdapter;
namespace Microsoft.AspNet.MiddlewareAnalysis
{
public class TestDiagnosticListener
{
public IList<string> MiddlewareStarting { get; } = new List<string>();
public IList<string> MiddlewareFinished { get; } = new List<string>();
public IList<string> MiddlewareException { get; } = new List<string>();
[DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareStarting")]
public virtual void OnMiddlewareStarting(HttpContext httpContext, string name)
{
MiddlewareStarting.Add(name);
}
[DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareException")]
public virtual void OnMiddlewareException(Exception exception, string name)
{
MiddlewareException.Add(name);
}
[DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareFinished")]
public virtual void OnMiddlewareFinished(HttpContext httpContext, string name)
{
MiddlewareFinished.Add(name);
}
}
}

View File

@ -0,0 +1,21 @@
{
"compilationOptions": {
"warningsAsErrors": false
},
"dependencies": {
"Microsoft.AspNet.Diagnostics": "1.0.0-*",
"Microsoft.AspNet.MiddlewareAnalysis": "1.0.0-*",
"Microsoft.AspNet.TestHost": "1.0.0-*",
"Microsoft.AspNet.Testing": "1.0.0-*",
"Microsoft.Extensions.DependencyInjection": "1.0.0-*",
"Microsoft.Extensions.DiagnosticAdapter": "1.0.0-*",
"xunit.runner.aspnet": "2.0.0-aspnet-*"
},
"frameworks": {
"dnx451": {},
"dnxcore50": {}
},
"commands": {
"test": "xunit.runner.aspnet"
}
}