diff --git a/.gitignore b/.gitignore
index d4c74d550..254707bad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,36 +19,34 @@ _ReSharper.*
/TestResult.xml
/builds/local/
*.dotCover
-/source/Glimpse.WebForms.WingTip.Sample/App_Data/ErrorLog.txt
-/source/Glimpse.Mvc3.MusicStore.Sample/App_Data/ASPNETDB.MDF
-/source/Glimpse.Mvc3.MusicStore.Sample/App_Data/ASPNETDB_log.ldf
-/source/Glimpse.Mvc3.MusicStore.Sample/App_Data/MvcMusicStore.sdf
/Packages.dgml
/packages
/.nuget/NuGet.Config
+*.sln.ide
TestResults
/*.DotSettings.user
*.DotSettings
*.shfbproj_*
working/
Help/
-/source/Glimpse.WebForms.WingTip.Sample/App_Data/wingtiptoys.mdf
-/source/Glimpse.WebForms.WingTip.Sample/App_Data/wingtiptoys_log.ldf
-/source/Glimpse.WebForms.WingTip.Sample/App_Data/ErrorLog.txt
/source/Glimpse.Core.Net45/NuSpec/lib/net45/Glimpse.Core.dll
-
/source/Glimpse.Core.Net45/NuSpec/lib/net45/Glimpse.Core.pdb
/source/Glimpse.AspNet.Net45/NuSpec/lib/net45/Glimpse.AspNet.dll
-
/source/Glimpse.AspNet.Net45/NuSpec/lib/net45/Glimpse.AspNet.pdb
-/source/Glimpse.Mvc4.MusicStore.Sample/App_Data/ASPNETDB.MDF
+/source/Glimpse.Mvc3.MusicStore.Sample/App_Data/ASPNETDB.MDF
+/source/Glimpse.Mvc3.MusicStore.Sample/App_Data/ASPNETDB_log.ldf
+/source/Glimpse.Mvc3.MusicStore.Sample/App_Data/MvcMusicStore.sdf
+/source/Glimpse.Mvc4.MusicStore.Sample/App_Data/ASPNETDB.MDF
/source/Glimpse.Mvc4.MusicStore.Sample/App_Data/ASPNETDB_log.ldf
-
/source/Glimpse.Mvc4.MusicStore.Sample/App_Data/MvcMusicStore.mdf
-
/source/Glimpse.Mvc4.MusicStore.Sample/App_Data/MvcMusicStore_log.ldf
+/source/Glimpse.WebForms.WingTip.Sample/App_Data/wingtiptoys.mdf
+/source/Glimpse.WebForms.WingTip.Sample/App_Data/wingtiptoys_log.ldf
+/source/Glimpse.WebForms.WingTip.Sample/App_Data/ErrorLog.txt
+/source/Glimpse.WebForms.WingTip.Sample/App_Data/ErrorLog.txt
+
csx/
\ No newline at end of file
diff --git a/Glimpse.All.sln b/Glimpse.All.sln
index 9334382be..9c806325d 100644
--- a/Glimpse.All.sln
+++ b/Glimpse.All.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.30501.0
+# Visual Studio 14
+VisualStudioVersion = 14.0.22129.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{CCFACE51-18FA-4C5D-9F89-EC58881786A9}"
EndProject
@@ -12,8 +12,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Legacy Support", "Legacy Su
source\ReadMe.txt = source\ReadMe.txt
EndProjectSection
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{13FEFF53-9CD2-4BF1-9128-A60F99E5532F}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.AspNet", "source\Glimpse.AspNet\Glimpse.AspNet.csproj", "{FDDFC8A6-CDDF-4BC6-9F07-E76050E1EEE7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Core", "source\Glimpse.Core\Glimpse.Core.csproj", "{C1289CE8-3259-41D9-893E-7A4E6F772D30}"
@@ -28,20 +26,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Test.Mvc", "source\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Mvc3.MusicStore.Sample", "source\Glimpse.Mvc3.MusicStore.Sample\Glimpse.Mvc3.MusicStore.Sample.csproj", "{32DCD27D-A84C-4250-B657-408B3620A9AC}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Core.Net35", "source\Glimpse.Core.Net35\Glimpse.Core.Net35.csproj", "{22E8C0B0-E32F-4598-896F-81F3A6BD9862}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Test.Core.Net35", "source\Glimpse.Test.Core.Net35\Glimpse.Test.Core.Net35.csproj", "{E242E3FC-DEF4-45E2-A129-A5DC3B0B8F9B}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.AspNet.Net35", "source\Glimpse.AspNet.Net35\Glimpse.AspNet.Net35.csproj", "{971143D1-B40E-4AF4-AD3D-D4FFAD3FE444}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{0352975D-08B7-435E-B444-A77292D4F6E1}"
- ProjectSection(SolutionItems) = preProject
- .nuget\NuGet.exe = .nuget\NuGet.exe
- .nuget\packages.config = .nuget\packages.config
- EndProjectSection
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Mvc2", "source\Glimpse.Mvc2\Glimpse.Mvc2.csproj", "{6B8B535F-923B-4083-A5BD-31A34F5230A1}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Test.Common", "source\Glimpse.Test.Common\Glimpse.Test.Common.csproj", "{BC28BB90-8BF2-4D54-B96E-0E0181DDF432}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Ado", "source\Glimpse.Ado\Glimpse.Ado.csproj", "{4C993B73-D03A-4080-B31E-C04F23372997}"
@@ -66,8 +50,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Ado.Net45", "source
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Ado.Net40", "source\Glimpse.Ado.Net40\Glimpse.Ado.Net40.csproj", "{EE152A2E-E27F-4329-A40A-6951387D3629}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Ado.Net35", "source\Glimpse.Ado.Net35\Glimpse.Ado.Net35.csproj", "{4E0483E0-A87C-40C6-A82E-078D1DF8C0AC}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.EF5.Net40", "source\Glimpse.EF5.Net40\Glimpse.EF5.Net40.csproj", "{8BAAD0C1-E44B-4E1B-9206-A1D8B9CD4870}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.EF5.Net45", "source\Glimpse.EF5.Net45\Glimpse.EF5.Net45.csproj", "{9A9DDFC7-B342-4E2E-99D6-2657AB8E3627}"
@@ -80,47 +62,46 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.EF43.Net40", "sourc
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.WebForms.WingTip.Sample", "source\Glimpse.WebForms.WingTip.Sample\Glimpse.WebForms.WingTip.Sample.csproj", "{214472C2-5C93-440A-8E14-BADC49CA6FE6}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Owin.Sample", "source\Glimpse.Owin.Sample\Glimpse.Owin.Sample.csproj", "{FFA64A97-2263-4F0C-9FD9-32520EA402F2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Owin", "source\Glimpse.Owin\Glimpse.Owin.csproj", "{6A99983E-130E-43B0-85F5-59CA4AA7E54E}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Mvc5", "source\Glimpse.Mvc5\Glimpse.Mvc5.csproj", "{BCDCF0D0-77CF-4589-BE46-C86FE11781E5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.WebForms", "source\Glimpse.WebForms\Glimpse.WebForms.csproj", "{3F948157-7469-45F1-A453-B0D9095EAE51}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.WebForms.Net35", "source\Glimpse.WebForms.Net35\Glimpse.WebForms.Net35.csproj", "{971143D1-B40E-4AF4-AD3D-D4FFAD3FE555}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.WebForms.Net40", "source\Glimpse.WebForms.Net40\Glimpse.WebForms.Net40.csproj", "{DED28E26-8A57-472A-A454-E45643F1D555}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.WebForms.Net45", "source\Glimpse.WebForms.Net45\Glimpse.WebForms.Net45.csproj", "{DD576747-CD93-43F0-8648-6CDC5CD9C555}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.WindowsAzure", "source\Glimpse.WindowsAzure\Glimpse.WindowsAzure.csproj", "{310D2FEA-6B20-4D2E-869D-EC3B578FF552}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.WindowsAzure.Caching", "source\Glimpse.WindowsAzure.Caching\Glimpse.WindowsAzure.Caching.csproj", "{C58BDD08-9093-43AC-9AEE-0DE2CF15DBEF}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.WindowsAzure.ServiceBus", "source\Glimpse.WindowsAzure.ServiceBus\Glimpse.WindowsAzure.ServiceBus.csproj", "{74538019-5CD0-4FCE-8D26-09F93E4E2A8C}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.WindowsAzure.Storage", "source\Glimpse.WindowsAzure.Storage\Glimpse.WindowsAzure.Storage.csproj", "{2E11865D-5484-4C3C-9C4B-940D8FCE043A}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.WindowsAzure.Net40", "source\Glimpse.WindowsAzure.Net40\Glimpse.WindowsAzure.Net40.csproj", "{C0A9A534-5DC9-4A26-952B-71D43160B597}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.WindowsAzure.ServiceBus.Net40", "source\Glimpse.WindowsAzure.ServiceBus.Net40\Glimpse.WindowsAzure.ServiceBus.Net40.csproj", "{D0A04D21-2403-4458-905E-027F6651823D}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.WindowsAzure.Caching.Net40", "source\Glimpse.WindowsAzure.Caching.Net40\Glimpse.WindowsAzure.Caching.Net40.csproj", "{98DDA3F0-13CC-428E-ABC0-0729C7C55F80}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.WindowsAzure.Storage.Net40", "source\Glimpse.WindowsAzure.Storage.Net40\Glimpse.WindowsAzure.Storage.Net40.csproj", "{DB3BB9CB-F577-42E8-8108-DB17EA0DE113}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WindowsAzure", "WindowsAzure", "{4288D838-C35F-4226-AEAD-766A19CF31CD}"
-EndProject
-Project("{CC5FD16D-436D-48AD-A40C-5A424C6E3E79}") = "Glimpse.WindowsAzure.Sample", "source\Glimpse.WindowsAzure.Sample\Glimpse.WindowsAzure.Sample.ccproj", "{9872CF80-D354-4A19-A28B-B5FE62DA3DF5}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.WindowsAzure.WebRole.Sample", "source\Glimpse.WindowsAzure.WebRole.Sample\Glimpse.WindowsAzure.WebRole.Sample.csproj", "{FE76DB8B-5FE3-4F25-B816-4EF2E6F20FFB}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Mvc5.MusicStore.Sample", "source\Glimpse.Mvc5.MusicStore.Sample\Glimpse.Mvc5.MusicStore.Sample.csproj", "{B373218F-19BB-4D5E-9EA7-000FDFD9BE5D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".items", ".items", "{EC933034-7250-4B53-A041-0D5DF203712B}"
ProjectSection(SolutionItems) = preProject
+ .gitattributes = .gitattributes
+ .gitignore = .gitignore
+ contributing.md = contributing.md
+ default.ps1 = default.ps1
+ global.json = global.json
+ ILMergeInternalize.txt = ILMergeInternalize.txt
+ integration.xunit = integration.xunit
+ license.txt = license.txt
+ MyGet.bat = MyGet.bat
+ NuGet.config = NuGet.config
+ psake.bat = psake.bat
+ README.markdown = README.markdown
source\Settings.StyleCop = source\Settings.StyleCop
+ tests.xunit = tests.xunit
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Glimpse.Test.Ado", "Glimpse.Test.Ado\Glimpse.Test.Ado.csproj", "{A38DA38F-8669-4B99-9DE8-51BF747B9A67}"
EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Glimpse.AspNet5.Sample", "source\Glimpse.AspNet5.Sample\Glimpse.AspNet5.Sample.kproj", "{38A85F8E-FDA5-42B0-A2A7-03FC14822AE6}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Glimpse.AspNet5", "source\Glimpse.AspNet5\Glimpse.AspNet5.kproj", "{A056721B-D6C0-44B6-AB1A-5C0481B354BC}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Glimpse.Core.AspNet5", "source\Glimpse.Core\Glimpse.Core.AspNet5.kproj", "{A9463C9B-74C2-4AD4-8DCB-51E6D07760B5}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -201,46 +182,6 @@ Global
{32DCD27D-A84C-4250-B657-408B3620A9AC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{32DCD27D-A84C-4250-B657-408B3620A9AC}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{32DCD27D-A84C-4250-B657-408B3620A9AC}.Release|x86.ActiveCfg = Release|Any CPU
- {22E8C0B0-E32F-4598-896F-81F3A6BD9862}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {22E8C0B0-E32F-4598-896F-81F3A6BD9862}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {22E8C0B0-E32F-4598-896F-81F3A6BD9862}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {22E8C0B0-E32F-4598-896F-81F3A6BD9862}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {22E8C0B0-E32F-4598-896F-81F3A6BD9862}.Debug|x86.ActiveCfg = Debug|Any CPU
- {22E8C0B0-E32F-4598-896F-81F3A6BD9862}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {22E8C0B0-E32F-4598-896F-81F3A6BD9862}.Release|Any CPU.Build.0 = Release|Any CPU
- {22E8C0B0-E32F-4598-896F-81F3A6BD9862}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {22E8C0B0-E32F-4598-896F-81F3A6BD9862}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {22E8C0B0-E32F-4598-896F-81F3A6BD9862}.Release|x86.ActiveCfg = Release|Any CPU
- {E242E3FC-DEF4-45E2-A129-A5DC3B0B8F9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E242E3FC-DEF4-45E2-A129-A5DC3B0B8F9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E242E3FC-DEF4-45E2-A129-A5DC3B0B8F9B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {E242E3FC-DEF4-45E2-A129-A5DC3B0B8F9B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {E242E3FC-DEF4-45E2-A129-A5DC3B0B8F9B}.Debug|x86.ActiveCfg = Debug|Any CPU
- {E242E3FC-DEF4-45E2-A129-A5DC3B0B8F9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E242E3FC-DEF4-45E2-A129-A5DC3B0B8F9B}.Release|Any CPU.Build.0 = Release|Any CPU
- {E242E3FC-DEF4-45E2-A129-A5DC3B0B8F9B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {E242E3FC-DEF4-45E2-A129-A5DC3B0B8F9B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {E242E3FC-DEF4-45E2-A129-A5DC3B0B8F9B}.Release|x86.ActiveCfg = Release|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE444}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE444}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE444}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE444}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE444}.Debug|x86.ActiveCfg = Debug|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE444}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE444}.Release|Any CPU.Build.0 = Release|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE444}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE444}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE444}.Release|x86.ActiveCfg = Release|Any CPU
- {6B8B535F-923B-4083-A5BD-31A34F5230A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6B8B535F-923B-4083-A5BD-31A34F5230A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6B8B535F-923B-4083-A5BD-31A34F5230A1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {6B8B535F-923B-4083-A5BD-31A34F5230A1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {6B8B535F-923B-4083-A5BD-31A34F5230A1}.Debug|x86.ActiveCfg = Debug|Any CPU
- {6B8B535F-923B-4083-A5BD-31A34F5230A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6B8B535F-923B-4083-A5BD-31A34F5230A1}.Release|Any CPU.Build.0 = Release|Any CPU
- {6B8B535F-923B-4083-A5BD-31A34F5230A1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {6B8B535F-923B-4083-A5BD-31A34F5230A1}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {6B8B535F-923B-4083-A5BD-31A34F5230A1}.Release|x86.ActiveCfg = Release|Any CPU
{BC28BB90-8BF2-4D54-B96E-0E0181DDF432}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BC28BB90-8BF2-4D54-B96E-0E0181DDF432}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BC28BB90-8BF2-4D54-B96E-0E0181DDF432}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -361,16 +302,6 @@ Global
{EE152A2E-E27F-4329-A40A-6951387D3629}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{EE152A2E-E27F-4329-A40A-6951387D3629}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{EE152A2E-E27F-4329-A40A-6951387D3629}.Release|x86.ActiveCfg = Release|Any CPU
- {4E0483E0-A87C-40C6-A82E-078D1DF8C0AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4E0483E0-A87C-40C6-A82E-078D1DF8C0AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4E0483E0-A87C-40C6-A82E-078D1DF8C0AC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {4E0483E0-A87C-40C6-A82E-078D1DF8C0AC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {4E0483E0-A87C-40C6-A82E-078D1DF8C0AC}.Debug|x86.ActiveCfg = Debug|Any CPU
- {4E0483E0-A87C-40C6-A82E-078D1DF8C0AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4E0483E0-A87C-40C6-A82E-078D1DF8C0AC}.Release|Any CPU.Build.0 = Release|Any CPU
- {4E0483E0-A87C-40C6-A82E-078D1DF8C0AC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {4E0483E0-A87C-40C6-A82E-078D1DF8C0AC}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {4E0483E0-A87C-40C6-A82E-078D1DF8C0AC}.Release|x86.ActiveCfg = Release|Any CPU
{8BAAD0C1-E44B-4E1B-9206-A1D8B9CD4870}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8BAAD0C1-E44B-4E1B-9206-A1D8B9CD4870}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8BAAD0C1-E44B-4E1B-9206-A1D8B9CD4870}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -431,6 +362,26 @@ Global
{214472C2-5C93-440A-8E14-BADC49CA6FE6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{214472C2-5C93-440A-8E14-BADC49CA6FE6}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{214472C2-5C93-440A-8E14-BADC49CA6FE6}.Release|x86.ActiveCfg = Release|Any CPU
+ {FFA64A97-2263-4F0C-9FD9-32520EA402F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FFA64A97-2263-4F0C-9FD9-32520EA402F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FFA64A97-2263-4F0C-9FD9-32520EA402F2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {FFA64A97-2263-4F0C-9FD9-32520EA402F2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {FFA64A97-2263-4F0C-9FD9-32520EA402F2}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FFA64A97-2263-4F0C-9FD9-32520EA402F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FFA64A97-2263-4F0C-9FD9-32520EA402F2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FFA64A97-2263-4F0C-9FD9-32520EA402F2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {FFA64A97-2263-4F0C-9FD9-32520EA402F2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {FFA64A97-2263-4F0C-9FD9-32520EA402F2}.Release|x86.ActiveCfg = Release|Any CPU
+ {6A99983E-130E-43B0-85F5-59CA4AA7E54E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6A99983E-130E-43B0-85F5-59CA4AA7E54E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6A99983E-130E-43B0-85F5-59CA4AA7E54E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {6A99983E-130E-43B0-85F5-59CA4AA7E54E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {6A99983E-130E-43B0-85F5-59CA4AA7E54E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6A99983E-130E-43B0-85F5-59CA4AA7E54E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6A99983E-130E-43B0-85F5-59CA4AA7E54E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6A99983E-130E-43B0-85F5-59CA4AA7E54E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {6A99983E-130E-43B0-85F5-59CA4AA7E54E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {6A99983E-130E-43B0-85F5-59CA4AA7E54E}.Release|x86.ActiveCfg = Release|Any CPU
{BCDCF0D0-77CF-4589-BE46-C86FE11781E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BCDCF0D0-77CF-4589-BE46-C86FE11781E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BCDCF0D0-77CF-4589-BE46-C86FE11781E5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -451,16 +402,6 @@ Global
{3F948157-7469-45F1-A453-B0D9095EAE51}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{3F948157-7469-45F1-A453-B0D9095EAE51}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{3F948157-7469-45F1-A453-B0D9095EAE51}.Release|x86.ActiveCfg = Release|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE555}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE555}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE555}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE555}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE555}.Debug|x86.ActiveCfg = Debug|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE555}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE555}.Release|Any CPU.Build.0 = Release|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE555}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE555}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE555}.Release|x86.ActiveCfg = Release|Any CPU
{DED28E26-8A57-472A-A454-E45643F1D555}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DED28E26-8A57-472A-A454-E45643F1D555}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DED28E26-8A57-472A-A454-E45643F1D555}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -481,113 +422,11 @@ Global
{DD576747-CD93-43F0-8648-6CDC5CD9C555}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{DD576747-CD93-43F0-8648-6CDC5CD9C555}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{DD576747-CD93-43F0-8648-6CDC5CD9C555}.Release|x86.ActiveCfg = Release|Any CPU
- {310D2FEA-6B20-4D2E-869D-EC3B578FF552}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {310D2FEA-6B20-4D2E-869D-EC3B578FF552}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {310D2FEA-6B20-4D2E-869D-EC3B578FF552}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {310D2FEA-6B20-4D2E-869D-EC3B578FF552}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {310D2FEA-6B20-4D2E-869D-EC3B578FF552}.Debug|x86.ActiveCfg = Debug|Any CPU
- {310D2FEA-6B20-4D2E-869D-EC3B578FF552}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {310D2FEA-6B20-4D2E-869D-EC3B578FF552}.Release|Any CPU.Build.0 = Release|Any CPU
- {310D2FEA-6B20-4D2E-869D-EC3B578FF552}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {310D2FEA-6B20-4D2E-869D-EC3B578FF552}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {310D2FEA-6B20-4D2E-869D-EC3B578FF552}.Release|x86.ActiveCfg = Release|Any CPU
- {C58BDD08-9093-43AC-9AEE-0DE2CF15DBEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C58BDD08-9093-43AC-9AEE-0DE2CF15DBEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C58BDD08-9093-43AC-9AEE-0DE2CF15DBEF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {C58BDD08-9093-43AC-9AEE-0DE2CF15DBEF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {C58BDD08-9093-43AC-9AEE-0DE2CF15DBEF}.Debug|x86.ActiveCfg = Debug|Any CPU
- {C58BDD08-9093-43AC-9AEE-0DE2CF15DBEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C58BDD08-9093-43AC-9AEE-0DE2CF15DBEF}.Release|Any CPU.Build.0 = Release|Any CPU
- {C58BDD08-9093-43AC-9AEE-0DE2CF15DBEF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {C58BDD08-9093-43AC-9AEE-0DE2CF15DBEF}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {C58BDD08-9093-43AC-9AEE-0DE2CF15DBEF}.Release|x86.ActiveCfg = Release|Any CPU
- {74538019-5CD0-4FCE-8D26-09F93E4E2A8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {74538019-5CD0-4FCE-8D26-09F93E4E2A8C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {74538019-5CD0-4FCE-8D26-09F93E4E2A8C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {74538019-5CD0-4FCE-8D26-09F93E4E2A8C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {74538019-5CD0-4FCE-8D26-09F93E4E2A8C}.Debug|x86.ActiveCfg = Debug|Any CPU
- {74538019-5CD0-4FCE-8D26-09F93E4E2A8C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {74538019-5CD0-4FCE-8D26-09F93E4E2A8C}.Release|Any CPU.Build.0 = Release|Any CPU
- {74538019-5CD0-4FCE-8D26-09F93E4E2A8C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {74538019-5CD0-4FCE-8D26-09F93E4E2A8C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {74538019-5CD0-4FCE-8D26-09F93E4E2A8C}.Release|x86.ActiveCfg = Release|Any CPU
- {2E11865D-5484-4C3C-9C4B-940D8FCE043A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2E11865D-5484-4C3C-9C4B-940D8FCE043A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2E11865D-5484-4C3C-9C4B-940D8FCE043A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {2E11865D-5484-4C3C-9C4B-940D8FCE043A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {2E11865D-5484-4C3C-9C4B-940D8FCE043A}.Debug|x86.ActiveCfg = Debug|Any CPU
- {2E11865D-5484-4C3C-9C4B-940D8FCE043A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2E11865D-5484-4C3C-9C4B-940D8FCE043A}.Release|Any CPU.Build.0 = Release|Any CPU
- {2E11865D-5484-4C3C-9C4B-940D8FCE043A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {2E11865D-5484-4C3C-9C4B-940D8FCE043A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {2E11865D-5484-4C3C-9C4B-940D8FCE043A}.Release|x86.ActiveCfg = Release|Any CPU
- {C0A9A534-5DC9-4A26-952B-71D43160B597}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C0A9A534-5DC9-4A26-952B-71D43160B597}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C0A9A534-5DC9-4A26-952B-71D43160B597}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {C0A9A534-5DC9-4A26-952B-71D43160B597}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {C0A9A534-5DC9-4A26-952B-71D43160B597}.Debug|x86.ActiveCfg = Debug|Any CPU
- {C0A9A534-5DC9-4A26-952B-71D43160B597}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C0A9A534-5DC9-4A26-952B-71D43160B597}.Release|Any CPU.Build.0 = Release|Any CPU
- {C0A9A534-5DC9-4A26-952B-71D43160B597}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {C0A9A534-5DC9-4A26-952B-71D43160B597}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {C0A9A534-5DC9-4A26-952B-71D43160B597}.Release|x86.ActiveCfg = Release|Any CPU
- {D0A04D21-2403-4458-905E-027F6651823D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D0A04D21-2403-4458-905E-027F6651823D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D0A04D21-2403-4458-905E-027F6651823D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {D0A04D21-2403-4458-905E-027F6651823D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {D0A04D21-2403-4458-905E-027F6651823D}.Debug|x86.ActiveCfg = Debug|Any CPU
- {D0A04D21-2403-4458-905E-027F6651823D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D0A04D21-2403-4458-905E-027F6651823D}.Release|Any CPU.Build.0 = Release|Any CPU
- {D0A04D21-2403-4458-905E-027F6651823D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {D0A04D21-2403-4458-905E-027F6651823D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {D0A04D21-2403-4458-905E-027F6651823D}.Release|x86.ActiveCfg = Release|Any CPU
- {98DDA3F0-13CC-428E-ABC0-0729C7C55F80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {98DDA3F0-13CC-428E-ABC0-0729C7C55F80}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {98DDA3F0-13CC-428E-ABC0-0729C7C55F80}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {98DDA3F0-13CC-428E-ABC0-0729C7C55F80}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {98DDA3F0-13CC-428E-ABC0-0729C7C55F80}.Debug|x86.ActiveCfg = Debug|Any CPU
- {98DDA3F0-13CC-428E-ABC0-0729C7C55F80}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {98DDA3F0-13CC-428E-ABC0-0729C7C55F80}.Release|Any CPU.Build.0 = Release|Any CPU
- {98DDA3F0-13CC-428E-ABC0-0729C7C55F80}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {98DDA3F0-13CC-428E-ABC0-0729C7C55F80}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {98DDA3F0-13CC-428E-ABC0-0729C7C55F80}.Release|x86.ActiveCfg = Release|Any CPU
- {DB3BB9CB-F577-42E8-8108-DB17EA0DE113}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DB3BB9CB-F577-42E8-8108-DB17EA0DE113}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DB3BB9CB-F577-42E8-8108-DB17EA0DE113}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {DB3BB9CB-F577-42E8-8108-DB17EA0DE113}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {DB3BB9CB-F577-42E8-8108-DB17EA0DE113}.Debug|x86.ActiveCfg = Debug|Any CPU
- {DB3BB9CB-F577-42E8-8108-DB17EA0DE113}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DB3BB9CB-F577-42E8-8108-DB17EA0DE113}.Release|Any CPU.Build.0 = Release|Any CPU
- {DB3BB9CB-F577-42E8-8108-DB17EA0DE113}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {DB3BB9CB-F577-42E8-8108-DB17EA0DE113}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {DB3BB9CB-F577-42E8-8108-DB17EA0DE113}.Release|x86.ActiveCfg = Release|Any CPU
- {9872CF80-D354-4A19-A28B-B5FE62DA3DF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9872CF80-D354-4A19-A28B-B5FE62DA3DF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9872CF80-D354-4A19-A28B-B5FE62DA3DF5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {9872CF80-D354-4A19-A28B-B5FE62DA3DF5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {9872CF80-D354-4A19-A28B-B5FE62DA3DF5}.Debug|x86.ActiveCfg = Debug|Any CPU
- {9872CF80-D354-4A19-A28B-B5FE62DA3DF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9872CF80-D354-4A19-A28B-B5FE62DA3DF5}.Release|Any CPU.Build.0 = Release|Any CPU
- {9872CF80-D354-4A19-A28B-B5FE62DA3DF5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {9872CF80-D354-4A19-A28B-B5FE62DA3DF5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {9872CF80-D354-4A19-A28B-B5FE62DA3DF5}.Release|x86.ActiveCfg = Release|Any CPU
- {FE76DB8B-5FE3-4F25-B816-4EF2E6F20FFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {FE76DB8B-5FE3-4F25-B816-4EF2E6F20FFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {FE76DB8B-5FE3-4F25-B816-4EF2E6F20FFB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {FE76DB8B-5FE3-4F25-B816-4EF2E6F20FFB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {FE76DB8B-5FE3-4F25-B816-4EF2E6F20FFB}.Debug|x86.ActiveCfg = Debug|Any CPU
- {FE76DB8B-5FE3-4F25-B816-4EF2E6F20FFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {FE76DB8B-5FE3-4F25-B816-4EF2E6F20FFB}.Release|Any CPU.Build.0 = Release|Any CPU
- {FE76DB8B-5FE3-4F25-B816-4EF2E6F20FFB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {FE76DB8B-5FE3-4F25-B816-4EF2E6F20FFB}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {FE76DB8B-5FE3-4F25-B816-4EF2E6F20FFB}.Release|x86.ActiveCfg = Release|Any CPU
{B373218F-19BB-4D5E-9EA7-000FDFD9BE5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B373218F-19BB-4D5E-9EA7-000FDFD9BE5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B373218F-19BB-4D5E-9EA7-000FDFD9BE5D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{B373218F-19BB-4D5E-9EA7-000FDFD9BE5D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{B373218F-19BB-4D5E-9EA7-000FDFD9BE5D}.Debug|x86.ActiveCfg = Debug|Any CPU
{B373218F-19BB-4D5E-9EA7-000FDFD9BE5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B373218F-19BB-4D5E-9EA7-000FDFD9BE5D}.Release|Any CPU.Build.0 = Release|Any CPU
{B373218F-19BB-4D5E-9EA7-000FDFD9BE5D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{B373218F-19BB-4D5E-9EA7-000FDFD9BE5D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{B373218F-19BB-4D5E-9EA7-000FDFD9BE5D}.Release|x86.ActiveCfg = Release|Any CPU
@@ -601,20 +440,44 @@ Global
{A38DA38F-8669-4B99-9DE8-51BF747B9A67}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{A38DA38F-8669-4B99-9DE8-51BF747B9A67}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{A38DA38F-8669-4B99-9DE8-51BF747B9A67}.Release|x86.ActiveCfg = Release|Any CPU
+ {38A85F8E-FDA5-42B0-A2A7-03FC14822AE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {38A85F8E-FDA5-42B0-A2A7-03FC14822AE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {38A85F8E-FDA5-42B0-A2A7-03FC14822AE6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {38A85F8E-FDA5-42B0-A2A7-03FC14822AE6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {38A85F8E-FDA5-42B0-A2A7-03FC14822AE6}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {38A85F8E-FDA5-42B0-A2A7-03FC14822AE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {38A85F8E-FDA5-42B0-A2A7-03FC14822AE6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {38A85F8E-FDA5-42B0-A2A7-03FC14822AE6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {38A85F8E-FDA5-42B0-A2A7-03FC14822AE6}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {38A85F8E-FDA5-42B0-A2A7-03FC14822AE6}.Release|x86.ActiveCfg = Release|Any CPU
+ {A056721B-D6C0-44B6-AB1A-5C0481B354BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A056721B-D6C0-44B6-AB1A-5C0481B354BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A056721B-D6C0-44B6-AB1A-5C0481B354BC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {A056721B-D6C0-44B6-AB1A-5C0481B354BC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {A056721B-D6C0-44B6-AB1A-5C0481B354BC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A056721B-D6C0-44B6-AB1A-5C0481B354BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A056721B-D6C0-44B6-AB1A-5C0481B354BC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A056721B-D6C0-44B6-AB1A-5C0481B354BC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {A056721B-D6C0-44B6-AB1A-5C0481B354BC}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {A056721B-D6C0-44B6-AB1A-5C0481B354BC}.Release|x86.ActiveCfg = Release|Any CPU
+ {A9463C9B-74C2-4AD4-8DCB-51E6D07760B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A9463C9B-74C2-4AD4-8DCB-51E6D07760B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A9463C9B-74C2-4AD4-8DCB-51E6D07760B5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {A9463C9B-74C2-4AD4-8DCB-51E6D07760B5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {A9463C9B-74C2-4AD4-8DCB-51E6D07760B5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A9463C9B-74C2-4AD4-8DCB-51E6D07760B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A9463C9B-74C2-4AD4-8DCB-51E6D07760B5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A9463C9B-74C2-4AD4-8DCB-51E6D07760B5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {A9463C9B-74C2-4AD4-8DCB-51E6D07760B5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {A9463C9B-74C2-4AD4-8DCB-51E6D07760B5}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {13FEFF53-9CD2-4BF1-9128-A60F99E5532F} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
{9923BFBD-EA73-4719-A418-213003862550} = {A3097EAF-9D1B-416A-822E-F679D768BC55}
{76714E46-AFE9-49F0-AEE8-C8A966195914} = {A3097EAF-9D1B-416A-822E-F679D768BC55}
- {FE12BC0C-CD22-4D24-BFC7-13ED1C428BAD} = {A3097EAF-9D1B-416A-822E-F679D768BC55}
{32DCD27D-A84C-4250-B657-408B3620A9AC} = {CCFACE51-18FA-4C5D-9F89-EC58881786A9}
- {22E8C0B0-E32F-4598-896F-81F3A6BD9862} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
- {E242E3FC-DEF4-45E2-A129-A5DC3B0B8F9B} = {13FEFF53-9CD2-4BF1-9128-A60F99E5532F}
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE444} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
- {6B8B535F-923B-4083-A5BD-31A34F5230A1} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
{BC28BB90-8BF2-4D54-B96E-0E0181DDF432} = {A3097EAF-9D1B-416A-822E-F679D768BC55}
{DD93B23C-E2D7-4283-9F3F-88F87271018B} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
{2CB2400F-BC66-4074-B6E4-177A6F78163E} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
@@ -625,25 +488,18 @@ Global
{D3644A2E-1A2D-42DB-9646-8EDF2855C478} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
{1594ADD8-62F8-417B-BD69-131AFBBF51BC} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
{EE152A2E-E27F-4329-A40A-6951387D3629} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
- {4E0483E0-A87C-40C6-A82E-078D1DF8C0AC} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
{8BAAD0C1-E44B-4E1B-9206-A1D8B9CD4870} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
{9A9DDFC7-B342-4E2E-99D6-2657AB8E3627} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
{1C1FABFD-768A-4E03-88DD-14E04F6B4DD8} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
{90D8F914-7271-466E-8A87-218176C39719} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
{6F3F9D55-2BE0-47E8-83D2-0F488504CF4A} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
{214472C2-5C93-440A-8E14-BADC49CA6FE6} = {CCFACE51-18FA-4C5D-9F89-EC58881786A9}
+ {FFA64A97-2263-4F0C-9FD9-32520EA402F2} = {CCFACE51-18FA-4C5D-9F89-EC58881786A9}
{BCDCF0D0-77CF-4589-BE46-C86FE11781E5} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
- {971143D1-B40E-4AF4-AD3D-D4FFAD3FE555} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
{DED28E26-8A57-472A-A454-E45643F1D555} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
{DD576747-CD93-43F0-8648-6CDC5CD9C555} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
- {C0A9A534-5DC9-4A26-952B-71D43160B597} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
- {D0A04D21-2403-4458-905E-027F6651823D} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
- {98DDA3F0-13CC-428E-ABC0-0729C7C55F80} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
- {DB3BB9CB-F577-42E8-8108-DB17EA0DE113} = {44EAFB31-C422-4B52-BBCE-18A3E95713DC}
- {4288D838-C35F-4226-AEAD-766A19CF31CD} = {CCFACE51-18FA-4C5D-9F89-EC58881786A9}
- {9872CF80-D354-4A19-A28B-B5FE62DA3DF5} = {4288D838-C35F-4226-AEAD-766A19CF31CD}
- {FE76DB8B-5FE3-4F25-B816-4EF2E6F20FFB} = {4288D838-C35F-4226-AEAD-766A19CF31CD}
{B373218F-19BB-4D5E-9EA7-000FDFD9BE5D} = {CCFACE51-18FA-4C5D-9F89-EC58881786A9}
{A38DA38F-8669-4B99-9DE8-51BF747B9A67} = {A3097EAF-9D1B-416A-822E-F679D768BC55}
+ {38A85F8E-FDA5-42B0-A2A7-03FC14822AE6} = {CCFACE51-18FA-4C5D-9F89-EC58881786A9}
EndGlobalSection
EndGlobal
diff --git a/NuGet.config b/NuGet.config
new file mode 100644
index 000000000..f06f2bee9
--- /dev/null
+++ b/NuGet.config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/default.ps1 b/default.ps1
index 6aea1c647..3767efeea 100644
--- a/default.ps1
+++ b/default.ps1
@@ -33,9 +33,9 @@ task clean {
Delete-Directory "$source_dir\Glimpse.Core.Net40\bin"
Delete-Directory "$source_dir\Glimpse.Core.Net40\obj"
- " Glimpse.Core.Net35"
- Delete-Directory "$source_dir\Glimpse.Core.Net35\bin"
- Delete-Directory "$source_dir\Glimpse.Core.Net35\obj"
+ " Glimpse.Owin"
+ Delete-Directory "$source_dir\Glimpse.Owin\bin"
+ Delete-Directory "$source_dir\Glimpse.Owin\obj"
" Glimpse.AspNet"
Delete-Directory "$source_dir\Glimpse.AspNet\bin"
@@ -49,18 +49,10 @@ task clean {
Delete-Directory "$source_dir\Glimpse.AspNet.Net40\bin"
Delete-Directory "$source_dir\Glimpse.AspNet.Net40\obj"
- " Glimpse.AspNet.Net35"
- Delete-Directory "$source_dir\Glimpse.AspNet.Net35\bin"
- Delete-Directory "$source_dir\Glimpse.AspNet.Net35\obj"
-
" Glimpse.Mvc"
Delete-Directory "$source_dir\Glimpse.Mvc\bin"
Delete-Directory "$source_dir\Glimpse.Mvc\obj"
- " Glimpse.Mvc2"
- Delete-Directory "$source_dir\Glimpse.Mvc2\bin"
- Delete-Directory "$source_dir\Glimpse.Mvc2\obj"
-
" Glimpse.Mvc3"
Delete-Directory "$source_dir\Glimpse.Mvc3\bin"
Delete-Directory "$source_dir\Glimpse.Mvc3\obj"
@@ -89,18 +81,10 @@ task clean {
Delete-Directory "$source_dir\Glimpse.Ado\bin"
Delete-Directory "$source_dir\Glimpse.Ado\obj"
- " Glimpse.Ado.Net45"
- Delete-Directory "$source_dir\Glimpse.Ado.Net45\bin"
- Delete-Directory "$source_dir\Glimpse.Ado.Net45\obj"
-
" Glimpse.Ado.Net40"
Delete-Directory "$source_dir\Glimpse.Ado.Net40\bin"
Delete-Directory "$source_dir\Glimpse.Ado.Net40\obj"
- " Glimpse.Ado.Net35"
- Delete-Directory "$source_dir\Glimpse.Ado.Net35\bin"
- Delete-Directory "$source_dir\Glimpse.Ado.Net35\obj"
-
" Glimpse.EF"
Delete-Directory "$source_dir\Glimpse.EF\bin"
Delete-Directory "$source_dir\Glimpse.EF\obj"
@@ -137,18 +121,6 @@ task clean {
Delete-Directory "$source_dir\Glimpse.WebForms.Net40\bin"
Delete-Directory "$source_dir\Glimpse.WebForms.Net40\obj"
- " Glimpse.WebForms.Net35"
- Delete-Directory "$source_dir\Glimpse.WebForms.Net35\bin"
- Delete-Directory "$source_dir\Glimpse.WebForms.Net35\obj"
-
- " Glimpse.WindowsAzure.Net40"
- Delete-Directory "$source_dir\Glimpse.WindowsAzure.Net40\bin"
- Delete-Directory "$source_dir\Glimpse.WindowsAzure.Net40\obj"
-
- " Glimpse.WindowsAzure.Storage.Net40"
- Delete-Directory "$source_dir\Glimpse.WindowsAzure.Storage.Net40\bin"
- Delete-Directory "$source_dir\Glimpse.WindowsAzure.Storage.Net40\obj"
-
" Glimpse.Test.*"
Delete-Directory "$source_dir\Glimpse.Test.AspNet\bin"
Delete-Directory "$source_dir\Glimpse.Test.AspNet\obj"
@@ -156,9 +128,6 @@ task clean {
Delete-Directory "$source_dir\Glimpse.Test.Core\bin"
Delete-Directory "$source_dir\Glimpse.Test.Core\obj"
- Delete-Directory "$source_dir\Glimpse.Test.Core.Net35\bin"
- Delete-Directory "$source_dir\Glimpse.Test.Core.net35\obj"
-
Delete-Directory "$source_dir\Glimpse.Test.Mvc3\bin"
Delete-Directory "$source_dir\Glimpse.Test.Mvc3\obj"
}
@@ -188,9 +157,9 @@ task merge -depends test {
" Glimpse.Core.Net40"
exec { & .\ilmerge.exe /targetplatform:"v4,$framework_dir" /log /out:"$source_dir\Glimpse.Core.Net45\nuspec\lib\net40\Glimpse.Core.dll" /internalize:$base_dir\ILMergeInternalize.txt "$source_dir\Glimpse.Core.Net40\bin\Release\Glimpse.Core.dll" "$source_dir\Glimpse.Core.Net40\bin\Release\Newtonsoft.Json.dll" "$source_dir\Glimpse.Core.Net40\bin\Release\Castle.Core.dll" "$source_dir\Glimpse.Core.Net40\bin\Release\NLog.dll" "$source_dir\Glimpse.Core.Net40\bin\Release\AntiXssLibrary.dll" "$source_dir\Glimpse.Core.Net40\bin\Release\Tavis.UriTemplates.dll" "$source_dir\Glimpse.Core.Net45\bin\Release\Antlr4.StringTemplate.dll"}
-
- " Glimpse.Core.Net35"
- exec { & .\ilmerge.exe /log /out:"$source_dir\Glimpse.Core.Net45\nuspec\lib\net35\Glimpse.Core.dll" /internalize:$base_dir\ILMergeInternalize.txt "$source_dir\Glimpse.Core.Net35\bin\Release\Glimpse.Core.dll" "$source_dir\Glimpse.Core.Net35\bin\Release\Newtonsoft.Json.dll" "$source_dir\Glimpse.Core.Net35\bin\Release\Castle.Core.dll" "$source_dir\Glimpse.Core.Net35\bin\Release\NLog.dll" "$source_dir\Glimpse.Core.Net35\bin\Release\AntiXssLibrary.dll" "$source_dir\Glimpse.Core.Net35\bin\Release\Tavis.UriTemplates.dll" "$source_dir\Glimpse.Core.Net45\bin\Release\Antlr4.StringTemplate.dll"}
+
+ " Glimpse.Owin"
+ exec { & .\ilmerge.exe /targetplatform:"v4" /out:"$source_dir\Glimpse.Owin\nuspec\lib\net40\Glimpse.Owin.dll" /internalize "$source_dir\Glimpse.Owin\bin\Release\Glimpse.Owin.dll" "$source_dir\Glimpse.Owin\bin\Release\Microsoft.Owin.dll" }
" Glimpse.AspNet.Net45"
copy $source_dir\Glimpse.AspNet.Net45\bin\Release\Glimpse.AspNet.* $source_dir\Glimpse.AspNet.Net45\nuspec\lib\net45\
@@ -198,21 +167,12 @@ task merge -depends test {
" Glimpse.AspNet.Net40"
copy $source_dir\Glimpse.AspNet.Net40\bin\Release\Glimpse.AspNet.* $source_dir\Glimpse.AspNet.Net45\nuspec\lib\net40\
- " Glimpse.AspNet.Net35"
- copy $source_dir\Glimpse.AspNet.Net35\bin\Release\Glimpse.AspNet.* $source_dir\Glimpse.AspNet.Net45\nuspec\lib\net35\
-
" Glimpse.Ado.Net45"
copy $source_dir\Glimpse.Ado.Net45\bin\Release\Glimpse.Ado.* $source_dir\Glimpse.Ado.Net45\nuspec\lib\net45\
" Glimpse.Ado.Net40"
copy $source_dir\Glimpse.Ado.Net40\bin\Release\Glimpse.Ado.* $source_dir\Glimpse.Ado.Net45\nuspec\lib\net40\
- " Glimpse.Ado.Net35"
- copy $source_dir\Glimpse.Ado.Net35\bin\Release\Glimpse.Ado.* $source_dir\Glimpse.Ado.Net45\nuspec\lib\net35\
-
- " Glimpse.Mvc2"
- copy $source_dir\Glimpse.Mvc2\bin\Release\Glimpse.Mvc2.* $source_dir\Glimpse.Mvc2\nuspec\lib\net35\
-
" Glimpse.Mvc3"
copy $source_dir\Glimpse.Mvc3\bin\Release\Glimpse.Mvc3.* $source_dir\Glimpse.Mvc3\nuspec\lib\net40\
@@ -242,15 +202,6 @@ task merge -depends test {
" Glimpse.WebForms.Net40"
copy $source_dir\Glimpse.WebForms.Net40\bin\Release\Glimpse.WebForms.* $source_dir\Glimpse.WebForms.Net45\nuspec\lib\net40\
-
- " Glimpse.WebForms.Net35"
- copy $source_dir\Glimpse.WebForms.Net35\bin\Release\Glimpse.WebForms.* $source_dir\Glimpse.WebForms.Net45\nuspec\lib\net35\
-
- " Glimpse.WindowsAzure.Net40"
- copy $source_dir\Glimpse.WindowsAzure.Net40\bin\Release\Glimpse.WindowsAzure.* $source_dir\Glimpse.WindowsAzure.Net40\nuspec\lib\net40\
-
- " Glimpse.WindowsAzure.Storage.Net40"
- copy $source_dir\Glimpse.WindowsAzure.Storage.Net40\bin\Release\Glimpse.WindowsAzure.Storage.* $source_dir\Glimpse.WindowsAzure.Storage.Net40\nuspec\lib\net40\
}
task pack -depends merge {
@@ -259,71 +210,60 @@ task pack -depends merge {
cd $base_dir\.NuGet
" Glimpse.nuspec"
- $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.Core.Net45\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
+ $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.Core\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
exec { & .\nuget.exe pack $source_dir\Glimpse.Core.Net45\NuSpec\Glimpse.nuspec -OutputDirectory $build_dir\local -Symbols -Version $version }
+ " Glimpse.Owin.nuspec"
+ $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.Owin\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
+ exec { & .\nuget.exe pack $source_dir\Glimpse.Owin\NuSpec\Glimpse.Owin.nuspec -OutputDirectory $build_dir\local -Symbols -Version $version }
+
" Glimpse.AspNet.nuspec"
- $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.AspNet.Net45\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
+ $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.AspNet\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
exec { & .\nuget.exe pack $source_dir\Glimpse.AspNet.Net45\NuSpec\Glimpse.AspNet.nuspec -OutputDirectory $build_dir\local -Symbols -Version $version }
- " Glimpse.Mvc2.nuspec"
- $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.Mvc2\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
- exec { & .\nuget.exe pack $source_dir\Glimpse.Mvc2\NuSpec\Glimpse.Mvc2.nuspec -OutputDirectory $build_dir\local -Symbols -Version $version }
-
" Glimpse.Mvc3.nuspec"
- $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.Mvc3\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
+ $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.Mvc\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
exec { & .\nuget.exe pack $source_dir\Glimpse.Mvc3\NuSpec\Glimpse.Mvc3.nuspec -OutputDirectory $build_dir\local -Symbols -Version $version }
" Glimpse.Mvc4.nuspec"
- $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.Mvc4\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
+ $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.Mvc\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
exec { & .\nuget.exe pack $source_dir\Glimpse.Mvc4\NuSpec\Glimpse.Mvc4.nuspec -OutputDirectory $build_dir\local -Symbols -Version $version }
" Glimpse.Mvc5.nuspec"
- $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.Mvc5\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
+ $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.Mvc\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
exec { & .\nuget.exe pack $source_dir\Glimpse.Mvc5\NuSpec\Glimpse.Mvc5.nuspec -OutputDirectory $build_dir\local -Symbols -Version $version }
" Glimpse.Ado.nuspec"
- $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.Ado.Net45\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
+ $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.Ado\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
exec { & .\nuget.exe pack $source_dir\Glimpse.Ado.Net45\NuSpec\Glimpse.Ado.nuspec -OutputDirectory $build_dir\local -Symbols -Version $version }
" Glimpse.EF43.nuspec"
- $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.EF43.Net40\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
+ $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.EF\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
exec { & .\nuget.exe pack $source_dir\Glimpse.EF43.Net40\NuSpec\Glimpse.EF43.nuspec -OutputDirectory $build_dir\local -Symbols -Version $version }
" Glimpse.EF5.nuspec"
- $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.EF5.Net45\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
+ $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.EF\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
exec { & .\nuget.exe pack $source_dir\Glimpse.EF5.Net45\NuSpec\Glimpse.EF5.nuspec -OutputDirectory $build_dir\local -Symbols -Version $version }
" Glimpse.EF6.nuspec"
- $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.EF6.Net45\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
+ $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.EF\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
exec { & .\nuget.exe pack $source_dir\Glimpse.EF6.Net45\NuSpec\Glimpse.EF6.nuspec -OutputDirectory $build_dir\local -Symbols -Version $version }
" Glimpse.WebForms.nuspec"
- $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.WebForms.Net45\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
+ $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.WebForms\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
exec { & .\nuget.exe pack $source_dir\Glimpse.WebForms.Net45\NuSpec\Glimpse.WebForms.nuspec -OutputDirectory $build_dir\local -Symbols -Version $version }
- " Glimpse.WindowsAzure.nuspec"
- $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.WindowsAzure.Net40\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
- exec { & .\nuget.exe pack $source_dir\Glimpse.WindowsAzure.Net40\NuSpec\Glimpse.WindowsAzure.nuspec -OutputDirectory $build_dir\local -Symbols -Version $version }
-
- " Glimpse.WindowsAzure.nuspec"
- $version = Get-AssemblyInformationalVersion $source_dir\Glimpse.WindowsAzure.Storage.Net40\Properties\AssemblyInfo.cs | Update-AssemblyInformationalVersion
- exec { & .\nuget.exe pack $source_dir\Glimpse.WindowsAzure.Storage.Net40\NuSpec\Glimpse.WindowsAzure.Storage.nuspec -OutputDirectory $build_dir\local -Symbols -Version $version }
-
" Glimpse.zip"
New-Item $build_dir\local\zip\Core\net45 -Type directory -Force > $null
New-Item $build_dir\local\zip\Core\net40 -Type directory -Force > $null
- New-Item $build_dir\local\zip\Core\net35 -Type directory -Force > $null
+ New-Item $build_dir\local\zip\Owin\net40 -Type directory -Force > $null
New-Item $build_dir\local\zip\AspNet\net45 -Type directory -Force > $null
New-Item $build_dir\local\zip\AspNet\net40 -Type directory -Force > $null
- New-Item $build_dir\local\zip\AspNet\net35 -Type directory -Force > $null
- New-Item $build_dir\local\zip\MVC2\net35 -Type directory -Force > $null
New-Item $build_dir\local\zip\MVC3\net40 -Type directory -Force > $null
New-Item $build_dir\local\zip\MVC4\net40 -Type directory -Force > $null
New-Item $build_dir\local\zip\MVC5\net45 -Type directory -Force > $null
New-Item $build_dir\local\zip\Ado\net45 -Type directory -Force > $null
New-Item $build_dir\local\zip\Ado\net40 -Type directory -Force > $null
- New-Item $build_dir\local\zip\Ado\net35 -Type directory -Force > $null
New-Item $build_dir\local\zip\EF43\net40 -Type directory -Force > $null
New-Item $build_dir\local\zip\EF5\net45 -Type directory -Force > $null
New-Item $build_dir\local\zip\EF5\net40 -Type directory -Force > $null
@@ -331,29 +271,24 @@ task pack -depends merge {
New-Item $build_dir\local\zip\EF6\net40 -Type directory -Force > $null
New-Item $build_dir\local\zip\WebForms\net45 -Type directory -Force > $null
New-Item $build_dir\local\zip\WebForms\net40 -Type directory -Force > $null
- New-Item $build_dir\local\zip\WebForms\net35 -Type directory -Force > $null
- New-Item $build_dir\local\zip\WindowsAzure\net40 -Type directory -Force > $null
- New-Item $build_dir\local\zip\WindowsAzure.Storage\net40 -Type directory -Force > $null
copy $base_dir\license.txt $build_dir\local\zip
copy $source_dir\Glimpse.Core.Net45\nuspec\lib\net45\Glimpse.Core.* $build_dir\local\zip\Core\net45
copy $source_dir\Glimpse.Core.Net45\nuspec\lib\net40\Glimpse.Core.* $build_dir\local\zip\Core\net40
- copy $source_dir\Glimpse.Core.Net45\nuspec\lib\net35\Glimpse.Core.* $build_dir\local\zip\Core\net35
+
+ copy $source_dir\Glimpse.Owin\nuspec\lib\net40\Glimpse.Owin.* $build_dir\local\zip\Owin\net40
copy $source_dir\Glimpse.AspNet.Net45\nuspec\lib\net45\Glimpse.AspNet.* $build_dir\local\zip\AspNet\net45
copy $source_dir\Glimpse.AspNet.Net45\nuspec\lib\net40\Glimpse.AspNet.* $build_dir\local\zip\AspNet\net40
- copy $source_dir\Glimpse.AspNet.Net45\nuspec\lib\net35\Glimpse.AspNet.* $build_dir\local\zip\AspNet\net35
copy $source_dir\Glimpse.AspNet.Net45\nuspec\readme.txt $build_dir\local\zip\AspNet
- copy $source_dir\Glimpse.Mvc2\nuspec\lib\net35\Glimpse.Mvc2.* $build_dir\local\zip\Mvc2\net35
copy $source_dir\Glimpse.Mvc3\nuspec\lib\net40\Glimpse.Mvc3.* $build_dir\local\zip\Mvc3\net40
copy $source_dir\Glimpse.Mvc4\nuspec\lib\net40\Glimpse.Mvc4.* $build_dir\local\zip\Mvc4\net40
copy $source_dir\Glimpse.Mvc5\nuspec\lib\net45\Glimpse.Mvc5.* $build_dir\local\zip\Mvc5\net40
copy $source_dir\Glimpse.Ado.Net45\nuspec\lib\net45\Glimpse.Ado.* $build_dir\local\zip\Ado\net45
copy $source_dir\Glimpse.Ado.Net45\nuspec\lib\net40\Glimpse.Ado.* $build_dir\local\zip\Ado\net40
- copy $source_dir\Glimpse.Ado.Net45\nuspec\lib\net35\Glimpse.Ado.* $build_dir\local\zip\Ado\net35
copy $source_dir\Glimpse.EF43.Net40\nuspec\lib\Net40\Glimpse.EF43.* $build_dir\local\zip\EF43\Net40
copy $source_dir\Glimpse.EF5.Net45\nuspec\lib\net45\Glimpse.EF5.* $build_dir\local\zip\EF5\net45
@@ -363,13 +298,8 @@ task pack -depends merge {
copy $source_dir\Glimpse.WebForms.Net45\nuspec\lib\net45\Glimpse.WebForms.* $build_dir\local\zip\WebForms\net45
copy $source_dir\Glimpse.WebForms.Net45\nuspec\lib\net40\Glimpse.WebForms.* $build_dir\local\zip\WebForms\net40
- copy $source_dir\Glimpse.WebForms.Net45\nuspec\lib\net35\Glimpse.WebForms.* $build_dir\local\zip\WebForms\net35
copy $source_dir\Glimpse.WebForms.Net45\nuspec\readme.txt $build_dir\local\zip\WebForms
- copy $source_dir\Glimpse.WindowsAzure.Net40\nuspec\lib\net40\Glimpse.WindowsAzure.* $build_dir\local\zip\WindowsAzure\net40
-
- copy $source_dir\Glimpse.WindowsAzure.Storage.Net40\nuspec\lib\net40\Glimpse.WindowsAzure.* $build_dir\local\zip\WindowsAzure.Storage\net40
-
#TODO: Add help .CHM file
Create-Zip $build_dir\local\zip $build_dir\local\Glimpse.zip
diff --git a/global.json b/global.json
new file mode 100644
index 000000000..55aa90329
--- /dev/null
+++ b/global.json
@@ -0,0 +1,3 @@
+{
+ "sources": [ "source" ]
+}
diff --git a/source/Glimpse.Ado.Net35/Glimpse.Ado.Net35.csproj b/source/Glimpse.Ado.Net35/Glimpse.Ado.Net35.csproj
deleted file mode 100644
index 4c20254a7..000000000
--- a/source/Glimpse.Ado.Net35/Glimpse.Ado.Net35.csproj
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {4E0483E0-A87C-40C6-A82E-078D1DF8C0AC}
- Library
- Properties
- Glimpse.Ado.Net35
- Glimpse.Ado
- v3.5
- 512
-
-
- true
- full
- false
- bin\Debug\
- TRACE;DEBUG;NET35
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE;NET35
- prompt
- 4
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {22E8C0B0-E32F-4598-896F-81F3A6BD9862}
- Glimpse.Core.Net35
-
-
-
-
-
\ No newline at end of file
diff --git a/source/Glimpse.Ado.Net35/Properties/AssemblyInfo.cs b/source/Glimpse.Ado.Net35/Properties/AssemblyInfo.cs
deleted file mode 100644
index f19b0963e..000000000
--- a/source/Glimpse.Ado.Net35/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Glimpse.Core.Extensibility;
-
-[assembly: ComVisible(false)]
-[assembly: Guid("b5a203a0-e464-485c-abc5-4c7f26871dd4")]
-
-[assembly: AssemblyTitle("Glimpse for ADO Assembly")]
-[assembly: AssemblyDescription("Main extensibility implementations for running Glimpse with ADO.")]
-[assembly: AssemblyProduct("Glimpse.ADO")]
-[assembly: AssemblyCopyright("© 2012 Nik Molnar & Anthony van der Hoorn")]
-[assembly: AssemblyTrademark("Glimpse™")]
-
-// Version is in major.minor.build format to support http://semver.org/
-// Keep these three attributes in sync
-[assembly: AssemblyVersion("1.7.3")]
-[assembly: AssemblyFileVersion("1.7.3")]
-[assembly: AssemblyInformationalVersion("1.7.3")] // Used to specify the NuGet version number at build time
-
-[assembly: CLSCompliant(true)]
-[assembly: InternalsVisibleTo("Glimpse.Test.ADO")]
-[assembly: NuGetPackage("Glimpse.Ado")]
\ No newline at end of file
diff --git a/source/Glimpse.Ado.Net40/Glimpse.Ado.Net40.csproj b/source/Glimpse.Ado.Net40/Glimpse.Ado.Net40.csproj
index 0c74c9426..5e486738f 100644
--- a/source/Glimpse.Ado.Net40/Glimpse.Ado.Net40.csproj
+++ b/source/Glimpse.Ado.Net40/Glimpse.Ado.Net40.csproj
@@ -23,6 +23,7 @@
DEBUG;TRACE;NET40
prompt
4
+ 1591
pdbonly
@@ -31,6 +32,7 @@
TRACE;NET40
prompt
4
+ 1591
@@ -45,10 +47,177 @@
-
-
+
+
+
+ Component
+
+
+
+
+ Component
+
+
+
+
+ Component
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
@@ -63,7 +232,6 @@
-
diff --git a/source/Glimpse.Ado.Net45/Properties/AssemblyInfo.cs b/source/Glimpse.Ado.Net45/Properties/AssemblyInfo.cs
deleted file mode 100644
index fa5042148..000000000
--- a/source/Glimpse.Ado.Net45/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Web;
-using Glimpse.Ado;
-using Glimpse.Core.Extensibility;
-
-[assembly: ComVisible(false)]
-[assembly: Guid("396138aa-b068-4a92-ae95-8a21cfb6d2dd")]
-
-[assembly: AssemblyTitle("Glimpse for ADO Assembly")]
-[assembly: AssemblyDescription("Main extensibility implementations for running Glimpse with ADO.")]
-[assembly: AssemblyProduct("Glimpse.ADO")]
-[assembly: AssemblyCopyright("© 2012 Nik Molnar & Anthony van der Hoorn")]
-[assembly: AssemblyTrademark("Glimpse™")]
-
-// Version is in major.minor.build format to support http://semver.org/
-// Keep these three attributes in sync
-[assembly: AssemblyVersion("1.7.3")]
-[assembly: AssemblyFileVersion("1.7.3")]
-[assembly: AssemblyInformationalVersion("1.7.3")] // Used to specify the NuGet version number at build time
-
-[assembly: CLSCompliant(true)]
-[assembly: InternalsVisibleTo("Glimpse.Test.Ado")]
-[assembly: NuGetPackage("Glimpse.Ado")]
-[assembly: PreApplicationStartMethod(typeof(Initialize), "Start")]
\ No newline at end of file
diff --git a/source/Glimpse.Ado/AlternateType/GlimpseDbCommand.cs b/source/Glimpse.Ado/AlternateType/GlimpseDbCommand.cs
index 146028fc8..429e57128 100644
--- a/source/Glimpse.Ado/AlternateType/GlimpseDbCommand.cs
+++ b/source/Glimpse.Ado/AlternateType/GlimpseDbCommand.cs
@@ -74,6 +74,28 @@ public override UpdateRowSource UpdatedRowSource
get { return InnerCommand.UpdatedRowSource; }
set { InnerCommand.UpdatedRowSource = value; }
}
+
+ internal IMessageBroker MessageBroker
+ {
+ get { return messageBroker ?? (messageBroker = Support.DetermineMessageBroker()); }
+ set { messageBroker = value; }
+ }
+
+ public DbCommand Inner
+ {
+ get { return InnerCommand; }
+ }
+
+ internal IExecutionTimer TimerStrategy
+ {
+ get { return timerStrategy ?? (timerStrategy = Support.DetermineExecutionTimer()); }
+ set { timerStrategy = value; }
+ }
+
+ protected override DbParameterCollection DbParameterCollection
+ {
+ get { return InnerCommand.Parameters; }
+ }
public bool BindByName
{
@@ -98,26 +120,14 @@ public bool BindByName
}
}
- public DbCommand Inner
- {
- get { return InnerCommand; }
- }
-
- internal IMessageBroker MessageBroker
- {
- get { return messageBroker ?? (messageBroker = GlimpseConfiguration.GetConfiguredMessageBroker()); }
- set { messageBroker = value; }
- }
-
- internal IExecutionTimer TimerStrategy
+ public override void Cancel()
{
- get { return timerStrategy ?? (timerStrategy = GlimpseConfiguration.GetConfiguredTimerStrategy()()); }
- set { timerStrategy = value; }
+ InnerCommand.Cancel();
}
- protected override DbParameterCollection DbParameterCollection
+ public override void Prepare()
{
- get { return InnerCommand.Parameters; }
+ InnerCommand.Prepare();
}
protected override DbConnection DbConnection
@@ -156,16 +166,6 @@ protected override DbTransaction DbTransaction
}
}
- public override void Cancel()
- {
- InnerCommand.Cancel();
- }
-
- public override void Prepare()
- {
- InnerCommand.Prepare();
- }
-
public override int ExecuteNonQuery()
{
int num;
@@ -210,130 +210,130 @@ public override object ExecuteScalar()
return result;
}
-#if NET45
- public override async Task
pdbonly
@@ -31,6 +32,7 @@
TRACE
prompt
4
+ 1591
@@ -43,10 +45,9 @@
-
+
-
@@ -61,7 +62,6 @@
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/Glimpse.AspNet5.Sample/Web.Release.config b/source/Glimpse.AspNet5.Sample/Web.Release.config
new file mode 100644
index 000000000..c35844462
--- /dev/null
+++ b/source/Glimpse.AspNet5.Sample/Web.Release.config
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/Glimpse.AspNet5.Sample/Web.config b/source/Glimpse.AspNet5.Sample/Web.config
new file mode 100644
index 000000000..cc3e3cb88
--- /dev/null
+++ b/source/Glimpse.AspNet5.Sample/Web.config
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/Glimpse.AspNet5.Sample/project.json b/source/Glimpse.AspNet5.Sample/project.json
new file mode 100644
index 000000000..f0c3c8509
--- /dev/null
+++ b/source/Glimpse.AspNet5.Sample/project.json
@@ -0,0 +1,18 @@
+{
+ "webroot" : "wwwroot",
+ "exclude": "wwwroot/**/*.*",
+ "dependencies": {
+ "Microsoft.AspNet.Server.IIS": "1.0.0-alpha4",
+ "Microsoft.AspNet.StaticFiles": "1.0.0-alpha4",
+ "Microsoft.AspNet.Diagnostics": "1.0.0-alpha4",
+ "Glimpse.AspNet5": ""
+ },
+ "frameworks" : {
+ "aspnet50": {
+ "dependencies": {
+ "System.Configuration": ""
+ }
+ },
+ "aspnetcore50" : { }
+ }
+}
diff --git a/source/Glimpse.AspNet5/ApplicationBuilder.cs b/source/Glimpse.AspNet5/ApplicationBuilder.cs
new file mode 100644
index 000000000..687f83299
--- /dev/null
+++ b/source/Glimpse.AspNet5/ApplicationBuilder.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using Glimpse.AspNet5.Middleware;
+using Microsoft.AspNet.Builder;
+
+namespace Glimpse.AspNet5
+{
+ public class ApplicationBuilder : IApplicationBuilder
+ {
+ private readonly IApplicationBuilder innerBuilder;
+ private readonly static IDictionary ApplicationStore = new Dictionary();
+ private readonly Guid builderId;
+ private readonly MiddlewareManager manager;
+
+ public ApplicationBuilder(IApplicationBuilder app)
+ {
+ innerBuilder = app;
+
+ manager = MiddlewareManager.Instance;
+ builderId = Guid.NewGuid();
+
+ innerBuilder.Use(next => new GlimpseMiddleware(next, ApplicationStore).Invoke); // This is the earliest we can add middleware
+ }
+
+ public IApplicationBuilder Use(Func middleware)
+ {
+ manager.Register(builderId, middleware.Target.GetType());
+
+ innerBuilder.Use(next => new HeadMiddleware(next, next.Target.GetType(), builderId).Invoke);
+ innerBuilder.Use(middleware);
+
+ return this;
+ }
+
+ public IApplicationBuilder New()
+ {
+ return new ApplicationBuilder(innerBuilder.New());
+ }
+
+ public RequestDelegate Build()
+ {
+ return innerBuilder.Build();
+ }
+
+ public IServiceProvider ApplicationServices
+ {
+ get { return innerBuilder.ApplicationServices; }
+ set { innerBuilder.ApplicationServices = value; }
+ }
+
+ public IServerInformation Server
+ {
+ get { return innerBuilder.Server; }
+ set { innerBuilder.Server = value; }
+ }
+
+ public IDictionary Properties
+ {
+ get { return innerBuilder.Properties; }
+ set { innerBuilder.Properties = value; }
+ }
+ }
+}
diff --git a/source/Glimpse.AspNet5/Framework/RequestMetadata.cs b/source/Glimpse.AspNet5/Framework/RequestMetadata.cs
new file mode 100644
index 000000000..eac6c68b7
--- /dev/null
+++ b/source/Glimpse.AspNet5/Framework/RequestMetadata.cs
@@ -0,0 +1,72 @@
+using System;
+using Glimpse.Core.Framework;
+using Microsoft.AspNet.Http;
+
+namespace Glimpse.AspNet5.Framework
+{
+ public class RequestMetadata : IRequestMetadata
+ {
+ private readonly HttpContext context;
+
+ public RequestMetadata(HttpContext context)
+ {
+ this.context = context;
+ }
+
+ public Uri RequestUri
+ {
+ get { return new Uri(context.Request.Scheme + "://" + context.Request.Host + (context.Request.Path + context.Request.QueryString)); }
+ }
+
+ public string RequestHttpMethod
+ {
+ get { return context.Request.Method; }
+ }
+
+ public int ResponseStatusCode
+ {
+ get { return context.Response.StatusCode; }
+ }
+
+ public string ResponseContentType
+ {
+ get { return context.Response.ContentType; }
+ }
+
+ public bool RequestIsAjax
+ {
+ get
+ {
+ if (context.Request.Headers != null)
+ {
+ return context.Request.Headers["X-Requested-With"] == "XMLHttpRequest";
+ }
+
+ return false;
+ }
+ }
+
+ public string ClientId
+ {
+ get
+ {
+ if (context.User != null && !string.IsNullOrEmpty(context.User.Identity.Name))
+ {
+ return context.User.Identity.Name;
+ }
+
+ return Guid.NewGuid().ToString("N");
+ }
+ }
+
+ public string GetCookie(string name)
+ {
+ return context.Request.Cookies[name];
+ }
+
+ public string GetHttpHeader(string name)
+ {
+ return context.Request.Headers[name];
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.AspNet5/Framework/RequestResponseAdapter.cs b/source/Glimpse.AspNet5/Framework/RequestResponseAdapter.cs
new file mode 100644
index 000000000..ed3bed3c9
--- /dev/null
+++ b/source/Glimpse.AspNet5/Framework/RequestResponseAdapter.cs
@@ -0,0 +1,183 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Glimpse.Core.Extensibility;
+using Glimpse.Core.Framework;
+using Microsoft.AspNet.Http;
+using Glimpse.Core;
+
+namespace Glimpse.AspNet5.Framework
+{
+ public class RequestResponseAdapter : IRequestResponseAdapter
+ {
+ private readonly HttpContext context;
+ private readonly HttpRequest request;
+ private readonly HttpResponse response;
+
+ public RequestResponseAdapter(HttpContext context)
+ {
+ this.context = context;
+ this.request = context.Request;
+ this.response = context.Response;
+ }
+
+ public IDataStore HttpRequestStore
+ {
+ get
+ {
+ const string key = "glimpse.RequestStore";
+
+ if (context.Items.ContainsKey(key))
+ {
+ return (IDataStore)context.Items[key];
+ }
+
+ var result = new DictionaryDataStoreAdapter(new Dictionary());
+ context.Items.Add(key, result);
+ return result;
+ }
+ }
+
+ public object RuntimeContext
+ {
+ get { return context; }
+ }
+
+ public Stream OutputStream
+ {
+ get
+ {
+ return response.Body;
+ }
+
+ set
+ {
+ Guard.ArgumentNotNull("value", value);
+ response.Body = value;
+ }
+ }
+
+#warning TODO find a better way to "know" what the content encoding is (needed by the wrapping output stream)
+ public Encoding ResponseEncoding
+ {
+ get { return Encoding.UTF8; }
+ }
+
+ public IRequestMetadata RequestMetadata
+ {
+ get { return new RequestMetadata(context); }
+ }
+
+ public void SetHttpResponseHeader(string name, string value)
+ {
+ response.Headers[name] = value;
+ }
+
+ public void SetHttpResponseStatusCode(int statusCode)
+ {
+ response.StatusCode = statusCode;
+ }
+
+ public void SetCookie(string name, string value)
+ {
+ response.Cookies.Append(name, value);
+ }
+
+ public void WriteHttpResponse(byte[] content)
+ {
+ response.Body.WriteAsync(content, 0, content.Length);
+ }
+
+ public void WriteHttpResponse(string content)
+ {
+ response.WriteAsync(content);
+ }
+ /*
+ private HttpContext context;
+
+ public RequestResponseAdapter(HttpContext context)
+ {
+ this.context = context;
+ }
+
+ public IDataStore HttpRequestStore
+ {
+ get
+ {
+ const string key = "glimpse.RequestStore";
+
+ if (context.Items.ContainsKey(key))
+ {
+ return (IDataStore)context.Items[key];
+ }
+
+ var result = new DictionaryDataStoreAdapter(new Dictionary());
+ context.Items.Add(key, result);
+ return result;
+ }
+ }
+
+ public object RuntimeContext
+ {
+ get { return context; }
+ }
+
+ public IRequestMetadata RequestMetadata
+ {
+ get { return new RequestMetadata(context); }
+ }
+
+ public Stream OutputStream
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+
+ set
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public Encoding ResponseEncoding
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public void SetHttpResponseHeader(string name, string value)
+ {
+ context.Response.Headers[name] = value;
+ }
+
+ public void SetHttpResponseStatusCode(int statusCode)
+ {
+ context.Response.StatusCode = statusCode;
+ }
+
+ public void SetCookie(string name, string value)
+ {
+ context.Response.Cookies.Append(name, value);
+ }
+
+ public void InjectHttpResponseBody(string htmlSnippet)
+ {
+ // Hack: doing nothing because this has been temporarily moved to HeadMiddlewear
+ }
+
+ public void WriteHttpResponse(byte[] content)
+ {
+ context.Response.Body.WriteAsync(content, 0, content.Length);
+ }
+
+ public void WriteHttpResponse(string content)
+ {
+ context.Response.WriteAsync(content);
+ }
+ */
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.AspNet5/Glimpse.AspNet5.kproj b/source/Glimpse.AspNet5/Glimpse.AspNet5.kproj
new file mode 100644
index 000000000..1c8226e61
--- /dev/null
+++ b/source/Glimpse.AspNet5/Glimpse.AspNet5.kproj
@@ -0,0 +1,19 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+
+ a056721b-d6c0-44b6-ab1a-5c0481b354bc
+ Library
+ Glimpse.KRuntime
+
+
+
+ 2.0
+
+
+
\ No newline at end of file
diff --git a/source/Glimpse.AspNet5/IApplicationBuilderExtensions.cs b/source/Glimpse.AspNet5/IApplicationBuilderExtensions.cs
new file mode 100644
index 000000000..01faa4253
--- /dev/null
+++ b/source/Glimpse.AspNet5/IApplicationBuilderExtensions.cs
@@ -0,0 +1,12 @@
+using Microsoft.AspNet.Builder;
+
+namespace Glimpse.AspNet5
+{
+ public static class IApplicationBuilderExtensions
+ {
+ public static IApplicationBuilder WithGlimpse(this IApplicationBuilder app)
+ {
+ return new ApplicationBuilder(app);
+ }
+ }
+}
diff --git a/source/Glimpse.AspNet5/Middleware/GlimpseMiddleware.cs b/source/Glimpse.AspNet5/Middleware/GlimpseMiddleware.cs
new file mode 100644
index 000000000..372c8d464
--- /dev/null
+++ b/source/Glimpse.AspNet5/Middleware/GlimpseMiddleware.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Glimpse.Core;
+using Glimpse.Core.Extensibility;
+using Glimpse.Core.Framework;
+using Glimpse.AspNet5.Framework;
+using Microsoft.AspNet.Http;
+using Microsoft.AspNet.Builder;
+
+namespace Glimpse.AspNet5.Middleware
+{
+ public class GlimpseMiddleware
+ {
+ private readonly RequestDelegate innerNext;
+ private readonly IConfiguration config;
+
+ public GlimpseMiddleware(RequestDelegate next, IDictionary serverStore)
+ {
+ innerNext = next;
+ config = new Configuration(new UriTemplateResourceEndpointConfiguration(), new InMemoryPersistenceStore(new DictionaryDataStoreAdapter((Dictionary)serverStore)), new Glimpse.Core.Configuration.Section { EndpointBaseUri = "/Glimpse.axd", DefaultRuntimePolicy = RuntimePolicy.On } );
+ }
+
+ public async Task Invoke(HttpContext context)
+ {
+ if (!GlimpseRuntime.IsAvailable)
+ {
+ GlimpseRuntime.Initializer.Initialize(config);
+ }
+
+ if (GlimpseRuntime.IsAvailable)
+ {
+ try
+ {
+ var requestResponseAdapter = new RequestResponseAdapter(context);
+
+ using (var glimpseRequestContextHandle = GlimpseRuntime.Instance.BeginRequest(requestResponseAdapter))
+ {
+ switch (glimpseRequestContextHandle.RequestHandlingMode)
+ {
+ case RequestHandlingMode.RegularRequest:
+ await ExecuteRegularRequest(glimpseRequestContextHandle, context);
+ break;
+ case RequestHandlingMode.ResourceRequest:
+ await ExecuteResourceRequest(glimpseRequestContextHandle, context.Request.Query);
+ break;
+ default:
+ await innerNext(context);
+ break;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw;
+ }
+ }
+ else
+ {
+ await innerNext(context);
+ }
+ }
+
+ private static async Task ExecuteResourceRequest(GlimpseRequestContextHandle glimpseRequestContextHandle, IReadableStringCollection queryString)
+ {
+ GlimpseRuntime.Instance.ExecuteResource(glimpseRequestContextHandle, queryString[UriTemplateResourceEndpointConfiguration.DefaultResourceNameKey], new ResourceParameters(queryString.ToDictionary(qs => qs.Key, qs => qs.Value.First())));
+ }
+
+ private async Task ExecuteRegularRequest(GlimpseRequestContextHandle glimpseRequestContextHandle, HttpContext context)
+ {
+ try
+ {
+ await innerNext(context);
+ await context.Response.Body.FlushAsync();
+ }
+ finally
+ {
+ GlimpseRuntime.Instance.EndRequest(glimpseRequestContextHandle);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.AspNet5/Middleware/HeadMiddleware.cs b/source/Glimpse.AspNet5/Middleware/HeadMiddleware.cs
new file mode 100644
index 000000000..839292750
--- /dev/null
+++ b/source/Glimpse.AspNet5/Middleware/HeadMiddleware.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.AspNet.Http;
+using Microsoft.AspNet.Builder;
+
+namespace Glimpse.AspNet5.Middleware
+{
+ public class HeadMiddleware
+ {
+ private readonly RequestDelegate next;
+ private readonly MiddlewareManager manager;
+ private readonly Type middlewareType;
+ private readonly Guid builderId;
+
+ public HeadMiddleware(RequestDelegate next, Type middlewareType, Guid builderId)
+ {
+ this.next = next;
+ this.manager = MiddlewareManager.Instance;
+ this.middlewareType = middlewareType;
+ this.builderId = builderId;
+ }
+
+ public async Task Invoke(HttpContext context)
+ {
+ manager.Start(context, middlewareType, builderId);
+ await next(context);
+ manager.End(context, middlewareType, builderId);
+ }
+ }
+}
diff --git a/source/Glimpse.AspNet5/Middleware/MiddlewareExecutionInfo.cs b/source/Glimpse.AspNet5/Middleware/MiddlewareExecutionInfo.cs
new file mode 100644
index 000000000..8c08f09f2
--- /dev/null
+++ b/source/Glimpse.AspNet5/Middleware/MiddlewareExecutionInfo.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text.RegularExpressions;
+
+namespace Glimpse.AspNet5.Middleware
+{
+ public class MiddlewareExecutionInfo
+ {
+ private string title;
+ private Stopwatch stopwatch;
+ private TimeSpan? childlessDuration;
+
+ public static MiddlewareExecutionInfo Unrun(Type type)
+ {
+ return new MiddlewareExecutionInfo {Type = type};
+ }
+
+ public static MiddlewareExecutionInfo Running(Type type)
+ {
+ return new MiddlewareExecutionInfo
+ {
+ Type = type,
+ stopwatch = Stopwatch.StartNew(),
+ };
+ }
+
+ public MiddlewareExecutionInfo()
+ {
+ Children = new List();
+ }
+
+ public void Stop()
+ {
+ stopwatch.Stop();
+ }
+
+ public Type Type { get; set; }
+
+ public TimeSpan? Duration
+ {
+ get
+ {
+ if (stopwatch == null)
+ return null;
+
+ return stopwatch.Elapsed;
+ }
+ }
+
+ public TimeSpan? ChildlessDuration
+ {
+ get
+ {
+ if (childlessDuration.HasValue)
+ return childlessDuration.Value;
+
+ if (!Duration.HasValue)
+ return null;
+
+ var duration = Duration.Value;
+ foreach (var child in Children)
+ {
+ duration -= child.ChildlessDuration.HasValue ? child.ChildlessDuration.Value : TimeSpan.Zero;
+ }
+
+ childlessDuration = duration;
+ return duration;
+ }
+ }
+
+ public string Title
+ {
+ get
+ {
+ return title ?? (title = Regex.Replace(Type.Name, "(?<=[a-z])([A-Z])", " $1")
+ .Replace(" Middleware", string.Empty));
+ }
+ }
+
+ public ICollection Children { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.AspNet5/Middleware/MiddlewareManager.cs b/source/Glimpse.AspNet5/Middleware/MiddlewareManager.cs
new file mode 100644
index 000000000..3f6ac83aa
--- /dev/null
+++ b/source/Glimpse.AspNet5/Middleware/MiddlewareManager.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using Microsoft.AspNet.Http;
+
+namespace Glimpse.AspNet5.Middleware
+{
+ public class MiddlewareManager
+ {
+ private const string trackerKey = "glimpse.MiddlewareTracker";
+ private static MiddlewareManager instance;
+ private readonly IDictionary> registeredMiddleware;
+
+ private MiddlewareManager()
+ {
+ registeredMiddleware = new Dictionary>();
+ }
+
+ public static MiddlewareManager Instance
+ {
+ get { return instance ?? (instance = new MiddlewareManager()); }
+ }
+
+ public void Register(Guid builderId, Type middlewareType)
+ {
+ List chain;
+ if (registeredMiddleware.ContainsKey(builderId))
+ {
+ chain = registeredMiddleware[builderId];
+ }
+ else
+ {
+ registeredMiddleware[builderId] = chain = new List();
+ }
+
+ chain.Add(middlewareType);
+ }
+
+ public void Start(HttpContext context, Type middlewareType, Guid builderId)
+ {
+ var tracker = GetTracker(context);
+
+ tracker.Push(MiddlewareExecutionInfo.Running(middlewareType));
+ }
+
+ public void End(HttpContext context, Type middlewareType, Guid builderId)
+ {
+ var tracker = GetTracker(context);
+ var middleware = tracker.Pop();
+ middleware.Stop();
+
+ // add in missing parts of chain
+ if (middleware.Children.Count == 0)
+ {
+ var chain = registeredMiddleware[builderId];
+ var child = middleware;
+ foreach (var registrant in chain.SkipWhile(m => m != middlewareType).Skip(1))
+ {
+ var newChild = MiddlewareExecutionInfo.Unrun(registrant);
+ child.Children.Add(newChild);
+ child = newChild;
+ }
+ }
+ }
+
+ private MiddlewareTracker GetTracker(HttpContext context)
+ {
+ var items = context.Items;
+ if (items.ContainsKey(trackerKey) && items[trackerKey] is MiddlewareTracker)
+ {
+ return (MiddlewareTracker)items[trackerKey];
+ }
+
+ var result = new MiddlewareTracker();
+ items[trackerKey] = result;
+ return result;
+ }
+ }
+
+ public class MiddlewareTracker
+ {
+ public MiddlewareTracker()
+ {
+ Stack = new Stack();
+ }
+
+ public MiddlewareExecutionInfo Graph { get; set; }
+
+ public Stack Stack { get; set; }
+
+ public void Push(MiddlewareExecutionInfo executionInfo)
+ {
+ if (Graph == null)
+ {
+ Graph = executionInfo;
+ }
+ else
+ {
+ Graph.Children.Add(executionInfo);
+ }
+
+ Stack.Push(executionInfo);
+ }
+
+ public MiddlewareExecutionInfo Pop()
+ {
+ return Stack.Pop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.AspNet5/Tab/Middleware.cs b/source/Glimpse.AspNet5/Tab/Middleware.cs
new file mode 100644
index 000000000..bb60ae135
--- /dev/null
+++ b/source/Glimpse.AspNet5/Tab/Middleware.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+using Glimpse.Core.Extensibility;
+using Glimpse.AspNet5.Middleware;
+
+namespace Glimpse.Owin.Tab
+{
+ public class Middleware : TabBase, IKey
+ {
+ public override string Name
+ {
+ get { return "Middleware"; }
+ }
+
+ public override object GetData(ITabContext context)
+ {
+ var environment = context.GetRequestContext>();
+
+ var tracker = environment["glimpse.MiddlewareTracker"] as MiddlewareTracker;
+
+ return tracker.Graph;
+ }
+
+ public string Key
+ {
+ get { return "glimpse_middleware"; }
+ }
+ }
+}
diff --git a/source/Glimpse.AspNet5/project.json b/source/Glimpse.AspNet5/project.json
new file mode 100644
index 000000000..4727d1aef
--- /dev/null
+++ b/source/Glimpse.AspNet5/project.json
@@ -0,0 +1,19 @@
+{
+ "dependencies": {
+ "Microsoft.AspNet.Http": "1.0.0-alpha4",
+ /*"Glimpse": "2.0.0-alpha0"*/
+ "Glimpse.Core": ""
+ },
+ "frameworks": {
+ "aspnet50": {
+ "dependencies": {
+ "System.Configuration": ""
+ }
+ },
+ "aspnetcore50": {
+ "dependencies": {
+ "System.Runtime": "4.0.20.0"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core.Net35/Backport/Net35Backport.cs b/source/Glimpse.Core.Net35/Backport/Net35Backport.cs
deleted file mode 100644
index da15bb72f..000000000
--- a/source/Glimpse.Core.Net35/Backport/Net35Backport.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-using System;
-
-namespace Glimpse.Core.Backport
-{
- public static class Net35Backport
- {
- public static bool HasFlag(this Enum type, T flag)
- {
- try
- {
- return (((int) (object) type & (int) (object) flag) == (int) (object) flag);
- }
- catch
- {
- return false;
- }
- }
-
- public static bool TryParseGuid(string input, out Guid output)
- {
- try
- {
- output = new Guid(input);
- return true;
- }
- catch
- {
- output = default(Guid);
- return false;
- }
- }
-
- public static bool TryParseEnum(string input, bool ignoreCase, out T result)
- {
- try
- {
- result = (T) Enum.Parse(typeof (T), input, ignoreCase);
- return true;
- }
- catch
- {
- result = default(T);
- return false;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/source/Glimpse.Core.Net35/Backport/Tuple.cs b/source/Glimpse.Core.Net35/Backport/Tuple.cs
deleted file mode 100644
index 351a36d15..000000000
--- a/source/Glimpse.Core.Net35/Backport/Tuple.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace System
-{
- public class Tuple
- {
- public T1 Item1 { get; private set; }
-
- public T2 Item2 { get; private set; }
-
- public Tuple(T1 item1, T2 item2)
- {
- Item1 = item1;
- Item2 = item2;
- }
- }
-}
diff --git a/source/Glimpse.Core.Net35/Glimpse.Core.Net35.csproj b/source/Glimpse.Core.Net35/Glimpse.Core.Net35.csproj
deleted file mode 100644
index 50b43df94..000000000
--- a/source/Glimpse.Core.Net35/Glimpse.Core.Net35.csproj
+++ /dev/null
@@ -1,122 +0,0 @@
-
-
-
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {22E8C0B0-E32F-4598-896F-81F3A6BD9862}
- Library
- Properties
- Glimpse.Core
- Glimpse.Core
- v3.5
- 512
-
- ..\..\
- true
-
-
- true
- full
- false
- bin\Debug\
- TRACE;DEBUG;NET35
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE;NET35
- prompt
- 4
-
-
-
- ..\..\packages\AntiXSS.4.2.1\lib\net35\AntiXssLibrary.dll
-
-
- ..\..\packages\Antlr4.StringTemplate.4.0.6.9004\lib\net35\Antlr4.StringTemplate.dll
-
-
- False
- ..\..\packages\Castle.Core.3.1.0\lib\net35\Castle.Core.dll
-
-
- ..\..\packages\AntiXSS.4.2.1\lib\net35\HtmlSanitizationLibrary.dll
-
-
- False
- ..\..\packages\Newtonsoft.Json.5.0.6\lib\net35\Newtonsoft.Json.dll
-
-
- ..\..\packages\NLog.2.0.0.2000\lib\net35\NLog.dll
-
-
-
-
-
- ..\..\packages\Tavis.UriTemplates.0.1.1\lib\NET35\Tavis.UriTemplates.dll
-
-
-
-
-
-
-
-
-
-
-
-
- glimpse.js
-
-
- glimpseInsight.js
-
-
-
-
-
-
-
-
- EmbeddedResources\github_logo.gif
-
-
- EmbeddedResources\glimpse_favicon.png
-
-
- EmbeddedResources\glimpse_image_logo.png
-
-
- EmbeddedResources\glimpse_text_logo.png
-
-
- EmbeddedResources\twitter_logo.png
-
-
- EmbeddedResources\sprite.png
-
-
- EmbeddedResources\glimpse_config.html
-
-
- EmbeddedResources\glimpse_config.css
-
-
- EmbeddedResources\glimpse_config.js
-
-
-
-
-
-
\ No newline at end of file
diff --git a/source/Glimpse.Core.Net35/Properties/AssemblyInfo.cs b/source/Glimpse.Core.Net35/Properties/AssemblyInfo.cs
deleted file mode 100644
index af5442238..000000000
--- a/source/Glimpse.Core.Net35/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Glimpse.Core.Extensibility;
-
-[assembly: ComVisible(false)]
-[assembly: Guid("da3e9a24-8809-48d0-807d-bce41a878883")]
-
-
-[assembly: AssemblyTitle("Glimpse Core Assembly for .NET 3.5")]
-[assembly: AssemblyDescription("Core .NET 3.5 interfaces and types for Glimpse.")]//When you right-click the assembly file in Windows Explorer, this attribute appears as the Comments value on the Version tab of the file properties dialog box.
-[assembly: AssemblyProduct("Glimpse")]
-[assembly: AssemblyCopyright("© 2012 Nik Molnar & Anthony van der Hoorn")]
-[assembly: AssemblyTrademark("Glimpse™")]
-
-
-// Version is in major.minor.build format to support http://semver.org/
-// Keep these three attributes in sync
-[assembly: AssemblyVersion("1.8.6")]
-[assembly: AssemblyFileVersion("1.8.6")]
-[assembly: AssemblyInformationalVersion("1.8.6")]
-
-[assembly: CLSCompliant(true)]
-[assembly: InternalsVisibleTo("Glimpse.Test.Core")]
-[assembly: NuGetPackage("Glimpse")]
\ No newline at end of file
diff --git a/source/Glimpse.Core.Net35/packages.config b/source/Glimpse.Core.Net35/packages.config
deleted file mode 100644
index 1318c9a2c..000000000
--- a/source/Glimpse.Core.Net35/packages.config
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/source/Glimpse.Core.Net40/Glimpse.Core.Net40.csproj b/source/Glimpse.Core.Net40/Glimpse.Core.Net40.csproj
index 871e9cbcb..cbcb7ef7c 100644
--- a/source/Glimpse.Core.Net40/Glimpse.Core.Net40.csproj
+++ b/source/Glimpse.Core.Net40/Glimpse.Core.Net40.csproj
@@ -25,6 +25,7 @@
4
+ 1591
pdbonly
@@ -34,6 +35,7 @@
prompt
4
bin\Release\Glimpse.Core.xml
+ 1591
@@ -60,22 +62,20 @@
+
..\..\packages\Tavis.UriTemplates.0.1.1\lib\NET40\Tavis.UriTemplates.dll
-
+
-
glimpse.js
-
-
- glimpseInsight.js
+ glimpse.js
@@ -85,34 +85,42 @@
EmbeddedResources\github_logo.gif
+ EmbeddedResources/github_logo.gif
EmbeddedResources\glimpse_favicon.png
+ EmbeddedResources/glimpse_favicon.png
EmbeddedResources\glimpse_image_logo.png
+ EmbeddedResources/glimpse_image_logo.png
EmbeddedResources\glimpse_text_logo.png
+ EmbeddedResources/glimpse_text_logo.png
EmbeddedResources\twitter_logo.png
+ EmbeddedResources/twitter_logo.png
EmbeddedResources\sprite.png
+ EmbeddedResources/sprite.png
EmbeddedResources\glimpse_config.html
+ EmbeddedResources/glimpse_config.html
EmbeddedResources\glimpse_config.css
+ EmbeddedResources/glimpse_config.css
EmbeddedResources\glimpse_config.js
+ EmbeddedResources/glimpse_config.js
-
+ ///
+ /// ]]>
+ ///
+ ///
+ [ConfigurationProperty("metadata")]
+ public DiscoverableCollectionElement Metadata
+ {
+ get { return (DiscoverableCollectionElement)base["metadata"]; }
+ set { base["metadata"] = value; }
+ }
+
+ ///
+ /// Gets or sets the collection of s that Glimpse will use in the tab metadata.
+ ///
+ ///
+ /// By default, tabs are discovered at runtime but that behavior, plus the location of where they are found, and which ones should be ignored is configurable.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// ]]>
+ ///
+ ///
+ [ConfigurationProperty("tabMetadata")]
+ public DiscoverableCollectionElement TabMetadata
+ {
+ get { return (DiscoverableCollectionElement)base["tabMetadata"]; }
+ set { base["tabMetadata"] = value; }
+ }
+
+ ///
+ /// Gets or sets the collection of s that Glimpse will use in the instance metadata.
+ ///
+ ///
+ /// By default, instance metadata is discovered at runtime but that behavior, plus the location of where they
+ /// are found, and which ones should be ignored is configurable.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// ]]>
+ ///
+ ///
+ [ConfigurationProperty("instanceMetadata")]
+ public DiscoverableCollectionElement InstanceMetadata
+ {
+ get { return (DiscoverableCollectionElement)base["instanceMetadata"]; }
+ set { base["instanceMetadata"] = value; }
+ }
+
[ConfigurationProperty("displays")]
public DiscoverableCollectionElement Displays
{
@@ -188,9 +270,9 @@ public DiscoverableCollectionElement Displays
///
///
[ConfigurationProperty("runtimePolicies")]
- public PolicyDiscoverableCollectionElement RuntimePolicies
+ public DiscoverableCollectionElement RuntimePolicies
{
- get { return (PolicyDiscoverableCollectionElement)base["runtimePolicies"]; }
+ get { return (DiscoverableCollectionElement)base["runtimePolicies"]; }
set { base["runtimePolicies"] = value; }
}
diff --git a/source/Glimpse.Core/Configuration/StatusCodeElement.cs b/source/Glimpse.Core/Configuration/StatusCodeElement.cs
deleted file mode 100644
index d5248be54..000000000
--- a/source/Glimpse.Core/Configuration/StatusCodeElement.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System.Configuration;
-
-namespace Glimpse.Core.Configuration
-{
- ///
- /// The Glimpse configuration node representing an Http status code.
- ///
- public class StatusCodeElement : ConfigurationElement
- {
- ///
- /// Gets or sets the status code.
- ///
- ///
- /// A list of ratified Http status codes in available in Section 10 of RFC 2616, the Http version 1.1 specification.
- ///
- /// Http 1.1 Specification
- [ConfigurationProperty("statusCode", IsRequired = true)]
- public int StatusCode
- {
- get { return (int)base["statusCode"]; }
- set { base["statusCode"] = value; }
- }
- }
-}
diff --git a/source/Glimpse.Core/Configuration/StatusCodeElementCollection.cs b/source/Glimpse.Core/Configuration/StatusCodeElementCollection.cs
deleted file mode 100644
index f9f42cbdb..000000000
--- a/source/Glimpse.Core/Configuration/StatusCodeElementCollection.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-using System.Configuration;
-
-namespace Glimpse.Core.Configuration
-{
- ///
- /// The Glimpse configuration node for collecting a list of status codes.
- ///
- ///
- /// By default, StatusCodeElementCollections contain three elements: 200, 301 and 302.
- ///
- [ConfigurationCollection(typeof(StatusCodeElement), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)]
- public class StatusCodeElementCollection : ConfigurationElementCollection
- {
- ///
- /// Initializes a new instance of the class with 200, 301 and 302 added to the collection.
- ///
- public StatusCodeElementCollection()
- {
- BaseAdd(new StatusCodeElement { StatusCode = 200 });
- BaseAdd(new StatusCodeElement { StatusCode = 301 });
- BaseAdd(new StatusCodeElement { StatusCode = 302 });
- }
-
- ///
- /// When overridden in a derived class, creates a new .
- ///
- ///
- /// A new .
- ///
- protected override ConfigurationElement CreateNewElement()
- {
- return new StatusCodeElement();
- }
-
- ///
- /// Gets the element key for a specified configuration element when overridden in a derived class.
- ///
- /// The to return the key for.
- ///
- /// An that acts as the key for the specified .
- ///
- protected override object GetElementKey(ConfigurationElement element)
- {
- return ((StatusCodeElement)element).StatusCode;
- }
- }
-}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Configuration/TypeElement.cs b/source/Glimpse.Core/Configuration/TypeElement.cs
deleted file mode 100644
index 5e6981997..000000000
--- a/source/Glimpse.Core/Configuration/TypeElement.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-using System.ComponentModel;
-using System.Configuration;
-
-namespace Glimpse.Core.Configuration
-{
- ///
- /// The Glimpse configuration node representing a .NET Framework type.
- ///
- public class TypeElement : ConfigurationElement
- {
- ///
- /// Gets or sets the type based on an assembly qualified name string.
- ///
- [ConfigurationProperty("type", IsRequired = true)]
- [TypeConverter(typeof(TypeConverter))]
- public Type Type
- {
- get { return (Type)base["type"]; }
- set { base["type"] = value; }
- }
- }
-}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Configuration/TypeElementCollection.cs b/source/Glimpse.Core/Configuration/TypeElementCollection.cs
deleted file mode 100644
index c07f8d8d2..000000000
--- a/source/Glimpse.Core/Configuration/TypeElementCollection.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System.Configuration;
-
-namespace Glimpse.Core.Configuration
-{
- ///
- /// The Glimpse configuration node for creating a collection of types.
- ///
- [ConfigurationCollection(typeof(TypeElement), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)]
- public class TypeElementCollection : ConfigurationElementCollection
- {
- ///
- /// When overridden in a derived class, creates a new .
- ///
- ///
- /// A new .
- ///
- protected override ConfigurationElement CreateNewElement()
- {
- return new TypeElement();
- }
-
- ///
- /// Gets the element key for a specified configuration element when overridden in a derived class.
- ///
- /// The to return the key for.
- ///
- /// An that acts as the key for the specified .
- ///
- protected override object GetElementKey(ConfigurationElement element)
- {
- return ((TypeElement)element).Type;
- }
- }
-}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Constants.cs b/source/Glimpse.Core/Constants.cs
index 1210957ed..12f2aec0b 100644
--- a/source/Glimpse.Core/Constants.cs
+++ b/source/Glimpse.Core/Constants.cs
@@ -1,6 +1,4 @@
-using Glimpse.Core.Extensibility;
-
-namespace Glimpse.Core
+namespace Glimpse.Core
{
///
/// Common constant strings used throughout Glimpse.
@@ -20,22 +18,6 @@ internal static class Constants
///
internal const string ClientIdCookieName = "glimpseId";
- ///
- /// The key Glimpse server uses to store a for tracking execution duration.
- ///
- ///
- /// Used as the key for the framework provider's local request storage mechanism (i.e. HttpContext.Items).
- ///
- internal const string GlobalStopwatchKey = "__GlimpseGlobalStopwatch";
-
- ///
- /// The key Glimpse server uses to store a for tracking execution duration.
- ///
- ///
- /// Used as the key for the framework provider's local request storage mechanism (i.e. HttpContext.Items).
- ///
- internal const string GlobalTimerKey = "__GlimpseTimer";
-
///
/// The name of the Http request header the Glimpse client will write the parent request ID to.
///
@@ -52,22 +34,6 @@ internal static class Constants
///
internal const string HttpResponseHeader = "Glimpse-RequestID";
- ///
- /// The key Glimpse server uses to store a which represents the current request's unique identifier.
- ///
- ///
- /// Used as the key for the framework provider's local request storage mechanism (i.e. HttpContext.Items).
- ///
- internal const string RequestIdKey = "__GlimpseRequestId";
-
- ///
- /// The key Glimpse server uses to store a for tracking Glimpse permissions.
- ///
- ///
- /// Used as the key for the framework provider's local request storage mechanism (i.e. HttpContext.Items).
- ///
- internal const string RuntimePolicyKey = "__GlimpseRequestRuntimePermissions";
-
///
/// The key Glimpse server uses to store an IDictionary<string, TabResult> which stores the result of calling GetData() on each implementation.
///
@@ -83,11 +49,6 @@ internal static class Constants
///
internal const string UserAgentHeaderName = "User-Agent";
- ///
- /// The key Glimpse server uses to track if script tags have been injected into an Http response.
- ///
- internal const string ScriptsHaveRenderedKey = "__GlimpseScriptHasRendered";
-
///
/// The key Glimpse server uses to store the client scripts strategy.
///
diff --git a/source/Glimpse.Core/Extensibility/IConfigurable.cs b/source/Glimpse.Core/Extensibility/IConfigurable.cs
index b4c15ca9c..7f62fc73f 100644
--- a/source/Glimpse.Core/Extensibility/IConfigurable.cs
+++ b/source/Glimpse.Core/Extensibility/IConfigurable.cs
@@ -1,19 +1,15 @@
-using Glimpse.Core.Configuration;
+using Glimpse.Core.Framework;
namespace Glimpse.Core.Extensibility
{
///
- /// IConfigurable allows types to participate in their own configuration.
+ /// Represents a type that can be configured by a
///
- ///
- /// Several implementations leverage IConfigurable to allow for configuration via web.config.
- ///
public interface IConfigurable
{
///
- /// Provides implementations an instance of to self populate any end user configuration options.
+ /// Gets the configurator
///
- /// The configuration section, <glimpse> from web.config.
- void Configure(Section section);
+ IConfigurator Configurator { get; }
}
}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Extensibility/IConfigurator.cs b/source/Glimpse.Core/Extensibility/IConfigurator.cs
new file mode 100644
index 000000000..fba64b38b
--- /dev/null
+++ b/source/Glimpse.Core/Extensibility/IConfigurator.cs
@@ -0,0 +1,19 @@
+namespace Glimpse.Core.Framework
+{
+ ///
+ /// Represents a configurator
+ ///
+ public interface IConfigurator
+ {
+ ///
+ /// Gets the name of the configuration element which the configurator wants to process
+ ///
+ string CustomConfigurationKey { get; }
+
+ ///
+ /// Will be called when custom configuration is available for the given custom configuration key
+ ///
+ /// The custom configuration
+ void ProcessCustomConfiguration(string customConfiguration);
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Extensibility/IContentTypePolicyConfigurator.cs b/source/Glimpse.Core/Extensibility/IContentTypePolicyConfigurator.cs
new file mode 100644
index 000000000..2674a29c9
--- /dev/null
+++ b/source/Glimpse.Core/Extensibility/IContentTypePolicyConfigurator.cs
@@ -0,0 +1,38 @@
+using System.Collections.Generic;
+
+namespace Glimpse.Core.Policy
+{
+ ///
+ /// Represents a content type policy configurator
+ ///
+ public interface IContentTypePolicyConfigurator
+ {
+ ///
+ /// Gets the supported content types
+ ///
+ IEnumerable SupportedContentTypes { get; }
+
+ ///
+ /// Gets a boolean indicating whether there are supported content types
+ ///
+ bool ContainsSupportedContentTypes { get; }
+
+ ///
+ /// Adds the given content types to the list of supported content types
+ ///
+ /// The content types to support
+ void AddSupportedContentTypes(IEnumerable supportedContentTypes);
+
+ ///
+ /// Adds the given content type to the list of supported content types
+ ///
+ /// The content type to support
+ void AddSupportedContentType(SupportedContentType supportedContentType);
+
+ ///
+ /// Removes the given content type from the list of supported content types
+ ///
+ /// The content type to remove
+ void RemoveSupportedContentType(string contentType);
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Extensibility/IInspector.cs b/source/Glimpse.Core/Extensibility/IInspector.cs
index 6aadfee74..29fc8d2d7 100644
--- a/source/Glimpse.Core/Extensibility/IInspector.cs
+++ b/source/Glimpse.Core/Extensibility/IInspector.cs
@@ -1,4 +1,6 @@
-namespace Glimpse.Core.Extensibility
+using Glimpse.Core.Framework;
+
+namespace Glimpse.Core.Extensibility
{
///
/// Definition of an inspector that runs during startup. This provides the means
@@ -16,10 +18,8 @@ public interface IInspector
///
/// The context.
///
- /// Executed during the phase of
- /// system startup. Specifically, with the ASP.NET provider, this is wired to/implemented by the
- /// System.Web.IHttpModule.Init method.
+ /// Executed during initialization of the
///
void Setup(IInspectorContext context);
}
-}
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Extensibility/IInstanceMetadata.cs b/source/Glimpse.Core/Extensibility/IInstanceMetadata.cs
new file mode 100644
index 000000000..aa6eeecc6
--- /dev/null
+++ b/source/Glimpse.Core/Extensibility/IInstanceMetadata.cs
@@ -0,0 +1,24 @@
+using Glimpse.Core.Framework;
+
+namespace Glimpse.Core.Extensibility
+{
+ ///
+ /// Provides the ability for metadata to be sliced into the metadata
+ /// response for a given instance of a request.
+ ///
+ public interface IInstanceMetadata
+ {
+ ///
+ /// Gets the key that should be used in the serialized output
+ ///
+ string Key { get; }
+
+ ///
+ /// Gets the instance metadata for this strategy
+ ///
+ /// Current configuration that the system has.
+ /// Context of the current request.
+ /// The metadata to be used for the given key
+ object GetInstanceMetadata(IReadonlyConfiguration configuration, IGlimpseRequestContext requestContext);
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Extensibility/IMetadata.cs b/source/Glimpse.Core/Extensibility/IMetadata.cs
new file mode 100644
index 000000000..852352949
--- /dev/null
+++ b/source/Glimpse.Core/Extensibility/IMetadata.cs
@@ -0,0 +1,23 @@
+using Glimpse.Core.Framework;
+
+namespace Glimpse.Core.Extensibility
+{
+ ///
+ /// Provides the ability for metadata to be sliced into the metadata
+ /// response for a given tab.
+ ///
+ public interface IMetadata
+ {
+ ///
+ /// Gets the key that should be used in the serialized output
+ ///
+ string Key { get; }
+
+ ///
+ /// Gets the metadata for a given configuration
+ ///
+ /// The configuration.
+ /// The metadata to be used for the given key
+ object GetMetadata(IReadonlyConfiguration configuration);
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Extensibility/IPrivilegedResource.cs b/source/Glimpse.Core/Extensibility/IPrivilegedResource.cs
index 174b6af05..5c0313d65 100644
--- a/source/Glimpse.Core/Extensibility/IPrivilegedResource.cs
+++ b/source/Glimpse.Core/Extensibility/IPrivilegedResource.cs
@@ -15,18 +15,15 @@ internal interface IPrivilegedResource : IResource
///
/// Executes the specified context.
///
- ///
- /// The context.
- ///
- ///
- /// The configuration.
- ///
+ /// The context
+ /// The configuration
+ /// The request response adapter
///
/// Use of is reserved.
///
///
/// A .
///
- IResourceResult Execute(IResourceContext context, IGlimpseConfiguration configuration);
+ IResourceResult Execute(IResourceContext context, IReadonlyConfiguration configuration, IRequestResponseAdapter requestResponseAdapter);
}
}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Extensibility/IResourceResultContext.cs b/source/Glimpse.Core/Extensibility/IResourceResultContext.cs
index ccbc2d263..2af72391a 100644
--- a/source/Glimpse.Core/Extensibility/IResourceResultContext.cs
+++ b/source/Glimpse.Core/Extensibility/IResourceResultContext.cs
@@ -4,7 +4,7 @@ namespace Glimpse.Core.Extensibility
{
///
/// IResourceResultContext provides implementations of access to the
- /// , and .
+ /// , and .
///
public interface IResourceResultContext : IContext
{
@@ -12,7 +12,7 @@ public interface IResourceResultContext : IContext
/// Gets the framework provider.
///
/// The framework provider.
- IFrameworkProvider FrameworkProvider { get; }
+ IRequestResponseAdapter RequestResponseAdapter { get; }
///
/// Gets the serializer.
diff --git a/source/Glimpse.Core/Extensibility/IStatusCodePolicyConfigurator.cs b/source/Glimpse.Core/Extensibility/IStatusCodePolicyConfigurator.cs
new file mode 100644
index 000000000..eeff1f2cc
--- /dev/null
+++ b/source/Glimpse.Core/Extensibility/IStatusCodePolicyConfigurator.cs
@@ -0,0 +1,38 @@
+using System.Collections.Generic;
+
+namespace Glimpse.Core.Policy
+{
+ ///
+ /// Represents a status code policy configurator
+ ///
+ public interface IStatusCodePolicyConfigurator
+ {
+ ///
+ /// Gets the supported status codes
+ ///
+ IEnumerable SupportedStatusCodes { get; }
+
+ ///
+ /// Gets a boolean indicating whether there are supported status codes
+ ///
+ bool ContainsSupportedStatusCodes { get; }
+
+ ///
+ /// Adds the given status codes to the list of supported status codes
+ ///
+ /// The status codes
+ void AddSupportedStatusCodes(IEnumerable statusCodes);
+
+ ///
+ /// Adds the given status code to the list of supported status codes
+ ///
+ /// The status code
+ void AddSupportedStatusCode(int statusCode);
+
+ ///
+ /// Removes the given status code from the list of supported status codes
+ ///
+ /// The status code to remove
+ void RemoveSupportedStatusCode(int statusCode);
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Extensibility/ITabMetadata.cs b/source/Glimpse.Core/Extensibility/ITabMetadata.cs
new file mode 100644
index 000000000..6ef1386df
--- /dev/null
+++ b/source/Glimpse.Core/Extensibility/ITabMetadata.cs
@@ -0,0 +1,24 @@
+using System;
+using Glimpse.Core.Framework;
+
+namespace Glimpse.Core.Extensibility
+{
+ ///
+ /// Provides the ability for metadata to be sliced into the metadata
+ /// response for a given tab.
+ ///
+ public interface ITabMetadata
+ {
+ ///
+ /// Gets the key that should be used in the serialized output
+ ///
+ string Key { get; }
+
+ ///
+ /// Gets the metadata for a given tab
+ ///
+ /// Tab that might have metadata generated for it.
+ ///
+ object GetTabMetadata(ITab tab);
+ }
+}
diff --git a/source/Glimpse.Core/Extensibility/IUriPolicyConfigurator.cs b/source/Glimpse.Core/Extensibility/IUriPolicyConfigurator.cs
new file mode 100644
index 000000000..ec5ffedc2
--- /dev/null
+++ b/source/Glimpse.Core/Extensibility/IUriPolicyConfigurator.cs
@@ -0,0 +1,39 @@
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+
+namespace Glimpse.Core.Policy
+{
+ ///
+ /// Represents a uri policy configurator
+ ///
+ public interface IUriPolicyConfigurator
+ {
+ ///
+ /// Gets the uri patterns that will be ignored
+ ///
+ IEnumerable UriPatternsToIgnore { get; }
+
+ ///
+ /// Gets a boolean indicating whether there are uri patterns that will be ignored
+ ///
+ bool ContainsUriPatternsToIgnore { get; }
+
+ ///
+ /// Adds the given uri patterns to the the list of uri patterns to ignore
+ ///
+ /// The uri patterns to ignore
+ void AddSupportedStatusCodes(IEnumerable uriPatternsToIgnore);
+
+ ///
+ /// Adds the given uri pattern to the list of uri patterns that will be ignored
+ ///
+ /// The uri pattern
+ void AddUriPatternToIgnore(string uriPattern);
+
+ ///
+ /// Removes the given uri pattern from the list of uri patterns that will be ignored
+ ///
+ /// The uri pattern
+ void RemoveUriPatternToIgnore(string uriPattern);
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Extensibility/MessageBroker.cs b/source/Glimpse.Core/Extensibility/MessageBroker.cs
index 383f834a5..118fe0cc7 100644
--- a/source/Glimpse.Core/Extensibility/MessageBroker.cs
+++ b/source/Glimpse.Core/Extensibility/MessageBroker.cs
@@ -11,9 +11,10 @@ public class MessageBroker : IMessageBroker
///
/// Initializes a new instance of the class.
///
+ /// Delegate indicating whether or not messages are allowed to be published
/// The logger.
/// Throws an exception if is null.
- public MessageBroker(ILogger logger)
+ public MessageBroker(Func messagePublishingAllowed, ILogger logger)
{
if (logger == null)
{
@@ -22,8 +23,11 @@ public MessageBroker(ILogger logger)
Subscriptions = new Dictionary>();
Logger = logger;
+ MessagePublishingAllowed = messagePublishingAllowed;
}
+ private Func MessagePublishingAllowed { get; set; }
+
///
/// Gets or sets the logger.
///
@@ -47,6 +51,11 @@ public MessageBroker(ILogger logger)
/// The message.
public void Publish(T message)
{
+ if (!MessagePublishingAllowed())
+ {
+ return;
+ }
+
foreach (var subscriptions in Subscriptions)
{
if (subscriptions.Key.IsInstanceOfType(message))
diff --git a/source/Glimpse.Core/Extensibility/NLogLogger.cs b/source/Glimpse.Core/Extensibility/NLogLogger.cs
index 10e1c6f42..7eba0f096 100644
--- a/source/Glimpse.Core/Extensibility/NLogLogger.cs
+++ b/source/Glimpse.Core/Extensibility/NLogLogger.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading;
using NLog;
namespace Glimpse.Core.Extensibility
@@ -6,7 +7,7 @@ namespace Glimpse.Core.Extensibility
///
/// An implementation of based on NLog.
///
- public class NLogLogger : LoggerBase
+ public class NLogLogger : LoggerBase, IDisposable
{
///
/// Initializes a new instance of the class.
@@ -132,5 +133,15 @@ public override void Fatal(string message, Exception exception)
{
Logger.FatalException(message, exception);
}
+
+ public void Dispose()
+ {
+ NLog.LogManager.Flush(100);
+
+ // NLog writes its logs asynchronously, which means that if we don't pause the thread, chances are the log will not be written
+ // especially if dispose is called on appDomain unload. Therefore we pause the thread for 100ms which should be enough for NLog
+ // to do its thing, as we only give it 100ms to start with
+ Thread.Sleep(110);
+ }
}
}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Extensibility/RequestHandlingMode.cs b/source/Glimpse.Core/Extensibility/RequestHandlingMode.cs
new file mode 100644
index 000000000..b6c499f72
--- /dev/null
+++ b/source/Glimpse.Core/Extensibility/RequestHandlingMode.cs
@@ -0,0 +1,27 @@
+using Glimpse.Core.Framework;
+
+namespace Glimpse.Core.Extensibility
+{
+ ///
+ /// Used to describe how a given request is handled by Glimpse
+ ///
+ public enum RequestHandlingMode
+ {
+ ///
+ /// Glimpse is not handling this request. This can be because Glimpse was disabled to start with or a decided
+ /// during that Glimpse should not handle this request.
+ ///
+ Unhandled,
+
+ ///
+ /// Glimpse hooked itself onto the request and started collecting information. This does not mean that information will be stored in the end,
+ /// as it is still possible for a to decide otherwise by the end of the request.
+ ///
+ RegularRequest,
+
+ ///
+ /// Glimpse handles this request completely, as the request is made for a specific Glimpse
+ ///
+ ResourceRequest
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Extensibility/ResourceResultContext.cs b/source/Glimpse.Core/Extensibility/ResourceResultContext.cs
index b3dd8ef72..2c9b042bd 100644
--- a/source/Glimpse.Core/Extensibility/ResourceResultContext.cs
+++ b/source/Glimpse.Core/Extensibility/ResourceResultContext.cs
@@ -11,13 +11,13 @@ public class ResourceResultContext : IResourceResultContext
/// Initializes a new instance of the class.
///
/// The logger.
- /// The framework provider.
+ /// The framework provider.
/// The serializer.
/// The HTML encoder.
- public ResourceResultContext(ILogger logger, IFrameworkProvider frameworkProvider, ISerializer serializer, IHtmlEncoder htmlEncoder)
+ public ResourceResultContext(ILogger logger, IRequestResponseAdapter requestResponseAdapter, ISerializer serializer, IHtmlEncoder htmlEncoder)
{
Logger = logger;
- FrameworkProvider = frameworkProvider;
+ RequestResponseAdapter = requestResponseAdapter;
Serializer = serializer;
HtmlEncoder = htmlEncoder;
}
@@ -36,7 +36,7 @@ public ResourceResultContext(ILogger logger, IFrameworkProvider frameworkProvide
///
/// The framework provider.
///
- public IFrameworkProvider FrameworkProvider { get; set; }
+ public IRequestResponseAdapter RequestResponseAdapter { get; set; }
///
/// Gets or sets the serializer.
diff --git a/source/Glimpse.Core/Extensions/StringExtensions.cs b/source/Glimpse.Core/Extensions/StringExtensions.cs
new file mode 100644
index 000000000..551298ee9
--- /dev/null
+++ b/source/Glimpse.Core/Extensions/StringExtensions.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Globalization;
+
+namespace Glimpse.Core.Extensions
+{
+ public static class StringExtensions
+ {
+ public static string TakeFirstChar(this string input)
+ {
+ if (!string.IsNullOrEmpty(input))
+ {
+ input = input[0].ToString(CultureInfo.InvariantCulture);
+ }
+
+ return input;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Extensions/TabContextExtensions.cs b/source/Glimpse.Core/Extensions/TabContextExtensions.cs
index 9f498da9c..579907fb1 100644
--- a/source/Glimpse.Core/Extensions/TabContextExtensions.cs
+++ b/source/Glimpse.Core/Extensions/TabContextExtensions.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using Glimpse.Core.Extensibility;
+using Glimpse.Core.Framework;
namespace Glimpse.Core.Extensions
{
@@ -43,6 +44,10 @@ public static void PersistMessages(this ITabSetupContext context)
private static void PersistMessage(T message, ITabSetupContext context)
{
var tabStore = context.GetTabStore();
+ if (tabStore == null)
+ {
+ throw new GlimpseException("The Tabstore is unavailable, are you sure the GlimpseRuntime.Instance.CurrentRequestContext.CurrentRuntimePolicy != RuntimePolicy.Off");
+ }
if (!tabStore.Contains>())
{
diff --git a/source/Glimpse.Core/Framework/ActiveGlimpseRequestContextEventArgs.cs b/source/Glimpse.Core/Framework/ActiveGlimpseRequestContextEventArgs.cs
new file mode 100644
index 000000000..e77a3899f
--- /dev/null
+++ b/source/Glimpse.Core/Framework/ActiveGlimpseRequestContextEventArgs.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace Glimpse.Core.Framework
+{
+ ///
+ /// Contains event data for related events
+ ///
+ public class ActiveGlimpseRequestContextEventArgs : EventArgs
+ {
+ ///
+ /// Initializes a new instance of the
+ ///
+ /// The Id assigned to the request by Glimpse.
+ public ActiveGlimpseRequestContextEventArgs(Guid glimpseRequestId)
+ {
+ GlimpseRequestId = glimpseRequestId;
+ RaisedOn = DateTime.Now;
+ }
+
+ ///
+ /// Gets the Glimpse Id assigned to this request
+ ///
+ public Guid GlimpseRequestId { get; private set; }
+
+ ///
+ /// Gets the moment when the event was raised
+ ///
+ public DateTime RaisedOn { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/ActiveGlimpseRequestContexts.cs b/source/Glimpse.Core/Framework/ActiveGlimpseRequestContexts.cs
new file mode 100644
index 000000000..c021c1813
--- /dev/null
+++ b/source/Glimpse.Core/Framework/ActiveGlimpseRequestContexts.cs
@@ -0,0 +1,162 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.Remoting.Messaging;
+
+namespace Glimpse.Core.Framework
+{
+ ///
+ /// Tracks active instances
+ ///
+ internal class ActiveGlimpseRequestContexts
+ {
+ private static readonly object glimpseRequestContextsAccessLock = new object();
+
+ private IDictionary GlimpseRequestContexts { get; set; }
+
+ private ICurrentGlimpseRequestIdTracker CurrentGlimpseRequestIdTracker { get; set; }
+
+ ///
+ /// Raised when a new was added to the list of active Glimpse request contexts
+ ///
+ public static event EventHandler RequestContextAdded = delegate { };
+
+ ///
+ /// Raised when an active was removed from the list of active Glimpse request contexts
+ ///
+ public static event EventHandler RequestContextRemoved = delegate { };
+
+ ///
+ /// Initializes the type
+ /// The to use
+ ///
+ public ActiveGlimpseRequestContexts(ICurrentGlimpseRequestIdTracker currentGlimpseRequestIdTracker)
+ {
+ if (currentGlimpseRequestIdTracker == null)
+ {
+ throw new ArgumentNullException("currentGlimpseRequestIdTracker");
+ }
+
+ CurrentGlimpseRequestIdTracker = currentGlimpseRequestIdTracker;
+ GlimpseRequestContexts = new Dictionary();
+ }
+
+ ///
+ /// Adds the given to the list of active Glimpse request contexts
+ ///
+ /// The to add
+ ///
+ /// A that will make sure the given is removed from
+ /// the list of active Glimpse request contexts once it is disposed or finalized.
+ ///
+ public GlimpseRequestContextHandle Add(IGlimpseRequestContext glimpseRequestContext)
+ {
+ // at this point, the glimpseRequestContext isn't stored anywhere, but before we put it in the list of active glimpse requests contexts
+ // we'll create the handle. This handle will make sure the glimpseRequestContext is removed from the collection of active glimpse request contexts
+ // in case something goes wrong further on. That's is also why we create the handle first and then add the the glimpseRequestContext to the list
+ // because if the creation of the handle would fail afterwards, then there is no way to remove the glimpseRequestContext from the list.
+ var glimpseRequestId = glimpseRequestContext.GlimpseRequestId;
+ var handle = new GlimpseRequestContextHandle(glimpseRequestId, glimpseRequestContext.RequestHandlingMode, () => Remove(glimpseRequestId));
+ lock (glimpseRequestContextsAccessLock)
+ {
+ /*
+ * if we don't lock, then it is possible to get the following exception under heavy load:
+ * [IndexOutOfRangeException: Index was outside the bounds of the array.]
+ * System.Collections.Generic.Dictionary`2.Resize(Int32 newSize, Boolean forceNewHashCodes)
+ * System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
+ * System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
+ */
+ GlimpseRequestContexts.Add(glimpseRequestId, glimpseRequestContext);
+ }
+
+ CurrentGlimpseRequestIdTracker.StartTracking(glimpseRequestId);
+
+ RaiseEvent(() => RequestContextAdded(this, new ActiveGlimpseRequestContextEventArgs(glimpseRequestId)), "RequestContextAdded");
+
+ return handle;
+ }
+
+ ///
+ /// Tries to get the corresponding from the list of active Glimpse request contexts.
+ ///
+ /// The Glimpse Id for which the corresponding must be returned
+ /// The corresponding
+ /// Boolean indicating whether or not the corresponding was found.
+ public bool TryGet(Guid glimpseRequestId, out IGlimpseRequestContext glimpseRequestContext)
+ {
+ return GlimpseRequestContexts.TryGetValue(glimpseRequestId, out glimpseRequestContext);
+ }
+
+ ///
+ /// Removes the corresponding from the list of active Glimpse request contexts.
+ ///
+ /// The Glimpse Id for which the corresponding must be removed
+ private void Remove(Guid glimpseRequestId)
+ {
+ bool glimpseRequestContextRemoved;
+ lock (glimpseRequestContextsAccessLock)
+ {
+ glimpseRequestContextRemoved = GlimpseRequestContexts.Remove(glimpseRequestId);
+ }
+
+ CurrentGlimpseRequestIdTracker.StopTracking();
+
+ if (glimpseRequestContextRemoved)
+ {
+ RaiseEvent(() => RequestContextRemoved(this, new ActiveGlimpseRequestContextEventArgs(glimpseRequestId)), "RequestContextRemoved");
+ }
+ }
+
+ ///
+ /// Gets the current based on the . If the has no matching
+ /// Glimpse request Id, then an will be returned instead. If the has a matching
+ /// Glimpse request Id, but there is no corresponding in the list of active Glimpse request contexts, then a
+ /// is thrown.
+ ///
+ public IGlimpseRequestContext Current
+ {
+ get
+ {
+ Guid glimpseRequestId;
+ if (!CurrentGlimpseRequestIdTracker.TryGet(out glimpseRequestId))
+ {
+ if (GlimpseRuntime.IsAvailable)
+ {
+ GlimpseRuntime.Instance.Configuration.Logger.Warn("Returning UnavailableGlimpseRequestContext.Instance which is unexpected. If you set the log level to Trace, then you'll see the stack trace as well.");
+ GlimpseRuntime.Instance.Configuration.Logger.Trace("Call for UnavailableGlimpseRequestContext.Instance made from" + Environment.NewLine + "\t" + new StackTrace());
+ }
+
+ // there is no context registered, which means Glimpse did not initialize itself for this request aka GlimpseRuntime.BeginRequest has not been
+ // called even when there is code that wants to check this. Either way, we return here an empty context which indicates that Glimpse is disabled
+ return UnavailableGlimpseRequestContext.Instance;
+ }
+
+ // we have a Glimpse Request Id, now we need to check whether we can find the corresponding Glimpse request context
+ IGlimpseRequestContext glimpseRequestContext;
+ if (TryGet(glimpseRequestId, out glimpseRequestContext))
+ {
+ return glimpseRequestContext;
+ }
+
+ // for some reason the context corresponding to the glimpse request id is not found
+ throw new GlimpseException("No corresponding Glimpse request context found for GlimpseRequestId '" + glimpseRequestId + "'.");
+ }
+ }
+
+ private static void RaiseEvent(Action eventRaiser, string eventName)
+ {
+ // we don't want any event handling code that throws an exception to have an impact on the workings of the ActiveGlimpseRequestContexts class
+ try
+ {
+ eventRaiser();
+ }
+ catch (Exception exception)
+ {
+ if (GlimpseRuntime.IsAvailable)
+ {
+ GlimpseRuntime.Instance.Configuration.Logger.Error("Exception occurred when '" + eventName + "' event got raised", exception);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/BaseDataProvider.cs b/source/Glimpse.Core/Framework/BaseDataProvider.cs
new file mode 100644
index 000000000..f033068e9
--- /dev/null
+++ b/source/Glimpse.Core/Framework/BaseDataProvider.cs
@@ -0,0 +1,62 @@
+using System.Collections.Generic;
+using Glimpse.Core.Extensibility;
+using Glimpse.Core.Extensions;
+
+namespace Glimpse.Core.Framework
+{
+ internal class BaseDataProvider : BaseProvider
+ {
+ public BaseDataProvider(IReadonlyConfiguration configuration, ActiveGlimpseRequestContexts activeGlimpseRequestContexts)
+ : base(configuration, activeGlimpseRequestContexts)
+ {
+ }
+
+ protected TResult GetResultsStore(IGlimpseRequestContext glimpseRequestContext, string resultStoreKey)
+ where TResult : class, new()
+ {
+ var requestStore = glimpseRequestContext.RequestStore;
+
+ var resultStore = requestStore.Get(resultStoreKey);
+ if (resultStore == null)
+ {
+ resultStore = new TResult();
+ requestStore.Set(resultStoreKey, resultStore);
+ }
+
+ return resultStore;
+ }
+
+ protected IDataStore GetTabStore(string tabName, IGlimpseRequestContext glimpseRequestContext)
+ {
+ if (glimpseRequestContext.CurrentRuntimePolicy == RuntimePolicy.Off)
+ {
+ return null;
+ }
+
+ var requestStore = glimpseRequestContext.RequestStore;
+ IDictionary tabStorage;
+ if (!requestStore.Contains(Constants.TabStorageKey))
+ {
+ tabStorage = new Dictionary();
+ requestStore.Set(Constants.TabStorageKey, tabStorage);
+ }
+ else
+ {
+ tabStorage = requestStore.Get>(Constants.TabStorageKey);
+ }
+
+ IDataStore tabStore;
+ if (!tabStorage.ContainsKey(tabName))
+ {
+ tabStore = new DictionaryDataStoreAdapter(new Dictionary());
+ tabStorage.Add(tabName, tabStore);
+ }
+ else
+ {
+ tabStore = tabStorage[tabName];
+ }
+
+ return tabStore;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/BaseProvider.cs b/source/Glimpse.Core/Framework/BaseProvider.cs
new file mode 100644
index 000000000..4cdb9db6b
--- /dev/null
+++ b/source/Glimpse.Core/Framework/BaseProvider.cs
@@ -0,0 +1,20 @@
+namespace Glimpse.Core.Framework
+{
+ internal class BaseProvider
+ {
+ protected IReadonlyConfiguration Configuration { get; set; }
+
+ protected ActiveGlimpseRequestContexts ActiveGlimpseRequestContexts { get; set; }
+
+ protected IGlimpseRequestContext CurrentRequestContext
+ {
+ get { return ActiveGlimpseRequestContexts.Current; }
+ }
+
+ public BaseProvider(IReadonlyConfiguration configuration, ActiveGlimpseRequestContexts activeGlimpseRequestContexts)
+ {
+ Configuration = configuration;
+ ActiveGlimpseRequestContexts = activeGlimpseRequestContexts;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/CallContextCurrentGlimpseRequestIdTracker.cs b/source/Glimpse.Core/Framework/CallContextCurrentGlimpseRequestIdTracker.cs
new file mode 100644
index 000000000..78cd7f03c
--- /dev/null
+++ b/source/Glimpse.Core/Framework/CallContextCurrentGlimpseRequestIdTracker.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Runtime.Remoting.Messaging;
+
+namespace Glimpse.Core.Framework
+{
+ ///
+ /// Implementation of a that tracks a given Glimpse request Id inside the
+ ///
+ public class CallContextCurrentGlimpseRequestIdTracker : ICurrentGlimpseRequestIdTracker
+ {
+ protected const string RequestIdKey = "__GlimpseRequestIdTracker";
+
+ ///
+ /// Tracks the Glimpse request id inside the
+ ///
+ /// The Glimpse request id to track.
+ public virtual void StartTracking(Guid glimpseRequestId)
+ {
+ CallContext.LogicalSetData(RequestIdKey, glimpseRequestId);
+ }
+
+ ///
+ /// Tries to get the tracked Glimpse request id from the
+ ///
+ /// The tracked Glimpse request id, or the default in case it was not found
+ /// Boolean indicating whether a Glimpse request id was found or not.
+ public virtual bool TryGet(out Guid glimpseRequestId)
+ {
+ glimpseRequestId = new Guid();
+
+ var possibleGlimpseRequestId = CallContext.LogicalGetData(RequestIdKey) as Guid?;
+ if (possibleGlimpseRequestId.HasValue)
+ {
+ glimpseRequestId = possibleGlimpseRequestId.Value;
+ }
+
+ return possibleGlimpseRequestId.HasValue;
+ }
+
+ ///
+ /// Stops tracking the Glimpse request id inside the
+ ///
+ public virtual void StopTracking()
+ {
+ CallContext.LogicalSetData(RequestIdKey, null);
+ CallContext.FreeNamedDataSlot(RequestIdKey);
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/Configuration.cs b/source/Glimpse.Core/Framework/Configuration.cs
new file mode 100644
index 000000000..8bb9936f9
--- /dev/null
+++ b/source/Glimpse.Core/Framework/Configuration.cs
@@ -0,0 +1,972 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Text;
+using Glimpse.Core.Configuration;
+using Glimpse.Core.Extensibility;
+using Glimpse.Core.Resource;
+using NLog;
+using NLog.Config;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+
+namespace Glimpse.Core.Framework
+{
+ ///
+ /// Contains all configuration required by instances to execute.
+ ///
+ public class Configuration : IConfiguration
+ {
+ private IMessageBroker messageBroker;
+ private ILogger logger;
+ private ICollection clientScripts;
+ private IResource defaultResource;
+ private string endpointBaseUri;
+ private IHtmlEncoder htmlEncoder;
+ private IPersistenceStore persistenceStore;
+ private ICollection inspectors;
+ private IProxyFactory proxyFactory;
+ private IResourceEndpointConfiguration resourceEndpoint;
+ private ICollection resources;
+ private ICollection runtimePolicies;
+ private ISerializer serializer;
+ private ICollection tabs;
+ private ICollection metadata;
+ private ICollection tabMetadata;
+ private ICollection instanceMetadata;
+ private ICollection displays;
+ private string hash;
+ private string version;
+ private Section xmlConfiguration;
+ private RuntimePolicy? defaultRuntimePolicy;
+ private ICollection serializationConverters;
+
+ public Configuration(ResourceEndpointConfiguration endpointConfiguration, IPersistenceStore persistenceStore, ICurrentGlimpseRequestIdTracker currentGlimpseRequestIdTracker = null)
+ : this(endpointConfiguration, persistenceStore, "glimpse", currentGlimpseRequestIdTracker)
+ {
+ }
+
+ public Configuration(ResourceEndpointConfiguration endpointConfiguration, IPersistenceStore persistenceStore, string xmlConfigurationSectionName, ICurrentGlimpseRequestIdTracker currentGlimpseRequestIdTracker = null)
+ : this(endpointConfiguration, persistenceStore, ConfigurationManager.GetSection(xmlConfigurationSectionName) as Section, currentGlimpseRequestIdTracker)
+ {
+ }
+
+ public Configuration(ResourceEndpointConfiguration endpointConfiguration, IPersistenceStore persistenceStore, Section xmlConfigurationSection, ICurrentGlimpseRequestIdTracker currentGlimpseRequestIdTracker = null)
+ {
+ if (endpointConfiguration == null)
+ {
+ throw new ArgumentNullException("endpointConfiguration");
+ }
+
+ if (persistenceStore == null)
+ {
+ throw new ArgumentNullException("persistenceStore");
+ }
+
+ if (xmlConfigurationSection == null)
+ {
+ throw new ArgumentNullException("xmlConfigurationSection");
+ }
+
+ ResourceEndpoint = endpointConfiguration;
+ PersistenceStore = persistenceStore;
+ XmlConfiguration = xmlConfigurationSection;
+ CurrentGlimpseRequestIdTracker = currentGlimpseRequestIdTracker ?? new CallContextCurrentGlimpseRequestIdTracker();
+
+ // TODO: Instantiate the user's IOC container (if they have one)
+ }
+
+ ///
+ /// Gets the .
+ ///
+ ///
+ /// The configured .
+ ///
+ public ICurrentGlimpseRequestIdTracker CurrentGlimpseRequestIdTracker { get; private set; }
+
+ public IServiceLocator UserServiceLocator { get; set; }
+
+ public Section XmlConfiguration
+ {
+ get
+ {
+ return xmlConfiguration;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ xmlConfiguration = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the client scripts collection.
+ ///
+ ///
+ /// The client scripts.
+ ///
+ /// A collection of instances resolved by the s, otherwise all s discovered in the configured discovery location.
+ /// An exception is thrown if the value is set to null.
+ public ICollection ClientScripts
+ {
+ get
+ {
+ if (clientScripts != null)
+ {
+ return clientScripts;
+ }
+
+ clientScripts = InstantiateDiscoverableCollection(XmlConfiguration.ClientScripts);
+ return clientScripts;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ clientScripts = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the default to execute.
+ ///
+ ///
+ /// The default resource.
+ ///
+ /// A instance resolved by the s, otherwise .
+ /// An exception is thrown if the value is set to null.
+ public IResource DefaultResource
+ {
+ get
+ {
+ if (defaultResource != null)
+ {
+ return defaultResource;
+ }
+
+ if (TrySingleInstanceFromServiceLocators(out defaultResource))
+ {
+ return defaultResource;
+ }
+
+ defaultResource = new ConfigurationResource();
+ return defaultResource;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ defaultResource = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the default runtime policy.
+ ///
+ ///
+ /// The default runtime policy.
+ ///
+ /// A instance based on configuration settings.
+ public RuntimePolicy DefaultRuntimePolicy
+ {
+ get
+ {
+ if (defaultRuntimePolicy.HasValue)
+ {
+ return defaultRuntimePolicy.Value;
+ }
+
+ defaultRuntimePolicy = XmlConfiguration.DefaultRuntimePolicy;
+ return defaultRuntimePolicy.Value;
+ }
+
+ set
+ {
+ defaultRuntimePolicy = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the endpoint base URI.
+ ///
+ ///
+ /// The endpoint base URI.
+ ///
+ /// An exception is thrown if the value is set to null.
+ public string EndpointBaseUri
+ {
+ get
+ {
+ if (!string.IsNullOrEmpty(endpointBaseUri))
+ {
+ return endpointBaseUri;
+ }
+
+ endpointBaseUri = XmlConfiguration.EndpointBaseUri;
+ return endpointBaseUri;
+ }
+
+ set
+ {
+ if (string.IsNullOrEmpty(value))
+ {
+ throw new ArgumentException("EndpointBaseUri must be a non-null, non-empty string.", "value");
+ }
+
+ endpointBaseUri = value;
+ }
+ }
+
+ ///
+ /// Instantiates an instance of .
+ ///
+ /// A instance resolved by the s, otherwise (leveraging the Microsoft Web Protection Library).
+ public IHtmlEncoder HtmlEncoder
+ {
+ get
+ {
+ if (htmlEncoder != null)
+ {
+ return htmlEncoder;
+ }
+
+ if (TrySingleInstanceFromServiceLocators(out htmlEncoder))
+ {
+ return htmlEncoder;
+ }
+
+ htmlEncoder = new AntiXssEncoder();
+ return htmlEncoder;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ htmlEncoder = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the .
+ ///
+ ///
+ /// The configured .
+ ///
+ /// A instance resolved by the s, otherwise a or (leveraging the NLog project) based on configuration settings.
+ /// An exception is thrown if the value is set to null.
+ public ILogger Logger
+ {
+ get
+ {
+ if (logger != null)
+ {
+ return logger;
+ }
+
+ if (TrySingleInstanceFromServiceLocators(out logger))
+ {
+ return logger;
+ }
+
+ // use null logger if logging is off
+ var logLevel = XmlConfiguration.Logging.Level;
+ if (logLevel == LoggingLevel.Off)
+ {
+ logger = new NullLogger();
+ return logger;
+ }
+
+ logger = CreateLogger();
+ return logger;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ logger = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the .
+ ///
+ /// A instance resolved by one of the s, otherwise .
+ ///
+ /// The configured .
+ ///
+ /// An exception is thrown if the value is set to null.
+ public IMessageBroker MessageBroker
+ {
+ get
+ {
+ if (messageBroker != null)
+ {
+ return messageBroker;
+ }
+
+ if (TrySingleInstanceFromServiceLocators(out messageBroker))
+ {
+ return messageBroker;
+ }
+
+ messageBroker = new MessageBroker(
+ () => GlimpseRuntime.IsAvailable && GlimpseRuntime.Instance.CurrentRequestContext.CurrentRuntimePolicy != RuntimePolicy.Off,
+ Logger);
+
+ return messageBroker;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ messageBroker = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the .
+ ///
+ ///
+ /// The configured .
+ ///
+ /// An exception is thrown if the value is set to null.
+ public IPersistenceStore PersistenceStore
+ {
+ get
+ {
+ return persistenceStore;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ persistenceStore = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the collection of .
+ ///
+ ///
+ /// The configured collection of .
+ ///
+ /// A collection of instances resolved by the s, otherwise all s discovered in the configured discovery location.
+ /// An exception is thrown if the value is set to null.
+ public ICollection Inspectors
+ {
+ get
+ {
+ if (inspectors != null)
+ {
+ return inspectors;
+ }
+
+ inspectors = InstantiateDiscoverableCollection(XmlConfiguration.Inspectors);
+ return inspectors;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ inspectors = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the .
+ ///
+ ///
+ /// The configured .
+ ///
+ /// A instance resolved by the s, otherwise (leveraging Castle DynamicProxy.).
+ /// An exception is thrown if the value is set to null.
+ public IProxyFactory ProxyFactory
+ {
+ get
+ {
+ if (proxyFactory != null)
+ {
+ return proxyFactory;
+ }
+
+ if (TrySingleInstanceFromServiceLocators(out proxyFactory))
+ {
+ return proxyFactory;
+ }
+
+ proxyFactory = new CastleDynamicProxyFactory(
+ Logger,
+ MessageBroker,
+ () => GlimpseRuntime.IsAvailable ? GlimpseRuntime.Instance.CurrentRequestContext.CurrentExecutionTimer : UnavailableGlimpseRequestContext.Instance.CurrentExecutionTimer,
+ () => GlimpseRuntime.IsAvailable ? GlimpseRuntime.Instance.CurrentRequestContext.CurrentRuntimePolicy : UnavailableGlimpseRequestContext.Instance.CurrentRuntimePolicy);
+
+ return proxyFactory;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ proxyFactory = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the .
+ ///
+ ///
+ /// The configured .
+ ///
+ /// An exception is thrown if the value is set to null.
+ public IResourceEndpointConfiguration ResourceEndpoint
+ {
+ get
+ {
+ return resourceEndpoint;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ resourceEndpoint = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the collection of .
+ ///
+ ///
+ /// The configured collection of .
+ ///
+ /// A collection of instances resolved by the s, otherwise all s discovered in the configured discovery location.
+ /// An exception is thrown if the value is set to null.
+ public ICollection Resources
+ {
+ get
+ {
+ if (resources != null)
+ {
+ return resources;
+ }
+
+ resources = InstantiateDiscoverableCollection(XmlConfiguration.Resources);
+ return resources;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ resources = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the collection of .
+ ///
+ ///
+ /// The configured collection of .
+ ///
+ /// A collection of instances resolved by the s, otherwise all s discovered in the configured discovery location.
+ /// An exception is thrown if the value is set to null.
+ public ICollection RuntimePolicies
+ {
+ get
+ {
+ if (runtimePolicies != null)
+ {
+ return runtimePolicies;
+ }
+
+ runtimePolicies = InstantiateDiscoverableCollection(XmlConfiguration.RuntimePolicies);
+ return runtimePolicies;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ runtimePolicies = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the .
+ ///
+ ///
+ /// The configured .
+ ///
+ /// A instance resolved by the s, otherwise (leveraging Json.Net).
+ /// An exception is thrown if the value is set to null.
+ public ISerializer Serializer
+ {
+ get
+ {
+ if (serializer != null)
+ {
+ return serializer;
+ }
+
+ if (TrySingleInstanceFromServiceLocators(out serializer))
+ {
+ return serializer;
+ }
+
+ var temp = new JsonNetSerializer(Logger);
+ temp.RegisterSerializationConverters(SerializationConverters);
+
+ serializer = temp;
+ return serializer;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ serializer = value;
+ }
+ }
+
+ ///
+ /// Gets or sets a collection of s.
+ ///
+ /// A collection of instances resolved by the s, otherwise all s discovered in the configured discovery location.
+ public ICollection SerializationConverters
+ {
+ get
+ {
+ if (serializationConverters != null)
+ {
+ return serializationConverters;
+ }
+
+ serializationConverters = InstantiateDiscoverableCollection(XmlConfiguration.SerializationConverters);
+ return serializationConverters;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ serializationConverters = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the collection of .
+ ///
+ ///
+ /// The configured .
+ ///
+ /// A collection of instances resolved by the s, otherwise all s discovered in the configured discovery location.
+ /// An exception is thrown if the value is set to null.
+ public ICollection Tabs
+ {
+ get
+ {
+ if (tabs != null)
+ {
+ return tabs;
+ }
+
+ tabs = InstantiateDiscoverableCollection(XmlConfiguration.Tabs);
+ return tabs;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ tabs = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the collection of .
+ ///
+ ///
+ /// The configured .
+ ///
+ /// A collection of instances resolved by the s, otherwise all s discovered in the configured discovery location.
+ /// An exception is thrown if the value is set to null.
+ public ICollection Metadata
+ {
+ get
+ {
+ if (metadata != null)
+ {
+ return metadata;
+ }
+
+ if (TryAllInstancesFromServiceLocators(out metadata))
+ {
+ return metadata;
+ }
+
+ metadata = CreateDiscoverableCollection(XmlConfiguration.Metadata);
+ return metadata;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ metadata = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the collection of .
+ ///
+ ///
+ /// The configured .
+ ///
+ /// A collection of instances resolved by the s, otherwise all s discovered in the configured discovery location.
+ /// An exception is thrown if the value is set to null.
+ public ICollection TabMetadata
+ {
+ get
+ {
+ if (tabMetadata != null)
+ {
+ return tabMetadata;
+ }
+
+ if (TryAllInstancesFromServiceLocators(out tabMetadata))
+ {
+ return tabMetadata;
+ }
+
+ tabMetadata = CreateDiscoverableCollection(XmlConfiguration.TabMetadata);
+ return tabMetadata;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ tabMetadata = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the collection of .
+ ///
+ ///
+ /// The configured .
+ ///
+ /// A collection of instances resolved by the s, otherwise all s discovered in the configured discovery location.
+ /// An exception is thrown if the value is set to null.
+ public ICollection InstanceMetadata
+ {
+ get
+ {
+ if (instanceMetadata != null)
+ {
+ return instanceMetadata;
+ }
+
+ if (TryAllInstancesFromServiceLocators(out instanceMetadata))
+ {
+ return instanceMetadata;
+ }
+
+ instanceMetadata = CreateDiscoverableCollection(XmlConfiguration.InstanceMetadata);
+ return instanceMetadata;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ instanceMetadata = value;
+ }
+ }
+
+ public ICollection Displays
+ {
+ get
+ {
+ if (displays != null)
+ {
+ return displays;
+ }
+
+ displays = InstantiateDiscoverableCollection(XmlConfiguration.Displays);
+ return displays;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ displays = value;
+ }
+ }
+
+ public string Hash
+ {
+ get
+ {
+ if (!string.IsNullOrEmpty(hash))
+ {
+ return hash;
+ }
+
+ var configuredTypes = new List { GetType() };
+ configuredTypes.AddRange(Tabs.Select(tab => tab.GetType()).OrderBy(type => type.Name));
+ configuredTypes.AddRange(Inspectors.Select(inspector => inspector.GetType()).OrderBy(type => type.Name));
+ configuredTypes.AddRange(Resources.Select(resource => resource.GetType()).OrderBy(type => type.Name));
+ configuredTypes.AddRange(ClientScripts.Select(clientScript => clientScript.GetType()).OrderBy(type => type.Name));
+ configuredTypes.AddRange(RuntimePolicies.Select(policy => policy.GetType()).OrderBy(type => type.Name));
+ configuredTypes.AddRange(Metadata.Select(extensions => extensions.GetType()).OrderBy(type => type.Name));
+ configuredTypes.AddRange(TabMetadata.Select(extensions => extensions.GetType()).OrderBy(type => type.Name));
+
+ var crc32 = new Crc32();
+ var sb = new StringBuilder();
+ using (var memoryStream = new MemoryStream())
+ {
+ var binaryFormatter = new BinaryFormatter();
+ binaryFormatter.Serialize(memoryStream, configuredTypes);
+ memoryStream.Position = 0;
+
+ var computeHash = crc32.ComputeHash(memoryStream);
+
+ foreach (var b in computeHash)
+ {
+ sb.Append(b.ToString("x2"));
+ }
+ }
+
+ hash = sb.ToString();
+ return hash;
+ }
+
+ set
+ {
+ hash = value;
+ }
+ }
+
+ public string Version
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(version))
+ {
+ version = Assembly.GetExecutingAssembly().GetName().Version.ToString(3);
+ }
+
+ return version;
+ }
+
+ set
+ {
+ version = value;
+ }
+ }
+
+ public void ApplyOverrides()
+ {
+ // This method can be updated to ensure that web.config settings "win" - but that is difficult to do for most of them
+ DefaultRuntimePolicy = XmlConfiguration.DefaultRuntimePolicy;
+ EndpointBaseUri = XmlConfiguration.EndpointBaseUri;
+ if (XmlConfiguration.Logging.Level != LoggingLevel.Off)
+ {
+ Logger = CreateLogger();
+ }
+ }
+
+ private bool TrySingleInstanceFromServiceLocators(out T instance) where T : class
+ {
+ if (UserServiceLocator != null)
+ {
+ instance = UserServiceLocator.GetInstance();
+ if (instance != null)
+ {
+ return true;
+ }
+ }
+
+ instance = null;
+ return false;
+ }
+
+ private ILogger CreateLogger()
+ {
+ // Root the path if it isn't already and add a filename if one isn't specified
+ var configuredPath = XmlConfiguration.Logging.LogLocation;
+ var logDirPath = Path.IsPathRooted(configuredPath) ? configuredPath : Path.Combine(AppDomain.CurrentDomain.BaseDirectory, configuredPath);
+ var logFilePath = string.IsNullOrEmpty(Path.GetExtension(logDirPath)) ? Path.Combine(logDirPath, "Glimpse.log") : logDirPath;
+
+ var fileTarget = new FileTarget();
+ fileTarget.FileName = logFilePath;
+ fileTarget.Layout = "${longdate} | ${level:uppercase=true} | ${message} | ${exception:maxInnerExceptionLevel=5:format=type,message,stacktrace:separator=--:innerFormat=shortType,message,method:innerExceptionSeparator=>>}";
+
+ var asyncTarget = new AsyncTargetWrapper(fileTarget);
+ var loggingConfiguration = new LoggingConfiguration();
+ loggingConfiguration.AddTarget("file", asyncTarget);
+ loggingConfiguration.LoggingRules.Add(new LoggingRule("*", LogLevel.FromOrdinal((int)XmlConfiguration.Logging.Level), asyncTarget));
+
+ return new NLogLogger(new LogFactory(loggingConfiguration).GetLogger("Glimpse"));
+ }
+
+ private bool TryAllInstancesFromServiceLocators(out ICollection instance) where T : class
+ {
+ if (UserServiceLocator != null)
+ {
+ var result = UserServiceLocator.GetAllInstances();
+ if (result != null)
+ {
+ instance = result;
+ return true;
+ }
+ }
+
+ instance = null;
+
+ return false;
+ }
+
+ private IDiscoverableCollection CreateDiscoverableCollection(DiscoverableCollectionElement config)
+ {
+ var discoverableCollection = new ReflectionDiscoverableCollection(Logger);
+
+ discoverableCollection.IgnoredTypes.AddRange(config.IgnoredTypes);
+
+ // Default to config.DiscoveryLocation (collection specific) otherwise overrides
+ // Configuration.DiscoveryLocation (on main node)
+ var locationCascade = string.IsNullOrEmpty(config.DiscoveryLocation) ? (string.IsNullOrEmpty(XmlConfiguration.DiscoveryLocation) ? null : XmlConfiguration.DiscoveryLocation) : config.DiscoveryLocation;
+ if (locationCascade != null)
+ {
+ discoverableCollection.DiscoveryLocation = locationCascade;
+ }
+
+ discoverableCollection.AutoDiscover = config.AutoDiscover;
+ if (discoverableCollection.AutoDiscover)
+ {
+ discoverableCollection.Discover();
+ }
+
+ return discoverableCollection;
+ }
+
+ private ICollection InstantiateDiscoverableCollection(DiscoverableCollectionElement configuredDiscoverableCollection)
+ where TElementType : class
+ {
+ ICollection collection;
+ if (TryAllInstancesFromServiceLocators(out collection))
+ {
+ return collection;
+ }
+
+ var discoverableCollection = CreateDiscoverableCollection(configuredDiscoverableCollection);
+
+ // get the list of configurators
+ var configurators = discoverableCollection.OfType()
+ .Select(configurable => configurable.Configurator)
+ .GroupBy(configurator => configurator.CustomConfigurationKey);
+
+ // have each configurator, configure its "configurable"
+ foreach (var groupedConfigurators in configurators)
+ {
+ if (groupedConfigurators.Count() != 1)
+ {
+ // there are multiple configurators using the same custom configuration key inside the same discoverable collection
+ // this means that any existing custom configuration content must be resolved by using the custom configuration key
+ // and the type for which the configurator is
+ foreach (var configurator in groupedConfigurators)
+ {
+ string customConfiguration = configuredDiscoverableCollection.GetCustomConfiguration(configurator.CustomConfigurationKey, configurator.GetType());
+ if (!string.IsNullOrEmpty(customConfiguration))
+ {
+ configurator.ProcessCustomConfiguration(customConfiguration);
+ }
+ }
+ }
+ else
+ {
+ var configurator = groupedConfigurators.Single();
+ string customConfiguration = configuredDiscoverableCollection.GetCustomConfiguration(configurator.CustomConfigurationKey);
+ if (!string.IsNullOrEmpty(customConfiguration))
+ {
+ configurator.ProcessCustomConfiguration(customConfiguration);
+ }
+ }
+ }
+
+ return discoverableCollection;
+ }
+ }
+}
diff --git a/source/Glimpse.Core/Framework/DisplayProvider.cs b/source/Glimpse.Core/Framework/DisplayProvider.cs
new file mode 100644
index 000000000..8f9b89378
--- /dev/null
+++ b/source/Glimpse.Core/Framework/DisplayProvider.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Glimpse.Core.Extensibility;
+
+namespace Glimpse.Core.Framework
+{
+ internal class DisplayProvider : BaseDataProvider
+ {
+ public DisplayProvider(IReadonlyConfiguration configuration, ActiveGlimpseRequestContexts activeGlimpseRequestContexts)
+ : base(configuration, activeGlimpseRequestContexts)
+ {
+ }
+
+ public void Setup()
+ {
+ var logger = Configuration.Logger;
+ var messageBroker = Configuration.MessageBroker;
+
+ // TODO: Fix this to IDisplay no longer uses I*Tab*Setup
+ var displaysThatRequireSetup = Configuration.Displays.Where(display => display is ITabSetup).Select(display => display);
+ foreach (ITabSetup display in displaysThatRequireSetup)
+ {
+ var key = KeyCreator.Create(display);
+ try
+ {
+ var setupContext = new TabSetupContext(logger, messageBroker, () => GetTabStore(key, CurrentRequestContext));
+ display.Setup(setupContext);
+ }
+ catch (Exception exception)
+ {
+ logger.Error(Resources.InitializeTabError, exception, key);
+ }
+ }
+ }
+
+ public void Execute(IGlimpseRequestContext glimpseRequestContext)
+ {
+ var runtimeContext = glimpseRequestContext.RequestResponseAdapter.RuntimeContext;
+ var messageBroker = Configuration.MessageBroker;
+
+ var displayResultsStore = GetResultsStore(glimpseRequestContext);
+ var logger = Configuration.Logger;
+
+ foreach (var display in Configuration.Displays)
+ {
+ TabResult result; // TODO: Rename now that it is no longer *just* tab results
+ var key = KeyCreator.Create(display);
+ try
+ {
+ var displayContext = new TabContext(runtimeContext, GetTabStore(key, glimpseRequestContext), logger, messageBroker); // TODO: Do we need a DisplayContext?
+ var displayData = display.GetData(displayContext);
+
+ result = new TabResult(display.Name, displayData);
+ }
+ catch (Exception exception)
+ {
+ result = new TabResult(display.Name, exception.ToString());
+ logger.Error(Resources.ExecuteTabError, exception, key);
+ }
+
+ if (displayResultsStore.ContainsKey(key))
+ {
+ displayResultsStore[key] = result;
+ }
+ else
+ {
+ displayResultsStore.Add(key, result);
+ }
+ }
+ }
+
+ public IDictionary GetResultsStore(IGlimpseRequestContext glimpseRequestContext)
+ {
+ return GetResultsStore>(glimpseRequestContext, Constants.DisplayResultsDataStoreKey);
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/Factory.cs b/source/Glimpse.Core/Framework/Factory.cs
deleted file mode 100644
index a345afca7..000000000
--- a/source/Glimpse.Core/Framework/Factory.cs
+++ /dev/null
@@ -1,609 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Configuration;
-using System.IO;
-using System.Linq;
-using Glimpse.Core.Configuration;
-using Glimpse.Core.Extensibility;
-using Glimpse.Core.Extensions;
-using Glimpse.Core.Resource;
-using NLog;
-using NLog.Config;
-using NLog.Targets;
-using NLog.Targets.Wrappers;
-
-namespace Glimpse.Core.Framework
-{
- ///
- /// The main bootstrapper for Glimpse, Factory (or its derived types) is responsible for instantiating all required configurable types.
- ///
- public class Factory
- {
- ///
- /// Initializes a new instance of the class without any implementations.
- ///
- public Factory() : this(null)
- {
- }
-
- ///
- /// Initializes a new instance of the class without a implementation from the framework provider.
- ///
- /// The framework provider's service locator.
- public Factory(IServiceLocator providerServiceLocator) : this(providerServiceLocator, null)
- {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The framework provider's service locator.
- /// The user's service locator.
- public Factory(IServiceLocator providerServiceLocator, IServiceLocator userServiceLocator) : this(providerServiceLocator, userServiceLocator, null)
- {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The framework provider's service locator.
- /// The user's service locator.
- /// The Glimpse configuration to use.
- public Factory(IServiceLocator providerServiceLocator, IServiceLocator userServiceLocator, Section configuration)
- {
- Configuration = configuration ?? ConfigurationManager.GetSection("glimpse") as Section ?? new Section();
-
- IServiceLocator loadedServiceLocator = null;
- if (userServiceLocator == null && Configuration.ServiceLocatorType != null)
- {
- loadedServiceLocator = Activator.CreateInstance(Configuration.ServiceLocatorType) as IServiceLocator;
- }
-
- ProviderServiceLocator = providerServiceLocator;
- UserServiceLocator = userServiceLocator ?? loadedServiceLocator;
- }
-
- internal IServiceLocator UserServiceLocator { get; set; }
-
- internal IServiceLocator ProviderServiceLocator { get; set; }
-
- internal Section Configuration { get; set; }
-
- private ILogger Logger { get; set; }
-
- private IFrameworkProvider FrameworkProvider { get; set; }
-
- private IMessageBroker MessageBroker { get; set; }
-
- ///
- /// Instantiates an instance of .
- ///
- /// A instance resolved by one of the s, otherwise .
- public IGlimpseRuntime InstantiateRuntime()
- {
- IGlimpseRuntime result;
- if (TrySingleInstanceFromServiceLocators(out result))
- {
- return result;
- }
-
- return new GlimpseRuntime(InstantiateConfiguration());
- }
-
- ///
- /// Instantiates an instance of .
- ///
- /// A instance resolved by one of the s.
- /// An exception is thrown is an instance of is not provided by a .
- public IFrameworkProvider InstantiateFrameworkProvider()
- {
- if (FrameworkProvider != null)
- {
- return FrameworkProvider;
- }
-
- IFrameworkProvider result;
- if (TrySingleInstanceFromServiceLocators(out result))
- {
- FrameworkProvider = result;
- return FrameworkProvider;
- }
-
- throw new GlimpseException(
- string.Format(
- Resources.InstantiateFrameworkProviderException,
- UserServiceLocator == null ? "UserServiceLocator not configured" : UserServiceLocator.GetType().AssemblyQualifiedName,
- ProviderServiceLocator == null ? "ProviderServiceLocator not configured" : ProviderServiceLocator.GetType().AssemblyQualifiedName));
- }
-
- ///
- /// Instantiates an instance of .
- ///
- /// A instance resolved by one of the s.
- /// An exception is thrown is an instance of is not provided by a .
- public ResourceEndpointConfiguration InstantiateResourceEndpointConfiguration()
- {
- ResourceEndpointConfiguration result;
- if (TrySingleInstanceFromServiceLocators(out result))
- {
- return result;
- }
-
- throw new GlimpseException(
- string.Format(
- Resources.InstantiateResourceEndpointConfigurationException,
- UserServiceLocator == null ? "UserServiceLocator not configured" : UserServiceLocator.GetType().AssemblyQualifiedName,
- ProviderServiceLocator == null ? "ProviderServiceLocator not configured" : ProviderServiceLocator.GetType().AssemblyQualifiedName));
- }
-
- ///
- /// Instantiates a collection of s.
- ///
- ///
- /// A collection of instances resolved by one of the s, otherwise all s discovered in the configured discovery location.
- ///
- public ICollection InstantiateClientScripts()
- {
- ICollection result;
- if (TryAllInstancesFromServiceLocators(out result))
- {
- return result;
- }
-
- return CreateDiscoverableCollection(Configuration.ClientScripts);
- }
-
- ///
- /// Instantiates an instance of .
- ///
- /// A instance resolved by one of the s, otherwise a or (leveraging the NLog project) based on configuration settings.
- public ILogger InstantiateLogger()
- {
- // reuse logger if already created
- if (Logger != null)
- {
- return Logger;
- }
-
- ILogger result;
- if (TrySingleInstanceFromServiceLocators(out result))
- {
- Logger = result;
- return Logger;
- }
-
- // use null logger if logging is off
- var logLevel = Configuration.Logging.Level;
- if (logLevel == LoggingLevel.Off)
- {
- Logger = new NullLogger();
- return Logger;
- }
-
- var configuredPath = Configuration.Logging.LogLocation;
-
- // Root the path if it isn't already
- var logDirPath = Path.IsPathRooted(configuredPath)
- ? configuredPath
- : Path.Combine(AppDomain.CurrentDomain.BaseDirectory, configuredPath);
-
- // Add a filename if one isn't specified
- var logFilePath = string.IsNullOrEmpty(Path.GetExtension(logDirPath))
- ? Path.Combine(logDirPath, "Glimpse.log")
- : logDirPath;
-
- // use NLog logger otherwise
- var fileTarget = new FileTarget
- {
- FileName = logFilePath,
- Layout =
- "${longdate} | ${level:uppercase=true} | ${message} | ${exception:maxInnerExceptionLevel=5:format=type,message,stacktrace:separator=--:innerFormat=shortType,message,method:innerExceptionSeparator=>>}"
- };
-
- var asyncTarget = new AsyncTargetWrapper(fileTarget);
-
- var loggingConfiguration = new LoggingConfiguration();
- loggingConfiguration.AddTarget("file", asyncTarget);
- loggingConfiguration.LoggingRules.Add(new LoggingRule("*", LogLevel.FromOrdinal((int)logLevel), asyncTarget));
-
- Logger = new NLogLogger(new LogFactory(loggingConfiguration).GetLogger("Glimpse"));
- return Logger;
- }
-
- ///
- /// Instantiates the default instance of .
- ///
- /// A instance based on configuration settings.
- public RuntimePolicy InstantiateDefaultRuntimePolicy()
- {
- return Configuration.DefaultRuntimePolicy;
- }
-
- ///
- /// Instantiates an instance of .
- ///
- /// A instance resolved by one of the s, otherwise (leveraging the Microsoft Web Protection Library).
- public IHtmlEncoder InstantiateHtmlEncoder()
- {
- IHtmlEncoder encoder;
-
- if (TrySingleInstanceFromServiceLocators(out encoder))
- {
- return encoder;
- }
-
- return new AntiXssEncoder();
- }
-
- ///
- /// Instantiates an instance of .
- ///
- /// A instance resolved by one of the s, otherwise .
- public IPersistenceStore InstantiatePersistenceStore()
- {
- IPersistenceStore store;
- if (TrySingleInstanceFromServiceLocators(out store))
- {
- return store;
- }
-
- return new ApplicationPersistenceStore(InstantiateFrameworkProvider().HttpServerStore);
- }
-
- ///
- /// Instantiates a collection of s.
- ///
- ///
- /// A collection of instances resolved by one of the s, otherwise all s discovered in the configured discovery location.
- ///
- public ICollection InstantiateInspectors()
- {
- ICollection result;
- if (TryAllInstancesFromServiceLocators(out result))
- {
- return result;
- }
-
- return CreateDiscoverableCollection(Configuration.Inspectors);
- }
-
- ///
- /// Instantiates a collection of s.
- ///
- ///
- /// A collection of instances resolved by one of the s, otherwise all s discovered in the configured discovery location.
- ///
- public ICollection InstantiateResources()
- {
- ICollection resources;
- if (TryAllInstancesFromServiceLocators(out resources))
- {
- return resources;
- }
-
- return CreateDiscoverableCollection(Configuration.Resources);
- }
-
- ///
- /// Instantiates an instance of .
- ///
- /// A instance resolved by one of the s, otherwise (leveraging Json.Net).
- public ISerializer InstantiateSerializer()
- {
- ISerializer result;
- if (TrySingleInstanceFromServiceLocators(out result))
- {
- return result;
- }
-
- result = new JsonNetSerializer(InstantiateLogger());
- result.RegisterSerializationConverters(InstantiateSerializationConverters());
-
- return result;
- }
-
- ///
- /// Instantiates a collection of s.
- ///
- ///
- /// A collection of instances resolved by one of the s, otherwise all s discovered in the configured discovery location.
- ///
- public ICollection InstantiateTabs()
- {
- ICollection tabs;
- if (TryAllInstancesFromServiceLocators(out tabs))
- {
- return tabs;
- }
-
- return CreateDiscoverableCollection(Configuration.Tabs);
- }
-
- public ICollection InstantiateDisplays()
- {
- ICollection displays;
- if (TryAllInstancesFromServiceLocators(out displays))
- {
- return displays;
- }
-
- return CreateDiscoverableCollection(Configuration.Displays);
- }
-
- ///
- /// Instantiates a collection of s.
- ///
- ///
- /// A collection of instances resolved by one of the s, otherwise all s discovered in the configured discovery location.
- ///
- public ICollection InstantiateRuntimePolicies()
- {
- ICollection result;
- if (TryAllInstancesFromServiceLocators(out result))
- {
- return result;
- }
-
- var collection = CreateDiscoverableCollection(Configuration.RuntimePolicies);
-
- foreach (var config in collection.OfType())
- {
- config.Configure(Configuration);
- }
-
- return collection;
- }
-
- ///
- /// Instantiates a collection of s.
- ///
- ///
- /// A collection of instances resolved by one of the s, otherwise all s discovered in the configured discovery location.
- ///
- public ICollection InstantiateSerializationConverters()
- {
- ICollection result;
- if (TryAllInstancesFromServiceLocators(out result))
- {
- return result;
- }
-
- return CreateDiscoverableCollection(Configuration.SerializationConverters);
- }
-
- ///
- /// Instantiates an instance of .
- ///
- /// A instance resolved by one of the s, otherwise .
- public IResource InstantiateDefaultResource()
- {
- IResource result;
- if (TrySingleInstanceFromServiceLocators(out result))
- {
- return result;
- }
-
- return new ConfigurationResource();
- }
-
- ///
- /// Instantiates a strategy pattern for accessing an instance of .
- ///
- ///
- /// A Func<IExecutionTimer> to access the request specific .
- ///
- public Func InstantiateTimerStrategy()
- {
- var frameworkProvider = InstantiateFrameworkProvider();
-
- return () => frameworkProvider.HttpRequestStore.Get(Constants.GlobalTimerKey);
- }
-
- ///
- /// Instantiates a strategy pattern for accessing an instance of .
- ///
- ///
- /// A Func<RuntimePolicy> to access the request specific .
- ///
- public Func InstantiateRuntimePolicyStrategy()
- {
- var frameworkProvider = InstantiateFrameworkProvider();
- var logger = InstantiateLogger();
-
- return () =>
- {
- // this code is indirectly called from 2 places :
- // - From inside an AlternateMethod instance (or basically everything that is related to a Glimpse proxy) to decide whether
- // or not Glimpse is enabled and data should be collected, and in case RuntimePolicy.Off is returned, the original method
- // will be called, which has the same effect as if Glimpse is not there.
- // - By any Inspector, since it is exposed on the InspectorContext
-
- // Now the assumption that is made here, is that this code will only be called after that the GlimpseRuntime's BeginRequest method
- // has run and properly initialized the 'GlimpseContext' for the current request, which means it has at least set the current runtime policy.
- // Unfortunately there are use-cases where users are creative and (ab)use specific concepts to achieve a specific goal, and those uses don't
- // always align with Glimpse's assumptions. For example a new instance of an HttpContext is sometimes created and assigned to the HttpContext.Current
- // property to have a new controller instance render a view to a string as if it was a request... This has the nasty side-effect that Glimpse is not
- // given the opportunity to do a proper setup of that request, resulting in non-deterministic behavior.
-
- // Therefore if we notice that the current request has not properly been initialized by the GlimpseRuntime's BeginRequest method then we'll decide
- // that Glimpse is disabled, which is the safest assumption we can make here, preventing any further Glimpse specific code from collection information for that new "request".
- if (!frameworkProvider.HttpRequestStore.Contains(Constants.RuntimePolicyKey))
- {
- logger.Debug("Apparently GlimpseRuntime has not yet initialized this request. This might happen in case you're doing something specific like mentioned in this issue: https://github.com/Glimpse/Glimpse/issues/703 . Either way, Glimpse will be disabled to prevent any further non-deterministic behavior during this request.");
-
- // we'll store a RuntimePolicy.Off in the HttpRequestStore for subsequent calls for this request.
- frameworkProvider.HttpRequestStore.Set(Constants.RuntimePolicyKey, RuntimePolicy.Off);
- }
-
- return frameworkProvider.HttpRequestStore.Get(Constants.RuntimePolicyKey);
- };
- }
-
- ///
- /// Instantiates an instance of .
- ///
- /// A instance resolved by one of the s, otherwise with each constructor parameter created with the corresponding method.
- public IGlimpseConfiguration InstantiateConfiguration()
- {
- IGlimpseConfiguration result;
- if (TrySingleInstanceFromServiceLocators(out result))
- {
- return result;
- }
-
- var frameworkProvider = InstantiateFrameworkProvider();
- var timerStrategy = InstantiateTimerStrategy();
- var runtimePolicyStrategy = InstantiateRuntimePolicyStrategy();
- var endpointConfiguration = InstantiateResourceEndpointConfiguration();
- var clientScripts = InstantiateClientScripts();
- var logger = InstantiateLogger();
- var policy = InstantiateDefaultRuntimePolicy();
- var htmlEncoder = InstantiateHtmlEncoder();
- var persistenceStore = InstantiatePersistenceStore();
- var inspectors = InstantiateInspectors();
- var resources = InstantiateResources();
- var serializer = InstantiateSerializer();
- var tabs = InstantiateTabs();
- var displays = InstantiateDisplays();
- var runtimePolicies = InstantiateRuntimePolicies();
- var defaultResource = InstantiateDefaultResource();
- var proxyFactory = InstantiateProxyFactory();
- var messageBroker = InstantiateMessageBroker();
- var endpointBaseUri = InstantiateBaseResourceUri();
-
- return new GlimpseConfiguration(frameworkProvider, endpointConfiguration, clientScripts, logger, policy, htmlEncoder, persistenceStore, inspectors, resources, serializer, tabs, displays, runtimePolicies, defaultResource, proxyFactory, messageBroker, endpointBaseUri, timerStrategy, runtimePolicyStrategy);
- }
-
- ///
- /// Instantiates a string that represents the base Uri Glimpse will use for invoking all instances of .
- ///
- /// A instance based on configuration settings.
- public string InstantiateBaseResourceUri()
- {
- return Configuration.EndpointBaseUri;
- }
-
- ///
- /// Instantiates an instance of .
- ///
- /// A instance resolved by one of the s, otherwise .
- public IMessageBroker InstantiateMessageBroker()
- {
- if (MessageBroker == null)
- {
- IMessageBroker result;
- if (TrySingleInstanceFromServiceLocators(out result))
- {
- MessageBroker = result;
- }
- else
- {
- MessageBroker = new MessageBroker(InstantiateLogger());
- }
- }
-
- return MessageBroker;
- }
-
- ///
- /// Instantiates an instance of .
- ///
- /// A instance resolved by one of the s, otherwise (leveraging Castle DynamicProxy.).
- public IProxyFactory InstantiateProxyFactory()
- {
- IProxyFactory result;
- if (TrySingleInstanceFromServiceLocators(out result))
- {
- return result;
- }
-
- return new CastleDynamicProxyFactory(InstantiateLogger(), InstantiateMessageBroker(), InstantiateTimerStrategy(), InstantiateRuntimePolicyStrategy());
- }
-
- private static IEnumerable ToEnumerable(TypeElementCollection collection)
- {
- foreach (TypeElement typeElement in collection)
- {
- yield return typeElement.Type;
- }
- }
-
- private IDiscoverableCollection CreateDiscoverableCollection(DiscoverableCollectionElement config)
- {
- var discoverableCollection = new ReflectionDiscoverableCollection(InstantiateLogger());
-
- discoverableCollection.IgnoredTypes.AddRange(ToEnumerable(config.IgnoredTypes));
-
- // config.DiscoveryLocation (collection specific) overrides Configuration.DiscoveryLocation (on main node)
- var locationCascade = string.IsNullOrEmpty(config.DiscoveryLocation)
- ? string.IsNullOrEmpty(Configuration.DiscoveryLocation)
- ? null
- : Configuration.DiscoveryLocation
- : config.DiscoveryLocation;
-
- if (locationCascade != null)
- {
- discoverableCollection.DiscoveryLocation = locationCascade;
- }
-
- discoverableCollection.AutoDiscover = config.AutoDiscover;
- if (discoverableCollection.AutoDiscover)
- {
- discoverableCollection.Discover();
- }
-
- return discoverableCollection;
- }
-
- private bool TrySingleInstanceFromServiceLocators(out T instance) where T : class
- {
- if (UserServiceLocator != null)
- {
- instance = UserServiceLocator.GetInstance();
- if (instance != null)
- {
- return true;
- }
- }
-
- if (ProviderServiceLocator != null)
- {
- instance = ProviderServiceLocator.GetInstance();
- if (instance != null)
- {
- return true;
- }
- }
-
- instance = null;
- return false;
- }
-
- private bool TryAllInstancesFromServiceLocators(out ICollection instance) where T : class
- {
- IEnumerable result;
- if (UserServiceLocator != null)
- {
- result = UserServiceLocator.GetAllInstances();
- if (result != null)
- {
- instance = result as IList;
- return true;
- }
- }
-
- if (ProviderServiceLocator != null)
- {
- result = ProviderServiceLocator.GetAllInstances();
- if (result != null)
- {
- instance = result as IList;
- return true;
- }
- }
-
- instance = null;
- return false;
- }
- }
-}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/GlimpseConfiguration.cs b/source/Glimpse.Core/Framework/GlimpseConfiguration.cs
deleted file mode 100644
index 6ddbfd9b9..000000000
--- a/source/Glimpse.Core/Framework/GlimpseConfiguration.cs
+++ /dev/null
@@ -1,708 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Runtime.Serialization.Formatters.Binary;
-using System.Text;
-using Glimpse.Core.Extensibility;
-
-namespace Glimpse.Core.Framework
-{
- ///
- /// Contains all configuration required by instances to execute.
- ///
- public class GlimpseConfiguration : IGlimpseConfiguration
- {
- private static IMessageBroker messageBroker;
- private static Func timerStrategy;
- private static ILogger logger;
- private ICollection clientScripts;
- private IResource defaultResource;
- private string endpointBaseUri;
- private IFrameworkProvider frameworkProvider;
- private IHtmlEncoder htmlEncoder;
- private IPersistenceStore persistenceStore;
- private ICollection inspectors;
- private IProxyFactory proxyFactory;
- private ResourceEndpointConfiguration resourceEndpoint;
- private ICollection resources;
- private ICollection runtimePolicies;
- private ISerializer serializer;
- private ICollection tabs;
- private ICollection displays;
- private Func runtimePolicyStrategy;
- private string hash;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The framework provider.
- /// The resource endpoint configuration.
- /// The client scripts collection.
- /// The logger.
- /// The default runtime policy.
- /// The Html encoder.
- /// The persistence store.
- /// The inspectors collection.
- /// The resources collection.
- /// The serializer.
- /// The tabs collection.
- /// The displays collection.
- /// The runtime policies collection.
- /// The default resource.
- /// The proxy factory.
- /// The message broker.
- /// The endpoint base Uri.
- /// The timer strategy.
- /// The runtime policy strategy.
- /// An exception is thrown if any parameter is null.
- public GlimpseConfiguration(
- IFrameworkProvider frameworkProvider,
- ResourceEndpointConfiguration endpointConfiguration,
- ICollection clientScripts,
- ILogger logger,
- RuntimePolicy defaultRuntimePolicy,
- IHtmlEncoder htmlEncoder,
- IPersistenceStore persistenceStore,
- ICollection inspectors,
- ICollection resources,
- ISerializer serializer,
- ICollection tabs,
- ICollection displays,
- ICollection runtimePolicies,
- IResource defaultResource,
- IProxyFactory proxyFactory,
- IMessageBroker messageBroker,
- string endpointBaseUri,
- Func timerStrategy,
- Func runtimePolicyStrategy)
- {
- if (frameworkProvider == null)
- {
- throw new ArgumentNullException("frameworkProvider");
- }
-
- if (endpointConfiguration == null)
- {
- throw new ArgumentNullException("endpointConfiguration");
- }
-
- if (logger == null)
- {
- throw new ArgumentNullException("logger");
- }
-
- if (htmlEncoder == null)
- {
- throw new ArgumentNullException("htmlEncoder");
- }
-
- if (persistenceStore == null)
- {
- throw new ArgumentNullException("persistenceStore");
- }
-
- if (clientScripts == null)
- {
- throw new ArgumentNullException("clientScripts");
- }
-
- if (resources == null)
- {
- throw new ArgumentNullException("inspectors");
- }
-
- if (serializer == null)
- {
- throw new ArgumentNullException("serializer");
- }
-
- if (tabs == null)
- {
- throw new ArgumentNullException("tabs");
- }
-
- if (displays == null)
- {
- throw new ArgumentNullException("displays");
- }
-
- if (runtimePolicies == null)
- {
- throw new ArgumentNullException("runtimePolicies");
- }
-
- if (defaultResource == null)
- {
- throw new ArgumentNullException("defaultResource");
- }
-
- if (proxyFactory == null)
- {
- throw new ArgumentNullException("proxyFactory");
- }
-
- if (messageBroker == null)
- {
- throw new ArgumentNullException("messageBroker");
- }
-
- if (endpointBaseUri == null)
- {
- throw new ArgumentNullException("endpointBaseUri");
- }
-
- if (timerStrategy == null)
- {
- throw new ArgumentNullException("timerStrategy");
- }
-
- if (runtimePolicyStrategy == null)
- {
- throw new ArgumentNullException("runtimePolicyStrategy");
- }
-
- Logger = logger;
- ClientScripts = clientScripts;
- FrameworkProvider = frameworkProvider;
- HtmlEncoder = htmlEncoder;
- PersistenceStore = persistenceStore;
- Inspectors = inspectors;
- ResourceEndpoint = endpointConfiguration;
- Resources = resources;
- Serializer = serializer;
- Tabs = tabs;
- Displays = displays;
- RuntimePolicies = runtimePolicies;
- DefaultRuntimePolicy = defaultRuntimePolicy;
- DefaultResource = defaultResource;
- ProxyFactory = proxyFactory;
- MessageBroker = messageBroker;
- EndpointBaseUri = endpointBaseUri;
- TimerStrategy = timerStrategy;
- RuntimePolicyStrategy = runtimePolicyStrategy;
- }
-
- ///
- /// Gets or sets the client scripts collection.
- ///
- ///
- /// The client scripts.
- ///
- /// An exception is thrown if the value is set to null.
- public ICollection ClientScripts
- {
- get
- {
- return clientScripts;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- clientScripts = value;
- }
- }
-
- ///
- /// Gets or sets the default to execute.
- ///
- ///
- /// The default resource.
- ///
- /// An exception is thrown if the value is set to null.
- public IResource DefaultResource
- {
- get
- {
- return defaultResource;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- defaultResource = value;
- }
- }
-
- ///
- /// Gets or sets the default runtime policy.
- ///
- ///
- /// The default runtime policy.
- ///
- public RuntimePolicy DefaultRuntimePolicy { get; set; }
-
- ///
- /// Gets or sets the endpoint base URI.
- ///
- ///
- /// The endpoint base URI.
- ///
- /// An exception is thrown if the value is set to null.
- public string EndpointBaseUri
- {
- get
- {
- return endpointBaseUri;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- endpointBaseUri = value;
- }
- }
-
- ///
- /// Gets or sets the .
- ///
- ///
- /// The configured .
- ///
- /// An exception is thrown if the value is set to null.
- public IFrameworkProvider FrameworkProvider
- {
- get
- {
- return frameworkProvider;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- frameworkProvider = value;
- }
- }
-
- ///
- /// Gets or sets the .
- ///
- ///
- /// The configured .
- ///
- /// An exception is thrown if the value is set to null.
- public IHtmlEncoder HtmlEncoder
- {
- get
- {
- return htmlEncoder;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- htmlEncoder = value;
- }
- }
-
- ///
- /// Gets or sets the .
- ///
- ///
- /// The configured .
- ///
- /// An exception is thrown if the value is set to null.
- public ILogger Logger
- {
- get
- {
- return logger;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- logger = value;
- }
- }
-
- ///
- /// Gets or sets the .
- ///
- ///
- /// The configured .
- ///
- /// An exception is thrown if the value is set to null.
- public IMessageBroker MessageBroker
- {
- get
- {
- return messageBroker;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- messageBroker = value;
- }
- }
-
- ///
- /// Gets or sets the .
- ///
- ///
- /// The configured .
- ///
- /// An exception is thrown if the value is set to null.
- public IPersistenceStore PersistenceStore
- {
- get
- {
- return persistenceStore;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- persistenceStore = value;
- }
- }
-
- ///
- /// Gets or sets the collection of .
- ///
- ///
- /// The configured collection of .
- ///
- /// An exception is thrown if the value is set to null.
- public ICollection Inspectors
- {
- get
- {
- return inspectors;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- inspectors = value;
- }
- }
-
- ///
- /// Gets or sets the .
- ///
- ///
- /// The configured .
- ///
- /// An exception is thrown if the value is set to null.
- public IProxyFactory ProxyFactory
- {
- get
- {
- return proxyFactory;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- proxyFactory = value;
- }
- }
-
- ///
- /// Gets or sets the .
- ///
- ///
- /// The configured .
- ///
- /// An exception is thrown if the value is set to null.
- public ResourceEndpointConfiguration ResourceEndpoint
- {
- get
- {
- return resourceEndpoint;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- resourceEndpoint = value;
- }
- }
-
- ///
- /// Gets or sets the collection of .
- ///
- ///
- /// The configured collection of .
- ///
- /// An exception is thrown if the value is set to null.
- public ICollection Resources
- {
- get
- {
- return resources;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- resources = value;
- }
- }
-
- ///
- /// Gets or sets the collection of .
- ///
- ///
- /// The configured collection of .
- ///
- /// An exception is thrown if the value is set to null.
- public ICollection RuntimePolicies
- {
- get
- {
- return runtimePolicies;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- runtimePolicies = value;
- }
- }
-
- ///
- /// Gets or sets the strategy.
- ///
- ///
- /// The configured .
- ///
- /// An exception is thrown if the value is set to null.
- public Func RuntimePolicyStrategy
- {
- get
- {
- return runtimePolicyStrategy;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- runtimePolicyStrategy = value;
- }
- }
-
- ///
- /// Gets or sets the .
- ///
- ///
- /// The configured .
- ///
- /// An exception is thrown if the value is set to null.
- public ISerializer Serializer
- {
- get
- {
- return serializer;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- serializer = value;
- }
- }
-
- ///
- /// Gets or sets the collection of .
- ///
- ///
- /// The configured .
- ///
- /// An exception is thrown if the value is set to null.
- public ICollection Tabs
- {
- get
- {
- return tabs;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- tabs = value;
- }
- }
-
- public ICollection Displays
- {
- get
- {
- return displays;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- displays = value;
- }
- }
-
- ///
- /// Gets or sets the strategy.
- ///
- ///
- /// The configured strategy.
- ///
- /// An exception is thrown if the value is set to null.
- public Func TimerStrategy
- {
- get
- {
- return timerStrategy;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- timerStrategy = value;
- }
- }
-
- public string Hash
- {
- get
- {
- if (!string.IsNullOrEmpty(hash))
- {
- return hash;
- }
-
- var configuredTypes = new List { GetType() };
- configuredTypes.AddRange(Tabs.Select(tab => tab.GetType()).OrderBy(type => type.Name));
- configuredTypes.AddRange(Inspectors.Select(inspector => inspector.GetType()).OrderBy(type => type.Name));
- configuredTypes.AddRange(Resources.Select(resource => resource.GetType()).OrderBy(type => type.Name));
- configuredTypes.AddRange(ClientScripts.Select(clientScript => clientScript.GetType()).OrderBy(type => type.Name));
- configuredTypes.AddRange(RuntimePolicies.Select(policy => policy.GetType()).OrderBy(type => type.Name));
-
- var crc32 = new Crc32();
- var sb = new StringBuilder();
- using (var memoryStream = new MemoryStream())
- {
- var binaryFormatter = new BinaryFormatter();
- binaryFormatter.Serialize(memoryStream, configuredTypes);
- memoryStream.Position = 0;
-
- var computeHash = crc32.ComputeHash(memoryStream);
-
- foreach (var b in computeHash)
- {
- sb.Append(b.ToString("x2"));
- }
- }
-
- hash = sb.ToString();
- return hash;
- }
-
- set
- {
- hash = value;
- }
- }
-
- [Obsolete("HACK: To support TraceListener with TraceSource via web.config")]
- public static ILogger GetLogger()
- {
- return logger;
- }
-
- [Obsolete("HACK: To support TraceListener with TraceSource via web.config")]
- public static Func GetConfiguredTimerStrategy()
- {
- return () =>
- {
- try
- {
- return timerStrategy();
- }
- catch
- {
- // Avoid exception being thrown from threads without access to request store
- return null;
- }
- };
- }
-
- [Obsolete("HACK: To support TraceListener with TraceSource via web.config")]
- public static IMessageBroker GetConfiguredMessageBroker()
- {
- return messageBroker;
- }
- }
-}
diff --git a/source/Glimpse.Core/Framework/GlimpseMetadata.cs b/source/Glimpse.Core/Framework/GlimpseMetadata.cs
deleted file mode 100644
index 95cf902f2..000000000
--- a/source/Glimpse.Core/Framework/GlimpseMetadata.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-using System.Collections.Generic;
-
-namespace Glimpse.Core.Framework
-{
- ///
- /// A class which describes Glimpse system metadata, as required by a client.
- ///
- public class GlimpseMetadata
- {
- ///
- /// Initializes a new instance of the class.
- ///
- public GlimpseMetadata()
- {
- Tabs = new Dictionary();
-
- Resources = new Dictionary();
- }
-
- ///
- /// Gets or sets the running version of Glimpse.
- ///
- ///
- /// The running version of Glimpse.
- ///
- public string Version { get; set; }
-
- ///
- /// Gets or sets the hash used for HTTP cache busting.
- ///
- ///
- /// The CRC32 hash of Glimpse's configuration.
- ///
- public string Hash { get; set; }
-
- ///
- /// Gets or sets the collection of tab specific metadata.
- ///
- ///
- /// The tab's metadata.
- ///
- public IDictionary Tabs { get; set; }
-
- ///
- /// Gets or sets the collection resources keys and their corresponding Uri templates.
- ///
- ///
- /// The resources keys and Uri templates.
- ///
- public IDictionary Resources { get; set; }
- }
-}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/GlimpseRequest.cs b/source/Glimpse.Core/Framework/GlimpseRequest.cs
index decf72e5f..32035cdfb 100644
--- a/source/Glimpse.Core/Framework/GlimpseRequest.cs
+++ b/source/Glimpse.Core/Framework/GlimpseRequest.cs
@@ -24,7 +24,8 @@ public GlimpseRequest()
/// The plugin data.
/// The display data
/// The duration.
- public GlimpseRequest(Guid requestId, IRequestMetadata requestMetadata, IDictionary tabData, IDictionary displayData, TimeSpan duration)
+ /// The metadata
+ public GlimpseRequest(Guid requestId, IRequestMetadata requestMetadata, IDictionary tabData, IDictionary displayData, TimeSpan duration, IDictionary instanceMetadata)
: this()
{
RequestId = requestId;
@@ -34,25 +35,18 @@ public GlimpseRequest(Guid requestId, IRequestMetadata requestMetadata, IDiction
RequestHttpMethod = requestMetadata.RequestHttpMethod;
RequestIsAjax = requestMetadata.RequestIsAjax;
- RequestUri = requestMetadata.RequestUri;
+ RequestUri = requestMetadata.RequestUri.PathAndQuery;
ResponseStatusCode = requestMetadata.ResponseStatusCode;
ResponseContentType = requestMetadata.ResponseContentType;
ClientId = requestMetadata.GetCookie(Constants.ClientIdCookieName) ?? requestMetadata.ClientId;
UserAgent = requestMetadata.GetHttpHeader(Constants.UserAgentHeaderName);
+ Metadata = instanceMetadata;
Guid parentRequestId;
-
-#if NET35
- if (RequestIsAjax && Glimpse.Core.Backport.Net35Backport.TryParseGuid(requestMetadata.GetHttpHeader(Constants.HttpRequestHeader), out parentRequestId))
- {
- ParentRequestId = parentRequestId;
- }
-#else
if (RequestIsAjax && Guid.TryParse(requestMetadata.GetHttpHeader(Constants.HttpRequestHeader), out parentRequestId))
{
ParentRequestId = parentRequestId;
}
-#endif
}
///
@@ -145,6 +139,14 @@ public GlimpseRequest(Guid requestId, IRequestMetadata requestMetadata, IDiction
public IDictionary DisplayData { get; set; }
+ ///
+ /// Gets or sets the metadata that targeted at this specific request.
+ ///
+ ///
+ /// The metadata data.
+ ///
+ public IDictionary Metadata { get; set; }
+
///
/// Gets or sets the user agent for the request.
///
diff --git a/source/Glimpse.Core/Framework/GlimpseRequestContext.cs b/source/Glimpse.Core/Framework/GlimpseRequestContext.cs
new file mode 100644
index 000000000..c11ead50f
--- /dev/null
+++ b/source/Glimpse.Core/Framework/GlimpseRequestContext.cs
@@ -0,0 +1,160 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using Glimpse.Core.Extensibility;
+
+namespace Glimpse.Core.Framework
+{
+ ///
+ /// Represents the context of a specific request, which is used as an access point to the request's handle
+ ///
+ internal sealed class GlimpseRequestContext : IGlimpseRequestContext
+ {
+ private RuntimePolicyDeterminator RuntimePolicyDeterminator { get; set; }
+
+ private RuntimePolicy currentRuntimePolicy;
+ private IExecutionTimer activeExecutionTimer;
+
+ private Stopwatch GlobalStopwatch { get; set; }
+
+ ///
+ /// Initializes a new instance of the
+ ///
+ /// The of this request.
+ /// The initial for this request.
+ /// The .
+ /// The endpoint base URI.
+ /// The runtime policy determinator
+ /// The script tags generator
+ /// The callback used by the in case an exception occurs.
+ public GlimpseRequestContext(
+ IRequestResponseAdapter requestResponseAdapter,
+ RuntimePolicy initialRuntimePolicy,
+ IResourceEndpointConfiguration resourceEndpointConfiguration,
+ string endpointBaseUri,
+ RuntimePolicyDeterminator runtimePolicyDeterminator,
+ IScriptTagsGenerator scriptTagsGenerator,
+ Action onScriptTagGenerationExceptionCallback = null)
+ {
+ Guard.ArgumentNotNull("requestResponseAdapter", requestResponseAdapter);
+ Guard.ArgumentNotNull("resourceEndpointConfiguration", resourceEndpointConfiguration);
+ Guard.ArgumentNotNull("runtimePolicyDeterminator", runtimePolicyDeterminator);
+
+ if (string.IsNullOrEmpty(endpointBaseUri))
+ {
+ throw new ArgumentException("endpointBaseUri is null or empty");
+ }
+
+ GlimpseRequestId = Guid.NewGuid();
+ RequestResponseAdapter = requestResponseAdapter;
+ RuntimePolicyDeterminator = runtimePolicyDeterminator;
+
+ ScriptTagsProvider = new ScriptTagsProvider(GlimpseRequestId, scriptTagsGenerator, IsAllowedToProvideScriptTags, onScriptTagGenerationExceptionCallback);
+
+ RequestHandlingMode = resourceEndpointConfiguration.IsResourceRequest(requestResponseAdapter.RequestMetadata.RequestUri, endpointBaseUri)
+ ? RequestHandlingMode.ResourceRequest
+ : RequestHandlingMode.RegularRequest;
+
+ RequestStore = new DictionaryDataStoreAdapter(new Dictionary());
+ this.currentRuntimePolicy = initialRuntimePolicy;
+ }
+
+ ///
+ /// Gets the Glimpse Id assigned to this request
+ ///
+ public Guid GlimpseRequestId { get; private set; }
+
+ ///
+ /// Gets the for the referenced request
+ ///
+ public IRequestResponseAdapter RequestResponseAdapter { get; private set; }
+
+ ///
+ /// Gets the for this request
+ ///
+ public IDataStore RequestStore { get; private set; }
+
+ ///
+ /// Gets or sets the active for the referenced request
+ ///
+ public RuntimePolicy CurrentRuntimePolicy
+ {
+ get
+ {
+ return this.currentRuntimePolicy;
+ }
+
+ set
+ {
+ if (value > this.currentRuntimePolicy)
+ {
+ throw new GlimpseException("You're not allowed to increase the active runtime policy level from '" + this.currentRuntimePolicy + "' to '" + value + "'.");
+ }
+
+ this.currentRuntimePolicy = value;
+ }
+ }
+
+ ///
+ /// Gets the for the referenced request
+ ///
+ public RequestHandlingMode RequestHandlingMode { get; private set; }
+
+ ///
+ /// Gets the for the referenced request
+ ///
+ public IScriptTagsProvider ScriptTagsProvider { get; private set; }
+
+ ///
+ /// Gets the for the referenced request
+ ///
+ public IExecutionTimer CurrentExecutionTimer
+ {
+ get
+ {
+ if (activeExecutionTimer == null)
+ {
+ throw new GlimpseException("Execution timer is not available, did you start timing?");
+ }
+
+ return activeExecutionTimer;
+ }
+
+ private set
+ {
+ activeExecutionTimer = value;
+ }
+ }
+
+ ///
+ /// Starts timing the execution of the referenced request
+ ///
+ public void StartTiming()
+ {
+ if (GlobalStopwatch != null)
+ {
+ throw new GlimpseException("Timing already started");
+ }
+
+ GlobalStopwatch = Stopwatch.StartNew();
+ CurrentExecutionTimer = new ExecutionTimer(GlobalStopwatch);
+ }
+
+ ///
+ /// Stops timing the execution of the referenced request
+ ///
+ /// The elapsed time since the start of the timing
+ public TimeSpan StopTiming()
+ {
+ GlobalStopwatch.Stop();
+ return GlobalStopwatch.Elapsed;
+ }
+
+ private bool IsAllowedToProvideScriptTags()
+ {
+ // we reuse the same runtime event but were are not causing side effects as the result is not stored in the current runtime policy
+ var policy = RuntimePolicyDeterminator.DetermineRuntimePolicy(RuntimeEvent.EndRequest, CurrentRuntimePolicy, RequestResponseAdapter);
+ return policy.HasFlag(RuntimePolicy.DisplayGlimpseClient);
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/GlimpseRequestContextHandle.cs b/source/Glimpse.Core/Framework/GlimpseRequestContextHandle.cs
new file mode 100644
index 000000000..3bb1ec19c
--- /dev/null
+++ b/source/Glimpse.Core/Framework/GlimpseRequestContextHandle.cs
@@ -0,0 +1,86 @@
+using System;
+using Glimpse.Core.Extensibility;
+
+namespace Glimpse.Core.Framework
+{
+ ///
+ /// This is a handle that contains the necessary information to track a corresponding and which will
+ /// make sure the instance, who created this handle, will be notified when it is being disposed,
+ /// either explicitly or implicitly when the finalizer of this handle is run by the Garbage Collector.
+ ///
+ public class GlimpseRequestContextHandle : IDisposable
+ {
+ private bool Disposed { get; set; }
+
+ private Action OnDisposeCallback { get; set; }
+
+ ///
+ /// Initializes a new instance of the
+ ///
+ /// The Id assigned to the request by Glimpse.
+ /// Mode representing the way Glimpse is handling the request.
+ /// The callback to be executed when this instance is being disposed.
+ internal GlimpseRequestContextHandle(Guid glimpseRequestId, RequestHandlingMode requestHandlingMode, Action onDisposeCallback)
+ {
+ if (onDisposeCallback == null)
+ {
+ throw new ArgumentNullException("onDisposeCallback");
+ }
+
+ GlimpseRequestId = glimpseRequestId;
+ RequestHandlingMode = requestHandlingMode;
+ OnDisposeCallback = onDisposeCallback;
+ }
+
+ ///
+ /// Finalizes the instance
+ ///
+ ~GlimpseRequestContextHandle()
+ {
+ Dispose(false);
+ }
+
+ ///
+ /// Gets the Glimpse Id assigned to this request
+ ///
+ public Guid GlimpseRequestId { get; private set; }
+
+ ///
+ /// Gets the mode indicating how Glimpse is handling this request
+ ///
+ public RequestHandlingMode RequestHandlingMode { get; private set; }
+
+ ///
+ /// Disposes the handle, which will make sure the instance, who created this handle, will be notified.
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Disposes the handle, which will make sure the instance, who created this handle, will be notified.
+ ///
+ /// Boolean indicating whether this method is called from the public method or from within the finalizer
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!Disposed)
+ {
+ if (disposing)
+ {
+ }
+
+ try
+ {
+ OnDisposeCallback();
+ Disposed = true;
+ }
+ catch (Exception disposeException)
+ {
+ GlimpseRuntime.Instance.Configuration.Logger.Error("Failed to dispose Glimpse request context handle", disposeException);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/GlimpseRuntime.cs b/source/Glimpse.Core/Framework/GlimpseRuntime.cs
index 5f1c1e362..1a8a75daf 100644
--- a/source/Glimpse.Core/Framework/GlimpseRuntime.cs
+++ b/source/Glimpse.Core/Framework/GlimpseRuntime.cs
@@ -1,30 +1,20 @@
using System;
-using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
using System.Reflection;
-using System.Text;
using Glimpse.Core.Extensibility;
-using Glimpse.Core.Extensions;
using Glimpse.Core.Message;
using Glimpse.Core.ResourceResult;
-using Glimpse.Core.Tab.Assist;
-using Tavis.UriTemplates;
-
-#if NET35
-using Glimpse.Core.Backport;
-#endif
namespace Glimpse.Core.Framework
{
///
- /// The heart and soul of Glimpse. The runtime coordinate all input from a , persists collected runtime information and writes responses out to the .
+ /// The heart and soul of Glimpse. The runtime coordinate all input from a , persists collected runtime information and writes responses out to the .
///
- public class GlimpseRuntime : IGlimpseRuntime
+ public partial class GlimpseRuntime : IGlimpseRuntime
{
private static readonly MethodInfo MethodInfoBeginRequest = typeof(GlimpseRuntime).GetMethod("BeginRequest", BindingFlags.Public | BindingFlags.Instance);
private static readonly MethodInfo MethodInfoEndRequest = typeof(GlimpseRuntime).GetMethod("EndRequest", BindingFlags.Public | BindingFlags.Instance);
- private static readonly object LockObj = new object();
+ private static IGlimpseRuntime instance;
///
/// Initializes static members of the class.
@@ -32,9 +22,7 @@ public class GlimpseRuntime : IGlimpseRuntime
/// BeginRequest method not found
static GlimpseRuntime()
{
- // Version is in major.minor.build format to support http://semver.org/
- // TODO: Consider adding configuration hash to version
- Version = Assembly.GetExecutingAssembly().GetName().Version.ToString(3);
+ Initializer = new GlimpseRuntimeInitializer();
if (MethodInfoBeginRequest == null)
{
@@ -48,28 +36,73 @@ static GlimpseRuntime()
}
///
- /// Initializes a new instance of the class.
+ /// Gets the which will initialize the and set the
///
- /// The configuration.
- /// Throws an exception if is null.
- public GlimpseRuntime(IGlimpseConfiguration configuration)
+ public static GlimpseRuntimeInitializer Initializer { get; private set; }
+
+ ///
+ /// Gets a value indicating whether the Glimpse runtime is available.
+ ///
+ ///
+ /// true if the Glimpse runtime is available; otherwise, false.
+ ///
+ public static bool IsAvailable
{
- if (configuration == null)
+ get { return instance != null; }
+ }
+
+ ///
+ /// Gets the instance set during the initialization of the Glimpse runtime
+ ///
+ public static IGlimpseRuntime Instance
+ {
+ get
{
- throw new ArgumentNullException("configuration");
+ if (!IsAvailable)
+ {
+ throw new GlimpseRuntimeNotAvailableException();
+ }
+
+ return instance;
}
- Configuration = configuration;
+ internal set
+ {
+ instance = value;
+ }
}
///
- /// Gets the executing version of Glimpse.
+ /// Initializes a new instance of the
///
- ///
- /// The version of Glimpse.
- ///
- /// Glimpse versioning follows the rules of Semantic Versioning.
- public static string Version { get; private set; }
+ /// The configuration
+ /// The store for active instances
+ /// The runtime policy determinator
+ /// The metadata provider
+ /// The tab provider
+ /// The display provider
+ internal GlimpseRuntime(
+ IReadonlyConfiguration configuration,
+ ActiveGlimpseRequestContexts activeGlimpseRequestContexts,
+ RuntimePolicyDeterminator runtimePolicyDeterminator,
+ MetadataProvider metadataProvider,
+ TabProvider tabProvider,
+ DisplayProvider displayProvider)
+ {
+ Guard.ArgumentNotNull("configuration", configuration);
+ Guard.ArgumentNotNull("activeGlimpseRequestContexts", activeGlimpseRequestContexts);
+ Guard.ArgumentNotNull("runtimePolicyDeterminator", runtimePolicyDeterminator);
+ Guard.ArgumentNotNull("metadataProvider", metadataProvider);
+ Guard.ArgumentNotNull("tabProvider", tabProvider);
+ Guard.ArgumentNotNull("displayProvider", displayProvider);
+
+ Configuration = configuration;
+ ActiveGlimpseRequestContexts = activeGlimpseRequestContexts;
+ RuntimePolicyDeterminator = runtimePolicyDeterminator;
+ MetadataProvider = metadataProvider;
+ TabProvider = tabProvider;
+ DisplayProvider = displayProvider;
+ }
///
/// Gets or sets the configuration.
@@ -77,204 +110,192 @@ public GlimpseRuntime(IGlimpseConfiguration configuration)
///
/// The configuration.
///
- public IGlimpseConfiguration Configuration { get; set; }
+ public IReadonlyConfiguration Configuration { get; private set; }
///
- /// Gets a value indicating whether this instance has been initialized.
+ /// Returns the corresponding to the current request.
///
- ///
- /// true if this instance is initialized; otherwise, false.
- ///
- public bool IsInitialized { get; private set; }
-
- private IDictionary TabResultsStore
+ public IGlimpseRequestContext CurrentRequestContext
{
- get
- {
- var requestStore = Configuration.FrameworkProvider.HttpRequestStore;
- var result = requestStore.Get>(Constants.TabResultsDataStoreKey);
+ get { return ActiveGlimpseRequestContexts.Current; }
+ }
- if (result == null)
- {
- result = new Dictionary();
- requestStore.Set(Constants.TabResultsDataStoreKey, result);
- }
+ private ActiveGlimpseRequestContexts ActiveGlimpseRequestContexts { get; set; }
- return result;
- }
- }
+ private RuntimePolicyDeterminator RuntimePolicyDeterminator { get; set; }
- private IDictionary DisplayResultsStore
- {
- get
- {
- var requestStore = Configuration.FrameworkProvider.HttpRequestStore;
- var result = requestStore.Get>(Constants.DisplayResultsDataStoreKey);
+ private MetadataProvider MetadataProvider { get; set; }
- if (result == null)
- {
- result = new Dictionary();
- requestStore.Set(Constants.DisplayResultsDataStoreKey, result);
- }
+ private TabProvider TabProvider { get; set; }
- return result;
- }
- }
+ private DisplayProvider DisplayProvider { get; set; }
///
/// Begins Glimpse's processing of a Http request.
///
/// Throws an exception if is not yet initialized.
- public void BeginRequest()
+ public GlimpseRequestContextHandle BeginRequest(IRequestResponseAdapter requestResponseAdapter)
{
- if (!IsInitialized)
+ var glimpseRequestContext = new GlimpseRequestContext(
+ requestResponseAdapter,
+ Configuration.DefaultRuntimePolicy,
+ Configuration.ResourceEndpoint,
+ Configuration.EndpointBaseUri,
+ RuntimePolicyDeterminator,
+ new ScriptTagsGenerator(Configuration),
+ Configuration.Logger.Error);
+
+ var runtimePolicy = RuntimePolicyDeterminator.DetermineRuntimePolicy(RuntimeEvent.BeginRequest, glimpseRequestContext.CurrentRuntimePolicy, glimpseRequestContext.RequestResponseAdapter);
+
+ // we check if we are dealing with a resource request, because it is possible that users are requesting the configuration resource to enable Glimpse in the first place, this will be checked while executing the resource
+ if (runtimePolicy == RuntimePolicy.Off && glimpseRequestContext.RequestHandlingMode != RequestHandlingMode.ResourceRequest)
{
- throw new GlimpseException(Resources.BeginRequestOutOfOrderRuntimeMethodCall);
+ return UnavailableGlimpseRequestContextHandle.Instance;
}
- if (HasOffRuntimePolicy(RuntimeEvent.BeginRequest))
+ glimpseRequestContext.CurrentRuntimePolicy = runtimePolicy;
+
+ var glimpseRequestContextHandle = ActiveGlimpseRequestContexts.Add(glimpseRequestContext);
+
+ try
{
- return;
- }
+ glimpseRequestContext.StartTiming();
- ExecuteTabs(RuntimeEvent.BeginRequest);
+ // When we are dealing with a resource request, there is no need to further
+ // continue setting up the request.
+ if (glimpseRequestContextHandle.RequestHandlingMode == RequestHandlingMode.ResourceRequest)
+ {
+ return glimpseRequestContextHandle;
+ }
- var requestStore = Configuration.FrameworkProvider.HttpRequestStore;
+ var options = new ScriptTagsInjectionOptions(
+ glimpseRequestContext.ScriptTagsProvider,
+ () => requestResponseAdapter.ResponseEncoding,
+ (sender, args) => Configuration.Logger.Warn(
+ "Failed to inject the Glimpse script tags for request '{0}' : {1}",
+ requestResponseAdapter.RequestMetadata.RequestUri.AbsoluteUri,
+ args.FailureMessage));
- // Give Request an ID
- var requestId = Guid.NewGuid();
- requestStore.Set(Constants.RequestIdKey, requestId);
- Func generateClientScripts = (rId) => rId.HasValue ? GenerateScriptTags(rId.Value) : GenerateScriptTags(requestId);
- requestStore.Set(Constants.ClientScriptsStrategy, generateClientScripts);
+ requestResponseAdapter.OutputStream = new ScriptTagsInjectionStream(requestResponseAdapter.OutputStream, options);
- var executionTimer = CreateAndStartGlobalExecutionTimer(requestStore);
+ TabProvider.Execute(glimpseRequestContext, RuntimeEvent.BeginRequest);
- Configuration.MessageBroker.Publish(new RuntimeMessage().AsSourceMessage(typeof(GlimpseRuntime), MethodInfoBeginRequest).AsTimelineMessage("Start Request", TimelineCategory.Request).AsTimedMessage(executionTimer.Point()));
- }
+ GlimpseTimeline.CaptureMoment("Start Request", TimelineCategory.Request, new RuntimeMessage().AsSourceMessage(typeof(GlimpseRuntime), MethodInfoBeginRequest));
- private bool HasOffRuntimePolicy(RuntimeEvent policyName)
- {
- var policy = DetermineAndStoreAccumulatedRuntimePolicy(policyName);
- return policy.HasFlag(RuntimePolicy.Off);
+ return glimpseRequestContextHandle;
+ }
+ catch
+ {
+ // We need to deactivate here because the handle won't be returned to the caller
+ glimpseRequestContextHandle.Dispose();
+ throw;
+ }
}
///
- /// Ends Glimpse's processing a Http request.
+ /// Ends Glimpse's processing of the request referenced by the given "/>
///
- /// Throws an exception if BeginRequest has not yet been called on a given request.
- public void EndRequest() // TODO: Add PRG support
+ /// The Glimpse handle of the corresponding request
+ /// Throws an exception if BeginRequest has not yet been called for the given request.
+ public void EndRequest(GlimpseRequestContextHandle glimpseRequestContextHandle)
{
- if (HasOffRuntimePolicy(RuntimeEvent.EndRequest))
+ if (glimpseRequestContextHandle == null)
{
- return;
+ throw new ArgumentNullException("glimpseRequestContextHandle");
}
- var frameworkProvider = Configuration.FrameworkProvider;
- var requestStore = frameworkProvider.HttpRequestStore;
-
- var executionTimer = requestStore.Get(Constants.GlobalTimerKey);
- if (executionTimer != null)
- {
- Configuration.MessageBroker.Publish(new RuntimeMessage().AsSourceMessage(typeof(GlimpseRuntime), MethodInfoBeginRequest).AsTimelineMessage("End Request", TimelineCategory.Request).AsTimedMessage(executionTimer.Point()));
- }
-
- ExecuteTabs(RuntimeEvent.EndRequest);
- ExecuteDisplays();
-
- Guid requestId;
- Stopwatch stopwatch;
try
{
- requestId = requestStore.Get(Constants.RequestIdKey);
- stopwatch = requestStore.Get(Constants.GlobalStopwatchKey);
- stopwatch.Stop();
- }
- catch (NullReferenceException ex)
- {
- throw new GlimpseException(Resources.EndRequestOutOfOrderRuntimeMethodCall, ex);
- }
+ IGlimpseRequestContext glimpseRequestContext;
+ if (!ContinueProcessingRequest(glimpseRequestContextHandle, RuntimeEvent.EndRequest, RequestHandlingMode.RegularRequest, out glimpseRequestContext))
+ {
+ return;
+ }
- var requestMetadata = frameworkProvider.RequestMetadata;
- var policy = DetermineAndStoreAccumulatedRuntimePolicy(RuntimeEvent.EndRequest);
- if (policy.HasFlag(RuntimePolicy.PersistResults))
- {
- var persistenceStore = Configuration.PersistenceStore;
+ GlimpseTimeline.CaptureMoment("End Request", TimelineCategory.Request, new RuntimeMessage().AsSourceMessage(typeof(GlimpseRuntime), MethodInfoBeginRequest));
- var metadata = new GlimpseRequest(requestId, requestMetadata, TabResultsStore, DisplayResultsStore, stopwatch.Elapsed);
+ TabProvider.Execute(glimpseRequestContext, RuntimeEvent.EndRequest);
+ DisplayProvider.Execute(glimpseRequestContext);
- try
- {
- persistenceStore.Save(metadata);
- }
- catch (Exception exception)
+ var timingDuration = glimpseRequestContext.StopTiming();
+ var requestResponseAdapter = glimpseRequestContext.RequestResponseAdapter;
+ var requestMetadata = requestResponseAdapter.RequestMetadata;
+
+ var runtimePolicy = glimpseRequestContext.CurrentRuntimePolicy;
+ if (runtimePolicy.HasFlag(RuntimePolicy.PersistResults))
{
- Configuration.Logger.Error(Resources.GlimpseRuntimeEndRequesPersistError, exception, persistenceStore.GetType());
- }
- }
+ var persistenceStore = Configuration.PersistenceStore;
+ var metadata = new GlimpseRequest(glimpseRequestContext.GlimpseRequestId, requestMetadata, TabProvider.GetResultsStore(glimpseRequestContext), DisplayProvider.GetResultsStore(glimpseRequestContext), timingDuration, MetadataProvider.GetRequestMetadata(glimpseRequestContext));
- if (policy.HasFlag(RuntimePolicy.ModifyResponseHeaders))
- {
- frameworkProvider.SetHttpResponseHeader(Constants.HttpResponseHeader, requestId.ToString());
+ try
+ {
+ persistenceStore.Save(metadata);
+ }
+ catch (Exception exception)
+ {
+ Configuration.Logger.Error(Resources.GlimpseRuntimeEndRequesPersistError, exception, persistenceStore.GetType());
+ }
+ }
- if (requestMetadata.GetCookie(Constants.ClientIdCookieName) == null)
+ if (runtimePolicy.HasFlag(RuntimePolicy.ModifyResponseHeaders))
{
- frameworkProvider.SetCookie(Constants.ClientIdCookieName, requestMetadata.ClientId);
+ requestResponseAdapter.SetHttpResponseHeader(Constants.HttpResponseHeader, glimpseRequestContext.GlimpseRequestId.ToString());
+
+ if (requestMetadata.GetCookie(Constants.ClientIdCookieName) == null)
+ {
+ requestResponseAdapter.SetCookie(Constants.ClientIdCookieName, requestMetadata.ClientId);
+ }
}
}
-
- if (policy.HasFlag(RuntimePolicy.DisplayGlimpseClient))
+ finally
{
- var html = GenerateScriptTags(requestId);
-
- frameworkProvider.InjectHttpResponseBody(html);
+ glimpseRequestContextHandle.Dispose();
}
}
- ///
- /// Executes the default resource.
- ///
- public void ExecuteDefaultResource()
- {
- ExecuteResource(Configuration.DefaultResource.Name, ResourceParameters.None());
- }
-
///
/// Begins access to session data.
///
- public void BeginSessionAccess()
+ public void BeginSessionAccess(GlimpseRequestContextHandle glimpseRequestContextHandle)
{
- if (HasOffRuntimePolicy(RuntimeEvent.BeginSessionAccess))
+ IGlimpseRequestContext glimpseRequestContext;
+ if (ContinueProcessingRequest(glimpseRequestContextHandle, RuntimeEvent.BeginSessionAccess, RequestHandlingMode.RegularRequest, out glimpseRequestContext))
{
- return;
+#warning should we add a try catch around this? So that failures in Glimpse don't fail the normal flow?
+ TabProvider.Execute(glimpseRequestContext, RuntimeEvent.BeginSessionAccess);
}
-
- ExecuteTabs(RuntimeEvent.BeginSessionAccess);
}
///
/// Ends access to session data.
///
- public void EndSessionAccess()
+ public void EndSessionAccess(GlimpseRequestContextHandle glimpseRequestContextHandle)
{
- if (HasOffRuntimePolicy(RuntimeEvent.EndSessionAccess))
+ IGlimpseRequestContext glimpseRequestContext;
+ if (ContinueProcessingRequest(glimpseRequestContextHandle, RuntimeEvent.EndSessionAccess, RequestHandlingMode.RegularRequest, out glimpseRequestContext))
{
- return;
+#warning should we add a try catch around this? So that failures in Glimpse don't fail the normal flow?
+ TabProvider.Execute(glimpseRequestContext, RuntimeEvent.EndSessionAccess);
}
-
- ExecuteTabs(RuntimeEvent.EndSessionAccess);
}
///
- /// Executes the resource.
+ /// Executes the given resource.
///
+ /// The Glimpse handle of the corresponding request
/// Name of the resource.
/// The parameters.
/// Throws an exception if either parameter is null.
- public void ExecuteResource(string resourceName, ResourceParameters parameters)
+ public void ExecuteResource(GlimpseRequestContextHandle glimpseRequestContextHandle, string resourceName, ResourceParameters parameters)
{
+ if (glimpseRequestContextHandle == null)
+ {
+ throw new ArgumentNullException("glimpseRequestContextHandle");
+ }
+
if (string.IsNullOrEmpty(resourceName))
{
- throw new ArgumentNullException("resourceName");
+ resourceName = Configuration.DefaultResource.Name;
}
if (parameters == null)
@@ -282,79 +303,84 @@ public void ExecuteResource(string resourceName, ResourceParameters parameters)
throw new ArgumentNullException("parameters");
}
- string message;
- var logger = Configuration.Logger;
- var context = new ResourceResultContext(logger, Configuration.FrameworkProvider, Configuration.Serializer, Configuration.HtmlEncoder);
+ IGlimpseRequestContext glimpseRequestContext;
+ if (!TryGetRequestContext(glimpseRequestContextHandle.GlimpseRequestId, out glimpseRequestContext))
+ {
+#warning or maybe only a log and return false instead of throwing an exception? It is an issue though!
+ throw new GlimpseException("No corresponding GlimpseRequestContext found for GlimpseRequestId '" + glimpseRequestContextHandle.GlimpseRequestId + "'.");
+ }
+
+ var requestResponseAdapter = glimpseRequestContext.RequestResponseAdapter;
- // First we determine the current policy as it has been processed so far
- RuntimePolicy policy = DetermineAndStoreAccumulatedRuntimePolicy(RuntimeEvent.ExecuteResource);
+ // First we get the current policy as it has been processed so far (by the GlimpseRuntime.BeginRequest)
+ var policy = glimpseRequestContext.CurrentRuntimePolicy;
- // It is possible that the policy now says Off, but if the requested resource is the default resource or one of it dependent resources,
- // then we need to make sure there is a good reason for not executing that resource, since the default resource (or one of it dependencies)
- // is the one we most likely need to set Glimpse On with in the first place.
- IDependOnResources defaultResourceDependsOnResources = Configuration.DefaultResource as IDependOnResources;
+ // No matter what the current policy now says (On, Off, ...), if the requested resource is the
+ // default resource or one of its dependent resources, then we need to make sure there
+ // is a good reason for not executing that resource, since the default resource (or one of its
+ // dependencies) is the one we most likely need to activate Glimpse with in the first place.
+ var defaultResourceDependsOnResources = Configuration.DefaultResource as IDependOnResources;
if (resourceName.Equals(Configuration.DefaultResource.Name) || (defaultResourceDependsOnResources != null && defaultResourceDependsOnResources.DependsOn(resourceName)))
{
- // To be clear we only do this for the default resource (or its dependencies), and we do this because it allows us to secure the default resource
- // the same way as any other resource, but for this we only rely on runtime policies that handle ExecuteResource runtime events and we ignore
- // ignore previously executed runtime policies (most likely during BeginRequest).
- // Either way, the default runtime policy is still our starting point and when it says Off, it remains Off
- policy = DetermineRuntimePolicy(RuntimeEvent.ExecuteResource, Configuration.DefaultRuntimePolicy);
+ // To be clear we only do this for the default resource (or its dependencies), and
+ // we do this because it allows us to secure the default resource the same way as
+ // any other resource, but for this we only rely on runtime policies that handle
+ // ExecuteResource runtime events and we ignore previously executed runtime
+ // policies (most likely during BeginRequest). Either way, the default runtime policy
+ // is still our starting point and when it says Off, it remains Off
+ policy = RuntimePolicyDeterminator.DetermineRuntimePolicy(RuntimeEvent.ExecuteResource, Configuration.DefaultRuntimePolicy, requestResponseAdapter);
}
+ IResourceResult result;
+ string message;
+ var logger = Configuration.Logger;
+
if (policy == RuntimePolicy.Off)
{
- string errorMessage = string.Format(Resources.ExecuteResourceInsufficientPolicy, resourceName);
- logger.Info(errorMessage);
- new StatusCodeResourceResult(403, errorMessage).Execute(context);
- return;
+ message = string.Format(Resources.ExecuteResourceInsufficientPolicy, resourceName);
+ logger.Info(message);
+ result = new StatusCodeResourceResult(403, message);
}
-
- var resources =
- Configuration.Resources.Where(
- r => r.Name.Equals(resourceName, StringComparison.InvariantCultureIgnoreCase));
-
- IResourceResult result;
- switch (resources.Count())
+ else
{
- case 1: // 200 - OK
- try
- {
- var resource = resources.First();
- var resourceContext = new ResourceContext(parameters.GetParametersFor(resource), Configuration.PersistenceStore, logger);
-
- var privilegedResource = resource as IPrivilegedResource;
-
- if (privilegedResource != null)
+ var resources = Configuration.Resources.Where(r => r.Name.Equals(resourceName, StringComparison.InvariantCultureIgnoreCase)).ToArray();
+ switch (resources.Length)
+ {
+ case 1: // 200 - OK
+ try
{
- result = privilegedResource.Execute(resourceContext, Configuration);
+ var resource = resources[0];
+ var resourceContext = new ResourceContext(parameters.GetParametersFor(resource), Configuration.PersistenceStore, logger);
+
+ var privilegedResource = resource as IPrivilegedResource;
+ result = privilegedResource != null
+ ? privilegedResource.Execute(resourceContext, Configuration, requestResponseAdapter)
+ : resource.Execute(resourceContext);
}
- else
+ catch (Exception ex)
{
- result = resource.Execute(resourceContext);
+ logger.Error(Resources.GlimpseRuntimeExecuteResourceError, ex, resourceName);
+ result = new ExceptionResourceResult(ex);
}
- }
- catch (Exception ex)
- {
- logger.Error(Resources.GlimpseRuntimeExecuteResourceError, ex, resourceName);
- result = new ExceptionResourceResult(ex);
- }
- break;
- case 0: // 404 - File Not Found
- message = string.Format(Resources.ExecuteResourceMissingError, resourceName);
- logger.Warn(message);
- result = new StatusCodeResourceResult(404, message);
- break;
- default: // 500 - Server Error
- message = string.Format(Resources.ExecuteResourceDuplicateError, resourceName);
- logger.Warn(message);
- result = new StatusCodeResourceResult(500, message);
- break;
+ break;
+ case 0: // 404 - File Not Found
+ message = string.Format(Resources.ExecuteResourceMissingError, resourceName);
+ logger.Warn(message);
+ result = new StatusCodeResourceResult(404, message);
+ break;
+ default: // 500 - Server Error
+ message = string.Format(Resources.ExecuteResourceDuplicateError, resourceName);
+ logger.Warn(message);
+ result = new StatusCodeResourceResult(500, message);
+ break;
+ }
}
try
{
+ var context = new ResourceResultContext(logger, requestResponseAdapter, Configuration.Serializer, Configuration.HtmlEncoder);
+
result.Execute(context);
}
catch (Exception exception)
@@ -364,538 +390,83 @@ public void ExecuteResource(string resourceName, ResourceParameters parameters)
}
///
- /// Initializes this instance of the Glimpse runtime.
+ /// Returns the corresponding for the given
///
- ///
- /// true if system initialized successfully, false otherwise
- ///
- public bool Initialize()
+ /// The Glimpse request Id
+ /// The corresponding
+ /// Boolean indicating whether the corresponding was found.
+ public bool TryGetRequestContext(Guid glimpseRequestId, out IGlimpseRequestContext glimpseRequestContext)
{
- var policy = RuntimePolicy.Off;
-
- // Double checked lock to ensure thread safety. http://en.wikipedia.org/wiki/Double_checked_locking_pattern
- if (!IsInitialized)
- {
- lock (LockObj)
- {
- if (!IsInitialized)
- {
- var logger = Configuration.Logger;
- policy = DetermineAndStoreAccumulatedRuntimePolicy(RuntimeEvent.Initialize);
-
- if (policy != RuntimePolicy.Off)
- {
- CreateAndStartGlobalExecutionTimer(Configuration.FrameworkProvider.HttpRequestStore);
-
- var messageBroker = Configuration.MessageBroker;
-
- // TODO: Fix this to IDisplay no longer uses I*Tab*Setup
- var displaysThatRequireSetup = Configuration.Displays.Where(display => display is ITabSetup).Select(display => display);
- foreach (ITabSetup display in displaysThatRequireSetup)
- {
- var key = CreateKey(display);
- try
- {
- var setupContext = new TabSetupContext(logger, messageBroker, () => GetTabStore(key));
- display.Setup(setupContext);
- }
- catch (Exception exception)
- {
- logger.Error(Resources.InitializeTabError, exception, key);
- }
- }
-
- var tabsThatRequireSetup = Configuration.Tabs.Where(tab => tab is ITabSetup).Select(tab => tab);
- foreach (ITabSetup tab in tabsThatRequireSetup)
- {
- var key = CreateKey(tab);
- try
- {
- var setupContext = new TabSetupContext(logger, messageBroker, () => GetTabStore(key));
- tab.Setup(setupContext);
- }
- catch (Exception exception)
- {
- logger.Error(Resources.InitializeTabError, exception, key);
- }
- }
-
- var inspectorContext = new InspectorContext(logger, Configuration.ProxyFactory, messageBroker, Configuration.TimerStrategy, Configuration.RuntimePolicyStrategy);
-
- foreach (var inspector in Configuration.Inspectors)
- {
- try
- {
- inspector.Setup(inspectorContext);
- logger.Debug(Resources.GlimpseRuntimeInitializeSetupInspector, inspector.GetType());
- }
- catch (Exception exception)
- {
- logger.Error(Resources.InitializeInspectorError, exception, inspector.GetType());
- }
- }
-
- PersistMetadata();
- }
-
- IsInitialized = true;
- }
- }
- }
-
- return policy != RuntimePolicy.Off;
+ return ActiveGlimpseRequestContexts.TryGet(glimpseRequestId, out glimpseRequestContext);
}
- private static UriTemplate SetParameters(UriTemplate template, IEnumerable> nameValues)
+ private bool ContinueProcessingRequest(GlimpseRequestContextHandle glimpseRequestContextHandle, RuntimeEvent runtimeEvent, RequestHandlingMode allowedRequestHandlingMode, out IGlimpseRequestContext glimpseRequestContext)
{
- if (nameValues == null)
- {
- return template;
- }
+ glimpseRequestContext = null;
- foreach (var pair in nameValues)
+ if (glimpseRequestContextHandle == null)
{
- template.SetParameter(pair.Key, pair.Value);
+ throw new ArgumentNullException("glimpseRequestContextHandle");
}
- return template;
- }
-
- private static ExecutionTimer CreateAndStartGlobalExecutionTimer(IDataStore requestStore)
- {
- if (requestStore.Contains(Constants.GlobalStopwatchKey) && requestStore.Contains(Constants.GlobalTimerKey))
+ if (glimpseRequestContextHandle.RequestHandlingMode != allowedRequestHandlingMode)
{
- return requestStore.Get(Constants.GlobalTimerKey);
+ return false;
}
- // Create and start global stopwatch
- var stopwatch = Stopwatch.StartNew();
- var executionTimer = new ExecutionTimer(stopwatch);
- requestStore.Set(Constants.GlobalStopwatchKey, stopwatch);
- requestStore.Set(Constants.GlobalTimerKey, executionTimer);
- return executionTimer;
- }
-
- private static string CreateKey(object obj)
- {
- string result;
- var keyProvider = obj as IKey;
-
- if (keyProvider != null)
+ if (!TryGetRequestContext(glimpseRequestContextHandle.GlimpseRequestId, out glimpseRequestContext))
{
- result = keyProvider.Key;
- }
- else
- {
- result = obj.GetType().FullName;
+#warning or maybe only a log and return false instead of throwing an exception? It is an issue though!
+ throw new GlimpseException("No corresponding GlimpseRequestContext found for GlimpseRequestId '" + glimpseRequestContextHandle.GlimpseRequestId + "'.");
}
- return result
- .Replace('.', '_')
- .Replace(' ', '_')
- .ToLower();
+ return ContinueProcessingRequest(glimpseRequestContext, runtimeEvent);
}
- private IDataStore GetTabStore(string tabName)
+ private bool ContinueProcessingRequest(IGlimpseRequestContext glimpseRequestContext, RuntimeEvent runtimeEvent)
{
- var requestStore = Configuration.FrameworkProvider.HttpRequestStore;
+ glimpseRequestContext.CurrentRuntimePolicy = RuntimePolicyDeterminator.DetermineRuntimePolicy(runtimeEvent, glimpseRequestContext.CurrentRuntimePolicy, glimpseRequestContext.RequestResponseAdapter);
- if (!requestStore.Contains(Constants.TabStorageKey))
- {
- requestStore.Set(Constants.TabStorageKey, new Dictionary());
- }
-
- var tabStorage = requestStore.Get>(Constants.TabStorageKey);
-
- if (!tabStorage.ContainsKey(tabName))
- {
- tabStorage.Add(tabName, new DictionaryDataStoreAdapter(new Dictionary()));
- }
-
- return tabStorage[tabName];
+ return glimpseRequestContext.CurrentRuntimePolicy != RuntimePolicy.Off;
}
- private void ExecuteTabs(RuntimeEvent runtimeEvent)
+ public void Dispose()
{
- var runtimeContext = Configuration.FrameworkProvider.RuntimeContext;
- var frameworkProviderRuntimeContextType = runtimeContext.GetType();
- var messageBroker = Configuration.MessageBroker;
-
- // Only use tabs that either don't specify a specific context type, or have a context type that matches the current framework provider's.
- var runtimeTabs =
- Configuration.Tabs.Where(
- tab =>
- tab.RequestContextType == null ||
- frameworkProviderRuntimeContextType.IsSubclassOf(tab.RequestContextType) ||
- tab.RequestContextType == frameworkProviderRuntimeContextType);
-
- var supportedRuntimeTabs = runtimeTabs.Where(p => p.ExecuteOn.HasFlag(runtimeEvent));
- var tabResultsStore = TabResultsStore;
- var logger = Configuration.Logger;
-
- foreach (var tab in supportedRuntimeTabs)
+ var disposables = Configuration.ClientScripts.OfType()
+ .Concat(new[] { Configuration.CurrentGlimpseRequestIdTracker }.OfType())
+ .Concat(new[] { Configuration.DefaultResource }.OfType())
+ .Concat(Configuration.Displays.OfType())
+ .Concat(new[] { Configuration.HtmlEncoder }.OfType())
+ .Concat(Configuration.Inspectors.OfType())
+ .Concat(Configuration.InstanceMetadata.OfType())
+ .Concat(new[] { Configuration.MessageBroker }.OfType())
+ .Concat(Configuration.Metadata.OfType())
+ .Concat(new[] { Configuration.PersistenceStore }.OfType())
+ .Concat(new[] { Configuration.ProxyFactory }.OfType())
+ .Concat(new[] { Configuration.ResourceEndpoint }.OfType())
+ .Concat(Configuration.Resources.OfType())
+ .Concat(Configuration.RuntimePolicies.OfType())
+ .Concat(new[] { Configuration.Serializer }.OfType())
+ .Concat(Configuration.TabMetadata.OfType())
+ .Concat(Configuration.Tabs.OfType())
+ .Concat(new[] { Configuration.Logger }.OfType()); // the logger right at the end
+
+ foreach (var disposable in disposables)
{
- TabResult result;
- var key = CreateKey(tab);
try
{
- var tabContext = new TabContext(runtimeContext, GetTabStore(key), logger, messageBroker);
- var tabData = tab.GetData(tabContext);
-
- var tabSection = tabData as TabSection;
- if (tabSection != null)
- {
- tabData = tabSection.Build();
- }
-
- result = new TabResult(tab.Name, tabData);
+ disposable.Dispose();
}
catch (Exception exception)
{
- result = new TabResult(tab.Name, exception.ToString());
- logger.Error(Resources.ExecuteTabError, exception, key);
- }
-
- if (tabResultsStore.ContainsKey(key))
- {
- tabResultsStore[key] = result;
- }
- else
- {
- tabResultsStore.Add(key, result);
- }
- }
- }
-
- private void ExecuteDisplays()
- {
- var runtimeContext = Configuration.FrameworkProvider.RuntimeContext;
- var messageBroker = Configuration.MessageBroker;
-
- var displayResultsStore = DisplayResultsStore;
- var logger = Configuration.Logger;
-
- foreach (var display in Configuration.Displays)
- {
- TabResult result; // TODO: Rename now that it is no longer *just* tab results
- var key = CreateKey(display);
- try
- {
- var displayContext = new TabContext(runtimeContext, GetTabStore(key), logger, messageBroker); // TODO: Do we need a DisplayContext?
- var displayData = display.GetData(displayContext);
-
- result = new TabResult(display.Name, displayData);
- }
- catch (Exception exception)
- {
- result = new TabResult(display.Name, exception.ToString());
- logger.Error(Resources.ExecuteTabError, exception, key);
- }
-
- if (displayResultsStore.ContainsKey(key))
- {
- displayResultsStore[key] = result;
- }
- else
- {
- displayResultsStore.Add(key, result);
- }
- }
- }
-
- private void PersistMetadata()
- {
- var metadata = new GlimpseMetadata { Version = Version, Hash = Configuration.Hash };
- var tabMetadata = metadata.Tabs;
-
- foreach (var tab in Configuration.Tabs)
- {
- var metadataInstance = new TabMetadata();
-
- var documentationTab = tab as IDocumentation;
- if (documentationTab != null)
- {
- metadataInstance.DocumentationUri = documentationTab.DocumentationUri;
- }
-
- var layoutControlTab = tab as ILayoutControl;
- if (layoutControlTab != null)
- {
- metadataInstance.KeysHeadings = layoutControlTab.KeysHeadings;
- }
-
- var layoutTab = tab as ITabLayout;
- if (layoutTab != null)
- {
- metadataInstance.Layout = layoutTab.GetLayout();
- }
-
- if (metadataInstance.HasMetadata)
- {
- tabMetadata[CreateKey(tab)] = metadataInstance;
- }
- }
-
- var resources = metadata.Resources;
- var endpoint = Configuration.ResourceEndpoint;
- var logger = Configuration.Logger;
-
- foreach (var resource in Configuration.Resources)
- {
- var resourceKey = CreateKey(resource);
- if (resources.ContainsKey(resourceKey))
- {
- logger.Warn(Resources.GlimpseRuntimePersistMetadataMultipleResourceWarning, resource.Name);
- }
-
- resources[resourceKey] = endpoint.GenerateUriTemplate(resource, Configuration.EndpointBaseUri, logger);
- }
-
- Configuration.PersistenceStore.Save(metadata);
- }
-
- private RuntimePolicy DetermineRuntimePolicy(RuntimeEvent runtimeEvent, RuntimePolicy maximumAllowedPolicy)
- {
- if (maximumAllowedPolicy == RuntimePolicy.Off)
- {
- return maximumAllowedPolicy;
- }
-
- var frameworkProvider = Configuration.FrameworkProvider;
- var logger = Configuration.Logger;
-
- // only run policies for this runtimeEvent
- var policies =
- Configuration.RuntimePolicies.Where(
- policy => policy.ExecuteOn.HasFlag(runtimeEvent));
-
- var policyContext = new RuntimePolicyContext(frameworkProvider.RequestMetadata, Configuration.Logger, frameworkProvider.RuntimeContext);
- foreach (var policy in policies)
- {
- var policyResult = RuntimePolicy.Off;
- try
- {
- policyResult = policy.Execute(policyContext);
-
- if (policyResult != RuntimePolicy.On)
+ if (!object.ReferenceEquals(disposable, Configuration.Logger))
{
- logger.Debug("RuntimePolicy set to '{0}' by IRuntimePolicy of type '{1}' during RuntimeEvent '{2}'.", policyResult, policy.GetType(), runtimeEvent);
+ Configuration.Logger.Error("Failed disposing '" + disposable.GetType().Name + "'", exception);
}
}
- catch (Exception exception)
- {
- logger.Warn("Exception when executing IRuntimePolicy of type '{0}'. RuntimePolicy is now set to 'Off'.", exception, policy.GetType());
- }
-
- // Only use the lowest policy allowed for the request
- if (policyResult < maximumAllowedPolicy)
- {
- maximumAllowedPolicy = policyResult;
- }
-
- // If the policy indicates Glimpse is Off, then we stop processing any other runtime policy
- if (maximumAllowedPolicy == RuntimePolicy.Off)
- {
- break;
- }
}
- return maximumAllowedPolicy;
- }
-
- private RuntimePolicy DetermineAndStoreAccumulatedRuntimePolicy(RuntimeEvent runtimeEvent)
- {
- var frameworkProvider = Configuration.FrameworkProvider;
- var requestStore = frameworkProvider.HttpRequestStore;
-
- // First determine the maximum allowed policy to start from. This is or the current stored runtime policy for this
- // request, or if none can be found, the default runtime policy set in the configuration
- var maximumAllowedPolicy = requestStore.Contains(Constants.RuntimePolicyKey)
- ? requestStore.Get(Constants.RuntimePolicyKey)
- : Configuration.DefaultRuntimePolicy;
-
- maximumAllowedPolicy = DetermineRuntimePolicy(runtimeEvent, maximumAllowedPolicy);
-
- // store result for request
- requestStore.Set(Constants.RuntimePolicyKey, maximumAllowedPolicy);
- return maximumAllowedPolicy;
- }
-
- private string GenerateScriptTags(Guid requestId)
- {
- var requestStore = Configuration.FrameworkProvider.HttpRequestStore;
- var runtimePolicy = requestStore.Get(Constants.RuntimePolicyKey);
- var hasRendered = false;
-
- if (requestStore.Contains(Constants.ScriptsHaveRenderedKey))
- {
- hasRendered = requestStore.Get(Constants.ScriptsHaveRenderedKey);
- }
-
- if (hasRendered)
- {
- return string.Empty;
- }
-
- var encoder = Configuration.HtmlEncoder;
- var resourceEndpoint = Configuration.ResourceEndpoint;
- var clientScripts = Configuration.ClientScripts;
- var logger = Configuration.Logger;
- var resources = Configuration.Resources;
-
- var stringBuilder = new StringBuilder();
-
- foreach (var clientScript in clientScripts.OrderBy(cs => cs.Order))
- {
- var dynamicScript = clientScript as IDynamicClientScript;
- if (dynamicScript != null)
- {
- try
- {
- var requestTokenValues = new Dictionary
- {
- { ResourceParameter.RequestId.Name, requestId.ToString() },
- { ResourceParameter.VersionNumber.Name, Version },
- { ResourceParameter.Hash.Name, Configuration.Hash }
- };
-
- var resourceName = dynamicScript.GetResourceName();
- var resource = resources.FirstOrDefault(r => r.Name.Equals(resourceName, StringComparison.InvariantCultureIgnoreCase));
-
- if (resource == null)
- {
- logger.Warn(Resources.RenderClientScriptMissingResourceWarning, clientScript.GetType(), resourceName);
- continue;
- }
-
- var uriTemplate = resourceEndpoint.GenerateUriTemplate(resource, Configuration.EndpointBaseUri, logger);
-
- var resourceParameterProvider = dynamicScript as IParameterValueProvider;
-
- if (resourceParameterProvider != null)
- {
- resourceParameterProvider.OverrideParameterValues(requestTokenValues);
- }
-
- var template = SetParameters(new UriTemplate(uriTemplate), requestTokenValues);
- var uri = encoder.HtmlAttributeEncode(template.Resolve());
-
- if (!string.IsNullOrEmpty(uri))
- {
- stringBuilder.AppendFormat(@"", uri);
- }
-
- continue;
- }
- catch (Exception exception)
- {
- logger.Error(Core.Resources.GenerateScriptTagsDynamicException, exception, dynamicScript.GetType());
- }
- }
-
- var staticScript = clientScript as IStaticClientScript;
- if (staticScript != null)
- {
- try
- {
- var uri = encoder.HtmlAttributeEncode(staticScript.GetUri(Version));
-
- if (!string.IsNullOrEmpty(uri))
- {
- stringBuilder.AppendFormat(@"", uri);
- }
-
- continue;
- }
- catch (Exception exception)
- {
- logger.Error(Core.Resources.GenerateScriptTagsStaticException, exception, staticScript.GetType());
- }
- }
-
- logger.Warn(Core.Resources.RenderClientScriptImproperImplementationWarning, clientScript.GetType());
- }
-
- requestStore.Set(Constants.ScriptsHaveRenderedKey, true);
- return stringBuilder.ToString();
- }
-
- ///
- /// The message used to to track the beginning and end of Http requests.
- ///
- protected class RuntimeMessage : ITimelineMessage, ISourceMessage
- {
- ///
- /// Gets the id of the request.
- ///
- ///
- /// The id.
- ///
- public Guid Id { get; private set; }
-
- ///
- /// Gets or sets the name of the event.
- ///
- ///
- /// The name of the event.
- ///
- public string EventName { get; set; }
-
- ///
- /// Gets or sets the event category.
- ///
- ///
- /// The event category.
- ///
- public TimelineCategoryItem EventCategory { get; set; }
-
- ///
- /// Gets or sets the event sub text.
- ///
- ///
- /// The event sub text.
- ///
- public string EventSubText { get; set; }
-
- ///
- /// Gets or sets the type of the executed.
- ///
- ///
- /// The type of the executed.
- ///
- public Type ExecutedType { get; set; }
-
- ///
- /// Gets or sets the executed method.
- ///
- ///
- /// The executed method.
- ///
- public MethodInfo ExecutedMethod { get; set; }
-
- ///
- /// Gets or sets the offset.
- ///
- ///
- /// The offset.
- ///
- public TimeSpan Offset { get; set; }
-
- ///
- /// Gets or sets the duration.
- ///
- ///
- /// The duration.
- ///
- public TimeSpan Duration { get; set; }
-
- ///
- /// Gets or sets the start time.
- ///
- ///
- /// The start time.
- ///
- public DateTime StartTime { get; set; }
+ GlimpseRuntime.Instance = null;
}
}
}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/GlimpseRuntimeInitializer.cs b/source/Glimpse.Core/Framework/GlimpseRuntimeInitializer.cs
new file mode 100644
index 000000000..c21d829d1
--- /dev/null
+++ b/source/Glimpse.Core/Framework/GlimpseRuntimeInitializer.cs
@@ -0,0 +1,138 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Glimpse.Core.Configuration;
+using Glimpse.Core.Extensibility;
+
+namespace Glimpse.Core.Framework
+{
+ public partial class GlimpseRuntime
+ {
+ private static readonly object initializationLock = new object();
+
+ ///
+ /// Initializer used by the to initialize the Glimpse runtime
+ ///
+ public class GlimpseRuntimeInitializer
+ {
+ private IList InitializationMessages { get; set; }
+
+ ///
+ /// Initializes a new instance of the
+ ///
+ internal GlimpseRuntimeInitializer()
+ {
+ InitializationMessages = new List();
+ }
+
+ ///
+ /// Allows the Glimpse runtime host to add additional initialization messages that will be written to the
+ /// Glimpse log once the Glimpse logger is available.
+ ///
+ /// The of the message
+ /// The message
+ /// A possible exception related to the message
+ public void AddInitializationMessage(LoggingLevel level, string message, Exception exception = null)
+ {
+ InitializationMessages.Add(new InitializationMessage
+ {
+ Level = level,
+ Message = message,
+ Exception = exception
+ });
+ }
+
+ ///
+ /// Initializes the Glimpse runtime by finalizing the and creating a new
+ /// that will be set as the
+ ///
+ /// The configuration used to initialize the Glimpse runtime
+ public void Initialize(IConfiguration configuration)
+ {
+ Guard.ArgumentNotNull("configuration", configuration);
+
+ lock (initializationLock)
+ {
+ // we always take a lock as concurrent initialization calls should not happen, but if they do, they'll have to wait on each other
+ if (!IsAvailable)
+ {
+ // Run user customizations to configuration before storing and then override
+ // (some) changes made by the user to make sure .config file driven settings win
+ var userUpdatedConfig = GlimpseConfiguration.Override(configuration);
+ userUpdatedConfig.ApplyOverrides();
+
+ if (configuration.DefaultRuntimePolicy == RuntimePolicy.Off)
+ {
+ return;
+ }
+
+ // now that the Logger is available, we can log the registered initialization messages
+ foreach (var initializationMessage in InitializationMessages.Where(initializationMessage => !initializationMessage.WrittenToLog))
+ {
+ switch (initializationMessage.Level)
+ {
+ case LoggingLevel.Trace:
+ configuration.Logger.Trace(initializationMessage.Message, initializationMessage.Exception);
+ break;
+ case LoggingLevel.Debug:
+ configuration.Logger.Debug(initializationMessage.Message, initializationMessage.Exception);
+ break;
+ case LoggingLevel.Info:
+ configuration.Logger.Info(initializationMessage.Message, initializationMessage.Exception);
+ break;
+ case LoggingLevel.Warn:
+ configuration.Logger.Warn(initializationMessage.Message, initializationMessage.Exception);
+ break;
+ case LoggingLevel.Error:
+ configuration.Logger.Error(initializationMessage.Message, initializationMessage.Exception);
+ break;
+ case LoggingLevel.Fatal:
+ configuration.Logger.Fatal(initializationMessage.Message, initializationMessage.Exception);
+ break;
+ }
+
+ initializationMessage.WrittenToLog = true;
+ }
+
+ var readonlyConfiguration = new ReadonlyConfigurationAdapter(userUpdatedConfig);
+
+ var activeGlimpseRequestContexts = new ActiveGlimpseRequestContexts(readonlyConfiguration.CurrentGlimpseRequestIdTracker);
+
+ var displayProvider = new DisplayProvider(readonlyConfiguration, activeGlimpseRequestContexts);
+ displayProvider.Setup();
+
+ var tabProvider = new TabProvider(readonlyConfiguration, activeGlimpseRequestContexts);
+ tabProvider.Setup();
+
+ var inspectorProvider = new InspectorProvider(readonlyConfiguration, activeGlimpseRequestContexts);
+ inspectorProvider.Setup();
+
+ var metadataProvider = new MetadataProvider(readonlyConfiguration);
+ metadataProvider.SaveMetadata();
+
+ var runtimePolicyDeterminator = new RuntimePolicyDeterminator(readonlyConfiguration);
+
+ GlimpseRuntime.Instance = new GlimpseRuntime(
+ readonlyConfiguration,
+ activeGlimpseRequestContexts,
+ runtimePolicyDeterminator,
+ metadataProvider,
+ tabProvider,
+ displayProvider);
+ }
+ }
+ }
+
+ private class InitializationMessage
+ {
+ public LoggingLevel Level { get; set; }
+
+ public string Message { get; set; }
+
+ public Exception Exception { get; set; }
+
+ public bool WrittenToLog { get; set; }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/GlimpseRuntimeNotAvailableException.cs b/source/Glimpse.Core/Framework/GlimpseRuntimeNotAvailableException.cs
new file mode 100644
index 000000000..0ae4e2913
--- /dev/null
+++ b/source/Glimpse.Core/Framework/GlimpseRuntimeNotAvailableException.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Runtime.Serialization;
+
+namespace Glimpse.Core.Framework
+{
+ ///
+ /// Exception thrown when the GlimpseRuntime instance is being accessed prematurely.
+ ///
+ public class GlimpseRuntimeNotAvailableException : Exception
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public GlimpseRuntimeNotAvailableException()
+ : this("The GlimpseRuntime is not (yet) available, make sure to check the GlimpseRuntime.IsAvailable property before accessing the GlimpseRuntime.Instance . The GlimpseRuntime.Instance will be made available once the Glimpse runtime is initialized by calling GlimpseRuntime.Initializer.Initialize(...)")
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The message.
+ public GlimpseRuntimeNotAvailableException(string message)
+ : base(message)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The message.
+ /// The inner exception.
+ public GlimpseRuntimeNotAvailableException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The info.
+ /// The context.
+ public GlimpseRuntimeNotAvailableException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/IConfiguration.cs b/source/Glimpse.Core/Framework/IConfiguration.cs
new file mode 100644
index 000000000..cdd8607fd
--- /dev/null
+++ b/source/Glimpse.Core/Framework/IConfiguration.cs
@@ -0,0 +1,143 @@
+using System;
+using System.Collections.Generic;
+using Glimpse.Core.Extensibility;
+
+namespace Glimpse.Core.Framework
+{
+ ///
+ /// Defines properties to provide access to system providers, stores, collections,
+ /// factories, etc.
+ ///
+ public interface IConfiguration
+ {
+ ///
+ /// Gets the client scripts.
+ ///
+ /// The client scripts.
+ ICollection ClientScripts { get; set; }
+
+ ///
+ /// Gets the HTML encoder.
+ ///
+ /// The HTML encoder.
+ IHtmlEncoder HtmlEncoder { get; set; }
+
+ ///
+ /// Gets the logger.
+ ///
+ /// The logger.
+ ILogger Logger { get; set; }
+
+ ///
+ /// Gets the persistence store.
+ ///
+ /// The persistence store.
+ IPersistenceStore PersistenceStore { get; set; }
+
+ ///
+ /// Gets the inspectors.
+ ///
+ /// The inspectors.
+ ICollection Inspectors { get; set; }
+
+ ///
+ /// Gets the resource endpoint.
+ ///
+ /// The resource endpoint.
+ IResourceEndpointConfiguration ResourceEndpoint { get; set; }
+
+ ///
+ /// Gets the resources.
+ ///
+ /// The resources.
+ ICollection Resources { get; set; }
+
+ ///
+ /// Gets the serializer.
+ ///
+ /// The serializer.
+ ISerializer Serializer { get; set; }
+
+ ///
+ /// Gets the tabs.
+ ///
+ /// The tabs.
+ ICollection Tabs { get; set; }
+
+ ///
+ /// Gets the metadata extensions.
+ ///
+ /// The metadata extensions.
+ ICollection Metadata { get; set; }
+
+ ///
+ /// Gets the tab metadata extensions.
+ ///
+ /// The tab metadata extensions.
+ ICollection TabMetadata { get; set; }
+
+ ///
+ /// Gets the tab instance metadata extensions.
+ ///
+ /// The tab metadata extensions.
+ ICollection InstanceMetadata { get; set; }
+
+ [Obsolete]
+ ICollection Displays { get; set; }
+
+ ///
+ /// Gets the runtime policies.
+ ///
+ /// The runtime policies.
+ ICollection RuntimePolicies { get; set; }
+
+ ///
+ /// Gets the default resource.
+ ///
+ /// The default resource.
+ IResource DefaultResource { get; set; }
+
+ ///
+ /// Gets the default runtime policy.
+ ///
+ /// The default runtime policy.
+ RuntimePolicy DefaultRuntimePolicy { get; set; }
+
+ ///
+ /// Gets the proxy factory.
+ ///
+ /// The proxy factory.
+ IProxyFactory ProxyFactory { get; set; }
+
+ ///
+ /// Gets the message broker.
+ ///
+ /// The message broker.
+ IMessageBroker MessageBroker { get; set; }
+
+ ///
+ /// Gets the endpoint base URI.
+ ///
+ /// The endpoint base URI.
+ string EndpointBaseUri { get; set; }
+
+ ///
+ /// Gets the configuration hash.
+ ///
+ /// The hash.
+ string Hash { get; set; }
+
+ ///
+ /// Gets the version of Glimpse core.
+ ///
+ /// The version.
+ string Version { get; set; }
+
+ ///
+ /// Gets the configured
+ ///
+ ICurrentGlimpseRequestIdTracker CurrentGlimpseRequestIdTracker { get; }
+
+ void ApplyOverrides();
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/ICurrentGlimpseRequestIdTracker.cs b/source/Glimpse.Core/Framework/ICurrentGlimpseRequestIdTracker.cs
new file mode 100644
index 000000000..51b197f93
--- /dev/null
+++ b/source/Glimpse.Core/Framework/ICurrentGlimpseRequestIdTracker.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace Glimpse.Core.Framework
+{
+ ///
+ /// Represents a store that keeps track of the Glimpse request id while a request is being processed.
+ /// The store needs to make sure the request id is still available when threads are being switched
+ /// while the request is being handled.
+ ///
+ public interface ICurrentGlimpseRequestIdTracker
+ {
+ ///
+ /// Tracks the Glimpse request id while the request is being handled
+ ///
+ /// The Glimpse request id assigned to the request that is being handled.
+ void StartTracking(Guid glimpseRequestId);
+
+ ///
+ /// Tries to get the tracked Glimpse request id for the request that is currently being handled
+ ///
+ /// The tracked Glimpse request id, or the default in case it was not found
+ /// Boolean indicating whether a Glimpse request id was found or not.
+ bool TryGet(out Guid glimpseRequestId);
+
+ ///
+ /// Stops tracking the Glimpse request id of the request that finished being handled.
+ ///
+ void StopTracking();
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/IGlimpseRequestContext.cs b/source/Glimpse.Core/Framework/IGlimpseRequestContext.cs
new file mode 100644
index 000000000..32bd43f4a
--- /dev/null
+++ b/source/Glimpse.Core/Framework/IGlimpseRequestContext.cs
@@ -0,0 +1,57 @@
+using System;
+using Glimpse.Core.Extensibility;
+
+namespace Glimpse.Core.Framework
+{
+ ///
+ /// Represents the context of a specific request, which is used as an access point to the request's handle
+ ///
+ public interface IGlimpseRequestContext
+ {
+ ///
+ /// Gets the Glimpse Id assigned to the referenced request
+ ///
+ Guid GlimpseRequestId { get; }
+
+ ///
+ /// Gets the for the referenced request
+ ///
+ IRequestResponseAdapter RequestResponseAdapter { get; }
+
+ ///
+ /// Gets the for the referenced request
+ ///
+ IDataStore RequestStore { get; }
+
+ ///
+ /// Gets or sets the active for the referenced request
+ ///
+ RuntimePolicy CurrentRuntimePolicy { get; set; }
+
+ ///
+ /// Gets the for the referenced request
+ ///
+ RequestHandlingMode RequestHandlingMode { get; }
+
+ ///
+ /// Gets the for the referenced request
+ ///
+ IScriptTagsProvider ScriptTagsProvider { get; }
+
+ ///
+ /// Starts timing the execution of the referenced request
+ ///
+ void StartTiming();
+
+ ///
+ /// Gets the for the referenced request
+ ///
+ IExecutionTimer CurrentExecutionTimer { get; }
+
+ ///
+ /// Stops timing the execution of the referenced request
+ ///
+ /// The elapsed time since the start of the timing
+ TimeSpan StopTiming();
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/IGlimpseRuntime.cs b/source/Glimpse.Core/Framework/IGlimpseRuntime.cs
index 7e3b68368..a392b2503 100644
--- a/source/Glimpse.Core/Framework/IGlimpseRuntime.cs
+++ b/source/Glimpse.Core/Framework/IGlimpseRuntime.cs
@@ -5,56 +5,30 @@ namespace Glimpse.Core.Framework
///
/// Defines methods to implement the Glimpse runtime
///
- public interface IGlimpseRuntime
+ public interface IGlimpseRuntime : IDisposable
{
///
- /// Gets a value indicating whether this instance is initialized.
+ /// Calling this method will allow Glimpse to decide to hook into the given request or not
///
- /// true if this instance is initialized; otherwise, false.
- bool IsInitialized { get; }
+ /// The
+ /// A for the given request which also indicates how Glimpse is actually handling that request.
+ GlimpseRequestContextHandle BeginRequest(IRequestResponseAdapter requestResponseAdapter);
///
- /// Begins the request.
+ /// Calling this method indicates Glimpse to finalize processing the request referenced by the given "/>
///
- ///
- /// Called when ever the implementing framework registers a request start. Specifically,
- /// with the ASP.NET provider, this is wired to the BeginRequest method.
- ///
- void BeginRequest();
-
- ///
- /// Ends the request.
- ///
- ///
- /// Called when ever the implementing framework registers a request end. Specifically,
- /// with the ASP.NET provider, this is wired to the PostReleaseRequestState method.
- ///
- void EndRequest();
-
- ///
- /// Executes the default resource.
- ///
- ///
- /// Specifically, with the ASP.NET provider, this is wired to the
- /// ProcessRequest method.
- ///
- ///
- ///
- void ExecuteDefaultResource();
+ /// The Glimpse handle of the corresponding request
+ void EndRequest(GlimpseRequestContextHandle glimpseRequestContextHandle);
///
- /// Executes the resource.
+ /// Executes the given resource.
///
+ /// The Glimpse handle of the corresponding request
/// Name of the resource.
/// The parameters.
- ///
- /// Specifically, with the ASP.NET provider, this is wired to the
- /// ProcessRequest method.
- ///
- ///
- ///
- void ExecuteResource(string resourceName, ResourceParameters parameters);
+ void ExecuteResource(GlimpseRequestContextHandle glimpseRequestContextHandle, string resourceName, ResourceParameters parameters);
+#warning CGI: These methods should be replaced with a CustomEvent method, passing in the custom event name as a string, so additional events can be added
///
/// Begins the session access.
///
@@ -63,7 +37,7 @@ public interface IGlimpseRuntime
/// executed off this methods should have access to the session state store. Specifically,
/// with the ASP.NET provider, this is wired to the PostAcquireRequestState method.
///
- void BeginSessionAccess();
+ void BeginSessionAccess(GlimpseRequestContextHandle glimpseRequestContextHandle);
///
/// Ends the session access.
@@ -73,18 +47,27 @@ public interface IGlimpseRuntime
/// executed off this methods should still have access to the session state store. Specifically,
/// with the ASP.NET provider, this is wired to the PostRequestHandlerExecute method.
///
- void EndSessionAccess();
+ void EndSessionAccess(GlimpseRequestContextHandle glimpseRequestContextHandle);
///
- /// Initializes this instance.
+ /// Gets or sets the configuration.
///
- /// true if system initialized successfully, false otherwise
- ///
- /// Typically used to wire up framework events to the corresponding runtime methods. Depending
- /// on framework implementation, this could be called multiple times per "application pool"
- /// recycle. Specifically, with the ASP.NET provider, this is wired to/implemented by the
- /// Init method.
- ///
- bool Initialize();
+ ///
+ /// The configuration.
+ ///
+ IReadonlyConfiguration Configuration { get; }
+
+ ///
+ /// Returns the corresponding for the given
+ ///
+ /// The Glimpse request Id
+ /// The corresponding
+ /// Boolean indicating whether the corresponding was found.
+ bool TryGetRequestContext(Guid glimpseRequestId, out IGlimpseRequestContext glimpseRequestContext);
+
+ ///
+ /// Returns the corresponding to the current request.
+ ///
+ IGlimpseRequestContext CurrentRequestContext { get; }
}
-}
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/IPersistenceStore.cs b/source/Glimpse.Core/Framework/IPersistenceStore.cs
index 7a9bf6ca6..9e84d425c 100644
--- a/source/Glimpse.Core/Framework/IPersistenceStore.cs
+++ b/source/Glimpse.Core/Framework/IPersistenceStore.cs
@@ -1,3 +1,5 @@
+using System.Collections.Generic;
+
namespace Glimpse.Core.Framework
{
///
@@ -16,6 +18,6 @@ public interface IPersistenceStore : IReadOnlyPersistenceStore
/// Saves the specified system metadata.
///
/// The metadata.
- void Save(GlimpseMetadata metadata);
+ void SaveMetadata(IDictionary metadata);
}
}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/IReadOnlyPersistenceStore.cs b/source/Glimpse.Core/Framework/IReadOnlyPersistenceStore.cs
index 74dd36ed0..c55a081fb 100644
--- a/source/Glimpse.Core/Framework/IReadOnlyPersistenceStore.cs
+++ b/source/Glimpse.Core/Framework/IReadOnlyPersistenceStore.cs
@@ -42,6 +42,6 @@ public interface IReadOnlyPersistenceStore
/// Gets the metadata.
///
/// Metadata that is currently applied.
- GlimpseMetadata GetMetadata();
+ IDictionary GetMetadata();
}
}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/IGlimpseConfiguration.cs b/source/Glimpse.Core/Framework/IReadonlyConfiguration.cs
similarity index 75%
rename from source/Glimpse.Core/Framework/IGlimpseConfiguration.cs
rename to source/Glimpse.Core/Framework/IReadonlyConfiguration.cs
index b0c1bb3e3..d33ca78d9 100644
--- a/source/Glimpse.Core/Framework/IGlimpseConfiguration.cs
+++ b/source/Glimpse.Core/Framework/IReadonlyConfiguration.cs
@@ -4,23 +4,19 @@
namespace Glimpse.Core.Framework
{
- ///
- /// Defines properties to provide access to system providers, stores, collections,
- /// factories, etc.
- ///
- public interface IGlimpseConfiguration
+ public interface IReadonlyConfiguration
{
///
- /// Gets the client scripts.
+ /// Gets the current requestId tracker.
///
- /// The client scripts.
- ICollection ClientScripts { get; }
+ /// The current requestId tracker.
+ ICurrentGlimpseRequestIdTracker CurrentGlimpseRequestIdTracker { get; }
///
- /// Gets the framework provider.
+ /// Gets the client scripts.
///
- /// The framework provider.
- IFrameworkProvider FrameworkProvider { get; }
+ /// The client scripts.
+ ICollection ClientScripts { get; }
///
/// Gets the HTML encoder.
@@ -50,7 +46,7 @@ public interface IGlimpseConfiguration
/// Gets the resource endpoint.
///
/// The resource endpoint.
- ResourceEndpointConfiguration ResourceEndpoint { get; }
+ IResourceEndpointConfiguration ResourceEndpoint { get; }
///
/// Gets the resources.
@@ -70,6 +66,24 @@ public interface IGlimpseConfiguration
/// The tabs.
ICollection Tabs { get; }
+ ///
+ /// Gets the metadata extensions.
+ ///
+ /// The metadata extensions.
+ ICollection Metadata { get; }
+
+ ///
+ /// Gets the tab metadata extensions.
+ ///
+ /// The tab metadata extensions.
+ ICollection TabMetadata { get; }
+
+ ///
+ /// Gets the instance metadata extensions.
+ ///
+ /// The tab metadata extensions.
+ ICollection InstanceMetadata { get; }
+
[Obsolete]
ICollection Displays { get; }
@@ -116,15 +130,9 @@ public interface IGlimpseConfiguration
string Hash { get; }
///
- /// Gets or sets the runtime policy strategy.
- ///
- /// The runtime policy strategy.
- Func RuntimePolicyStrategy { get; set; }
-
- ///
- /// Gets or sets the timer strategy.
+ /// Gets the version of Glimpse core.
///
- /// The timer strategy.
- Func TimerStrategy { get; set; }
+ /// The version.
+ string Version { get; }
}
}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/IRequestMetadata.cs b/source/Glimpse.Core/Framework/IRequestMetadata.cs
index 8e42ed9a9..6eb27534d 100644
--- a/source/Glimpse.Core/Framework/IRequestMetadata.cs
+++ b/source/Glimpse.Core/Framework/IRequestMetadata.cs
@@ -1,3 +1,5 @@
+using System;
+
namespace Glimpse.Core.Framework
{
///
@@ -9,7 +11,7 @@ public interface IRequestMetadata
/// Gets the request URI.
///
/// The request URI.
- string RequestUri { get; }
+ Uri RequestUri { get; }
///
/// Gets the request HTTP method.
diff --git a/source/Glimpse.Core/Framework/IFrameworkProvider.cs b/source/Glimpse.Core/Framework/IRequestResponseAdapter.cs
similarity index 64%
rename from source/Glimpse.Core/Framework/IFrameworkProvider.cs
rename to source/Glimpse.Core/Framework/IRequestResponseAdapter.cs
index 132ee484b..ebc9690cb 100644
--- a/source/Glimpse.Core/Framework/IFrameworkProvider.cs
+++ b/source/Glimpse.Core/Framework/IRequestResponseAdapter.cs
@@ -1,42 +1,20 @@
-using Glimpse.Core.Extensibility;
+using System.IO;
+using System.Text;
+using Glimpse.Core.Extensibility;
namespace Glimpse.Core.Framework
{
///
/// Defines methods to required to implement a Glimpse framework provider.
- /// Framework providers allow Glimpse to work generically against any .NET based web development framework.
+ /// Request/Response adapters allow Glimpse to work generically against any .NET based web development framework.
///
///
- /// Required by any different Framework Provider - i.e. ASP.NET, Self Hosted WebAPI,
+ /// Required by any different framework - i.e. ASP.NET, Self Hosted WebAPI,
/// NancyFX, etc. See Glimpse.AspNet.AspNetFrameworkProvider
/// as reference implementation.
///
- public interface IFrameworkProvider
+ public interface IRequestResponseAdapter
{
- ///
- /// Gets the Http request store.
- ///
- /// The Http request store.
- ///
- /// A request store is a place for Glimpse to store data that lives and dies with an Http request.
- ///
- ///
- /// In ASP.NET, HttpContext.Items is a request store.
- ///
- IDataStore HttpRequestStore { get; }
-
- ///
- /// Gets the Http server store.
- ///
- /// The Http server store.
- ///
- /// A server store is a place for Glimpse to store data a persists across Http requests.
- ///
- ///
- /// In ASP.NET, HttpContext.Application is a server store.
- ///
- IDataStore HttpServerStore { get; }
-
///
/// Gets the runtime context.
///
@@ -49,6 +27,8 @@ public interface IFrameworkProvider
///
object RuntimeContext { get; }
+ Stream OutputStream { get; set; }
+
///
/// Gets the request metadata.
///
@@ -61,6 +41,8 @@ public interface IFrameworkProvider
///
IRequestMetadata RequestMetadata { get; }
+ Encoding ResponseEncoding { get; }
+
///
/// Sets the Http response header.
///
@@ -81,15 +63,6 @@ public interface IFrameworkProvider
/// The value.
void SetCookie(string name, string value);
- ///
- /// Injects the Http response body.
- ///
- /// The HTML snippet.
- ///
- /// Inserts the given html snippet into the html document just before the end </body> tag.
- ///
- void InjectHttpResponseBody(string htmlSnippet);
-
///
/// Writes the Http response.
///
diff --git a/source/Glimpse.Core/Framework/IResourceEndpointConfiguration.cs b/source/Glimpse.Core/Framework/IResourceEndpointConfiguration.cs
new file mode 100644
index 000000000..a3379b6a7
--- /dev/null
+++ b/source/Glimpse.Core/Framework/IResourceEndpointConfiguration.cs
@@ -0,0 +1,29 @@
+using System;
+using Glimpse.Core.Extensibility;
+
+namespace Glimpse.Core.Framework
+{
+ ///
+ /// Represents a Glimpse resource endpoint configuration
+ ///
+ public interface IResourceEndpointConfiguration
+ {
+ ///
+ /// Generates the URI template.
+ ///
+ /// The resource.
+ /// The base URI.
+ /// The logger.
+ /// A Uri template a client can expand to invoke a resource.
+ /// Throws and exception if or is null.
+ string GenerateUriTemplate(IResource resource, string baseUri, ILogger logger);
+
+ ///
+ /// Checks whether the given is a request for a Glimpse or not
+ ///
+ /// The request URI to check
+ /// The endpoint base URI to check against
+ /// Boolean indicating whether a Glimpse request is made or not
+ bool IsResourceRequest(Uri requestUri, string endpointBaseUri);
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/IScriptTagsGenerator.cs b/source/Glimpse.Core/Framework/IScriptTagsGenerator.cs
new file mode 100644
index 000000000..6c80a5799
--- /dev/null
+++ b/source/Glimpse.Core/Framework/IScriptTagsGenerator.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace Glimpse.Core.Framework
+{
+ public interface IScriptTagsGenerator
+ {
+ ///
+ /// Generates Glimpse script tags for the given Glimpse request id
+ ///
+ /// The Glimpse request Id of the request for which script tags must be generated
+ /// The generated script tags
+ string Generate(Guid glimpseRequestId);
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/IScriptTagsProvider.cs b/source/Glimpse.Core/Framework/IScriptTagsProvider.cs
new file mode 100644
index 000000000..0a3ed3376
--- /dev/null
+++ b/source/Glimpse.Core/Framework/IScriptTagsProvider.cs
@@ -0,0 +1,9 @@
+namespace Glimpse.Core.Framework
+{
+ public interface IScriptTagsProvider
+ {
+ bool ScriptTagsAllowedToBeProvided { get; }
+ bool ScriptTagsAlreadyProvided { get; }
+ string GetScriptTags();
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/ApplicationPersistenceStore.cs b/source/Glimpse.Core/Framework/InMemoryPersistenceStore.cs
similarity index 91%
rename from source/Glimpse.Core/Framework/ApplicationPersistenceStore.cs
rename to source/Glimpse.Core/Framework/InMemoryPersistenceStore.cs
index 47266d22f..ae0033428 100644
--- a/source/Glimpse.Core/Framework/ApplicationPersistenceStore.cs
+++ b/source/Glimpse.Core/Framework/InMemoryPersistenceStore.cs
@@ -12,7 +12,7 @@ namespace Glimpse.Core.Framework
///
/// An example of an application store is HttpContext.Current.Application in ASP.NET.
///
- public class ApplicationPersistenceStore : IPersistenceStore
+ public class InMemoryPersistenceStore : IPersistenceStore
{
private const string PersistenceStoreKey = "__GlimpsePersistenceKey";
@@ -21,10 +21,10 @@ public class ApplicationPersistenceStore : IPersistenceStore
private readonly object queueLock = new object();
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The data store.
- public ApplicationPersistenceStore(IDataStore dataStore)
+ public InMemoryPersistenceStore(IDataStore dataStore)
{
DataStore = dataStore;
@@ -42,7 +42,7 @@ public ApplicationPersistenceStore(IDataStore dataStore)
private IDataStore DataStore { get; set; }
- private GlimpseMetadata Metadata { get; set; }
+ private IDictionary Metadata { get; set; }
///
/// Saves the specified request.
@@ -65,7 +65,7 @@ public void Save(GlimpseRequest request)
/// Saves the specified system metadata.
///
/// The metadata.
- public void Save(GlimpseMetadata metadata)
+ public void SaveMetadata(IDictionary metadata)
{
Metadata = metadata;
}
@@ -147,7 +147,7 @@ public IEnumerable GetTop(int count)
///
/// Metadata that is currently applied.
///
- public GlimpseMetadata GetMetadata()
+ public IDictionary GetMetadata()
{
return Metadata;
}
diff --git a/source/Glimpse.Core/Framework/InspectorProvider.cs b/source/Glimpse.Core/Framework/InspectorProvider.cs
new file mode 100644
index 000000000..d39ac3097
--- /dev/null
+++ b/source/Glimpse.Core/Framework/InspectorProvider.cs
@@ -0,0 +1,33 @@
+using System;
+using Glimpse.Core.Extensibility;
+
+namespace Glimpse.Core.Framework
+{
+ internal class InspectorProvider : BaseProvider
+ {
+ public InspectorProvider(IReadonlyConfiguration configuration, ActiveGlimpseRequestContexts activeGlimpseRequestContexts)
+ : base(configuration, activeGlimpseRequestContexts)
+ {
+ }
+
+ public void Setup()
+ {
+ var logger = Configuration.Logger;
+ var messageBroker = Configuration.MessageBroker;
+
+ var inspectorContext = new InspectorContext(logger, Configuration.ProxyFactory, messageBroker, () => ActiveGlimpseRequestContexts.Current.CurrentExecutionTimer, () => ActiveGlimpseRequestContexts.Current.CurrentRuntimePolicy);
+ foreach (var inspector in Configuration.Inspectors)
+ {
+ try
+ {
+ inspector.Setup(inspectorContext);
+ logger.Debug(Resources.GlimpseRuntimeInitializeSetupInspector, inspector.GetType());
+ }
+ catch (Exception exception)
+ {
+ logger.Error(Resources.InitializeInspectorError, exception, inspector.GetType());
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/KeyCreator.cs b/source/Glimpse.Core/Framework/KeyCreator.cs
new file mode 100644
index 000000000..5a6b56688
--- /dev/null
+++ b/source/Glimpse.Core/Framework/KeyCreator.cs
@@ -0,0 +1,26 @@
+using Glimpse.Core.Extensibility;
+
+namespace Glimpse.Core.Framework
+{
+ ///
+ /// Creates keys depending on the input given
+ ///
+ internal static class KeyCreator
+ {
+ ///
+ /// Creates a key based on the given
+ ///
+ /// The input to base a key on
+ /// The key
+ public static string Create(object obj)
+ {
+ Guard.ArgumentNotNull("obj", obj);
+
+ var keyProvider = obj as IKey;
+
+ string result = keyProvider != null ? keyProvider.Key : obj.GetType().FullName;
+
+ return result.Replace('.', '_').Replace(' ', '_').ToLower();
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/MetadataProvider.cs b/source/Glimpse.Core/Framework/MetadataProvider.cs
new file mode 100644
index 000000000..13b1cf443
--- /dev/null
+++ b/source/Glimpse.Core/Framework/MetadataProvider.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+
+namespace Glimpse.Core.Framework
+{
+ public class MetadataProvider
+ {
+ protected IReadonlyConfiguration Configuration { get; set; }
+
+ public MetadataProvider(IReadonlyConfiguration configuration)
+ {
+ Configuration = configuration;
+ }
+
+ public IDictionary GetMetadata()
+ {
+ var logger = Configuration.Logger;
+ var metadata = new Dictionary();
+
+ foreach (var extension in Configuration.Metadata)
+ {
+ try
+ {
+ var result = extension.GetMetadata(Configuration);
+ if (result != null)
+ {
+ metadata[extension.Key] = result;
+ }
+ }
+ catch (Exception exception)
+ {
+ logger.Error(Resources.ExecuteMetadataExtensionsError, exception, extension.GetType());
+ }
+ }
+
+ return metadata;
+ }
+
+ public void SaveMetadata()
+ {
+ Configuration.PersistenceStore.SaveMetadata(GetMetadata());
+ }
+
+ public IDictionary GetRequestMetadata(IGlimpseRequestContext requestContext)
+ {
+ var logger = Configuration.Logger;
+ var metadata = new Dictionary();
+
+ foreach (var extension in Configuration.InstanceMetadata)
+ {
+ try
+ {
+ var result = extension.GetInstanceMetadata(Configuration, requestContext);
+ if (result != null)
+ {
+ metadata[extension.Key] = result;
+ }
+ }
+ catch (Exception exception)
+ {
+ logger.Error(Resources.ExecuteInstanceMetadataExtensionsError, exception, extension.GetType());
+ }
+ }
+
+ return metadata;
+ }
+ }
+}
diff --git a/source/Glimpse.Core/Framework/ReadonlyConfigurationAdapter.cs b/source/Glimpse.Core/Framework/ReadonlyConfigurationAdapter.cs
new file mode 100644
index 000000000..d2ed05bd2
--- /dev/null
+++ b/source/Glimpse.Core/Framework/ReadonlyConfigurationAdapter.cs
@@ -0,0 +1,126 @@
+using System;
+using System.Collections.Generic;
+using Glimpse.Core.Extensibility;
+
+namespace Glimpse.Core.Framework
+{
+ public class ReadonlyConfigurationAdapter : IReadonlyConfiguration
+ {
+ private readonly IConfiguration configuration;
+
+ public ReadonlyConfigurationAdapter(IConfiguration configuration)
+ {
+ this.configuration = configuration;
+ }
+
+ public ICurrentGlimpseRequestIdTracker CurrentGlimpseRequestIdTracker
+ {
+ get { return configuration.CurrentGlimpseRequestIdTracker; }
+ }
+
+ public ICollection ClientScripts
+ {
+ get { return configuration.ClientScripts; }
+ }
+
+ public IHtmlEncoder HtmlEncoder
+ {
+ get { return configuration.HtmlEncoder; }
+ }
+
+ public ILogger Logger
+ {
+ get { return configuration.Logger; }
+ }
+
+ public IPersistenceStore PersistenceStore
+ {
+ get { return configuration.PersistenceStore; }
+ }
+
+ public ICollection Inspectors
+ {
+ get { return configuration.Inspectors; }
+ }
+
+ public IResourceEndpointConfiguration ResourceEndpoint
+ {
+ get { return configuration.ResourceEndpoint; }
+ }
+
+ public ICollection Resources
+ {
+ get { return configuration.Resources; }
+ }
+
+ public ISerializer Serializer
+ {
+ get { return configuration.Serializer; }
+ }
+
+ public ICollection Tabs
+ {
+ get { return configuration.Tabs; }
+ }
+
+ public ICollection Metadata
+ {
+ get { return configuration.Metadata; }
+ }
+
+ public ICollection TabMetadata
+ {
+ get { return configuration.TabMetadata; }
+ }
+
+ public ICollection InstanceMetadata
+ {
+ get { return configuration.InstanceMetadata; }
+ }
+
+ public ICollection Displays
+ {
+ get { return configuration.Displays; }
+ }
+
+ public ICollection RuntimePolicies
+ {
+ get { return configuration.RuntimePolicies; }
+ }
+
+ public IResource DefaultResource
+ {
+ get { return configuration.DefaultResource; }
+ }
+
+ public RuntimePolicy DefaultRuntimePolicy
+ {
+ get { return configuration.DefaultRuntimePolicy; }
+ }
+
+ public IProxyFactory ProxyFactory
+ {
+ get { return configuration.ProxyFactory; }
+ }
+
+ public IMessageBroker MessageBroker
+ {
+ get { return configuration.MessageBroker; }
+ }
+
+ public string EndpointBaseUri
+ {
+ get { return configuration.EndpointBaseUri; }
+ }
+
+ public string Hash
+ {
+ get { return configuration.Hash; }
+ }
+
+ public string Version
+ {
+ get { return configuration.Version; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/ResourceEndpointConfiguration.cs b/source/Glimpse.Core/Framework/ResourceEndpointConfiguration.cs
index 5fb9d656f..28c4f2b61 100644
--- a/source/Glimpse.Core/Framework/ResourceEndpointConfiguration.cs
+++ b/source/Glimpse.Core/Framework/ResourceEndpointConfiguration.cs
@@ -7,7 +7,7 @@ namespace Glimpse.Core.Framework
///
/// Defines methods to implement a resource endpoint configuration.
///
- public abstract class ResourceEndpointConfiguration
+ public abstract class ResourceEndpointConfiguration : IResourceEndpointConfiguration
{
///
/// Generates the URI template.
@@ -47,6 +47,17 @@ public string GenerateUriTemplate(IResource resource, string baseUri, ILogger lo
return string.Empty;
}
+ ///
+ /// Checks whether the given is a request for a Glimpse or not
+ ///
+ /// The request URI to check
+ /// The endpoint base URI to check against
+ /// Boolean indicating whether a Glimpse request is made or not
+ public virtual bool IsResourceRequest(Uri requestUri, string endpointBaseUri)
+ {
+ return requestUri.AbsolutePath.StartsWith(endpointBaseUri, StringComparison.InvariantCultureIgnoreCase);
+ }
+
///
/// Generates the URI template.
///
@@ -57,4 +68,4 @@ public string GenerateUriTemplate(IResource resource, string baseUri, ILogger lo
/// A Uri template a client can expand to invoke a resource.
protected abstract string GenerateUriTemplate(string resourceName, string baseUri, IEnumerable parameters, ILogger logger);
}
-}
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/RuntimePolicyDeterminator.cs b/source/Glimpse.Core/Framework/RuntimePolicyDeterminator.cs
new file mode 100644
index 000000000..eeedcdb02
--- /dev/null
+++ b/source/Glimpse.Core/Framework/RuntimePolicyDeterminator.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Linq;
+using Glimpse.Core.Extensibility;
+
+namespace Glimpse.Core.Framework
+{
+ internal class RuntimePolicyDeterminator
+ {
+ private IReadonlyConfiguration Configuration { get; set; }
+
+ ///
+ /// Initializes a new instance of the
+ ///
+ /// The that should be used
+ public RuntimePolicyDeterminator(IReadonlyConfiguration configuration)
+ {
+ Configuration = configuration;
+ }
+
+ ///
+ /// Determines the resulting based on the available
+ ///
+ /// The
+ /// The that start from, this is the highest possible that can be returned
+ /// The
+ /// The that is currently in effect
+ public RuntimePolicy DetermineRuntimePolicy(RuntimeEvent runtimeEvent, RuntimePolicy maximumAllowedPolicy, IRequestResponseAdapter requestResponseAdapter)
+ {
+ if (maximumAllowedPolicy == RuntimePolicy.Off)
+ {
+ return maximumAllowedPolicy;
+ }
+
+ var logger = Configuration.Logger;
+
+ var policies = Configuration.RuntimePolicies.Where(policy => policy.ExecuteOn.HasFlag(runtimeEvent));
+ var policyContext = new RuntimePolicyContext(requestResponseAdapter.RequestMetadata, logger, requestResponseAdapter.RuntimeContext);
+ foreach (var policy in policies)
+ {
+ var policyResult = RuntimePolicy.Off;
+ try
+ {
+ policyResult = policy.Execute(policyContext);
+
+ if (policyResult != RuntimePolicy.On)
+ {
+ logger.Debug("RuntimePolicy '{0}' has been returned by IRuntimePolicy of type '{1}' during RuntimeEvent '{2}'.", policyResult, policy.GetType(), runtimeEvent);
+ }
+ }
+ catch (Exception exception)
+ {
+ logger.Warn("Exception thrown when executing IRuntimePolicy of type '{0}'. The resulting RuntimePolicy will be set to 'Off'. {1}Exception: {2}", policy.GetType(), Environment.NewLine, exception);
+ }
+
+ // Only use the lowest policy allowed for the request
+ if (policyResult < maximumAllowedPolicy)
+ {
+ maximumAllowedPolicy = policyResult;
+ }
+
+ // If the policy indicates Glimpse is Off, then we stop processing any other runtime policy
+ if (maximumAllowedPolicy == RuntimePolicy.Off)
+ {
+ break;
+ }
+ }
+
+ return maximumAllowedPolicy;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/ScriptTagsGenerator.cs b/source/Glimpse.Core/Framework/ScriptTagsGenerator.cs
new file mode 100644
index 000000000..745f52109
--- /dev/null
+++ b/source/Glimpse.Core/Framework/ScriptTagsGenerator.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Glimpse.Core.Extensibility;
+using Tavis.UriTemplates;
+
+namespace Glimpse.Core.Framework
+{
+ ///
+ /// Generator of Glimpse script tags
+ ///
+ public class ScriptTagsGenerator : IScriptTagsGenerator
+ {
+ private IReadonlyConfiguration Configuration { get; set; }
+
+ ///
+ /// Initializes a new instance of the
+ ///
+ /// A
+ public ScriptTagsGenerator(IReadonlyConfiguration configuration)
+ {
+ Guard.ArgumentNotNull("configuration", configuration);
+ Configuration = configuration;
+ }
+
+ ///
+ /// Generates Glimpse script tags for the given Glimpse request id
+ ///
+ /// The Glimpse request Id of the request for which script tags must be generated
+ /// The generated script tags
+ public string Generate(Guid glimpseRequestId)
+ {
+ var encoder = Configuration.HtmlEncoder;
+ var resourceEndpoint = Configuration.ResourceEndpoint;
+ var clientScripts = Configuration.ClientScripts;
+ var logger = Configuration.Logger;
+ var resources = Configuration.Resources;
+
+ var stringBuilder = new StringBuilder();
+
+ foreach (var clientScript in clientScripts.OrderBy(cs => cs.Order))
+ {
+ var dynamicScript = clientScript as IDynamicClientScript;
+ if (dynamicScript != null)
+ {
+ try
+ {
+ var requestTokenValues = new Dictionary
+ {
+ { ResourceParameter.RequestId.Name, glimpseRequestId.ToString() },
+ { ResourceParameter.VersionNumber.Name, Configuration.Version },
+ { ResourceParameter.Hash.Name, Configuration.Hash }
+ };
+
+ var resourceName = dynamicScript.GetResourceName();
+ var resource = resources.FirstOrDefault(r => r.Name.Equals(resourceName, StringComparison.InvariantCultureIgnoreCase));
+
+ if (resource == null)
+ {
+ logger.Warn(Resources.RenderClientScriptMissingResourceWarning, clientScript.GetType(), resourceName);
+ continue;
+ }
+
+ var uriTemplate = resourceEndpoint.GenerateUriTemplate(resource, Configuration.EndpointBaseUri, logger);
+
+ var resourceParameterProvider = dynamicScript as IParameterValueProvider;
+
+ if (resourceParameterProvider != null)
+ {
+ resourceParameterProvider.OverrideParameterValues(requestTokenValues);
+ }
+
+ var template = SetParameters(new UriTemplate(uriTemplate), requestTokenValues);
+ var uri = encoder.HtmlAttributeEncode(template.Resolve());
+
+ if (!string.IsNullOrEmpty(uri))
+ {
+ stringBuilder.AppendFormat(@"", uri);
+ }
+
+ continue;
+ }
+ catch (Exception exception)
+ {
+ logger.Error(Core.Resources.GenerateScriptTagsDynamicException, exception, dynamicScript.GetType());
+ }
+ }
+
+ var staticScript = clientScript as IStaticClientScript;
+ if (staticScript != null)
+ {
+ try
+ {
+ var uri = encoder.HtmlAttributeEncode(staticScript.GetUri(Configuration.Version));
+
+ if (!string.IsNullOrEmpty(uri))
+ {
+ stringBuilder.AppendFormat(@"", uri);
+ }
+
+ continue;
+ }
+ catch (Exception exception)
+ {
+ logger.Error(Core.Resources.GenerateScriptTagsStaticException, exception, staticScript.GetType());
+ }
+ }
+
+ logger.Warn(Core.Resources.RenderClientScriptImproperImplementationWarning, clientScript.GetType());
+ }
+
+ return stringBuilder.ToString();
+ }
+
+ private static UriTemplate SetParameters(UriTemplate template, IEnumerable> nameValues)
+ {
+ if (nameValues == null)
+ {
+ return template;
+ }
+
+ foreach (var pair in nameValues)
+ {
+ template.SetParameter(pair.Key, pair.Value);
+ }
+
+ return template;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/ScriptTagsInjectionFailedEventArgs.cs b/source/Glimpse.Core/Framework/ScriptTagsInjectionFailedEventArgs.cs
new file mode 100644
index 000000000..fa4b5360e
--- /dev/null
+++ b/source/Glimpse.Core/Framework/ScriptTagsInjectionFailedEventArgs.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace Glimpse.Core.Framework
+{
+ public class ScriptTagsInjectionFailedEventArgs : EventArgs
+ {
+ public ScriptTagsInjectionFailedEventArgs(string failureMessage)
+ {
+ FailureMessage = failureMessage;
+ }
+
+ public string FailureMessage { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.Core/Framework/ScriptTagsInjectionOptions.cs b/source/Glimpse.Core/Framework/ScriptTagsInjectionOptions.cs
new file mode 100644
index 000000000..76c34b304
--- /dev/null
+++ b/source/Glimpse.Core/Framework/ScriptTagsInjectionOptions.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Text;
+
+namespace Glimpse.Core.Framework
+{
+ public class ScriptTagsInjectionOptions
+ {
+ private IScriptTagsProvider ScriptTagsProvider { get; set; }
+ private Func ContentEncodingProvider { get; set; }
+
+ private bool? _injectionRequired;
+ private Encoding _contentEncoding;
+
+ public event EventHandler InjectionFailed = delegate { };
+
+ public ScriptTagsInjectionOptions(
+ IScriptTagsProvider scriptTagsProvider,
+ Func contentEncodingProvider,
+ EventHandler onInjectionFailed = null)
+ {
+ Guard.ArgumentNotNull("scriptTagsProvider", scriptTagsProvider);
+ Guard.ArgumentNotNull("contentEncodingProvider", contentEncodingProvider);
+
+ ScriptTagsProvider = scriptTagsProvider;
+ ContentEncodingProvider = contentEncodingProvider;
+
+ if (onInjectionFailed != null)
+ {
+ InjectionFailed += onInjectionFailed;
+ }
+ }
+
+ public bool InjectionRequired
+ {
+ get { return (_injectionRequired ?? (_injectionRequired = ScriptTagsProvider.ScriptTagsAllowedToBeProvided)).Value; }
+ }
+
+ public string GetScriptTagsToInject()
+ {
+ return ScriptTagsProvider.GetScriptTags();
+ }
+
+ public Encoding ContentEncoding
+ {
+ get { return _contentEncoding ?? (_contentEncoding = ContentEncodingProvider()); }
+ }
+
+ public void NotifyInjectionFailure(string failureMessage)
+ {
+ InjectionFailed(this, new ScriptTagsInjectionFailedEventArgs(failureMessage));
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/Glimpse.AspNet/PreBodyTagFilter.cs b/source/Glimpse.Core/Framework/ScriptTagsInjectionStream.cs
similarity index 81%
rename from source/Glimpse.AspNet/PreBodyTagFilter.cs
rename to source/Glimpse.Core/Framework/ScriptTagsInjectionStream.cs
index 6fed41fa2..3fef2730f 100644
--- a/source/Glimpse.AspNet/PreBodyTagFilter.cs
+++ b/source/Glimpse.Core/Framework/ScriptTagsInjectionStream.cs
@@ -1,42 +1,33 @@
using System.IO;
-using System.Text;
using System.Text.RegularExpressions;
-using Glimpse.Core.Extensibility;
-namespace Glimpse.AspNet
+namespace Glimpse.Core.Framework
{
///
- /// This class will inject some html snippet (most likely the Glimpse Client script tags, but it can be anything) in the resulting HTML output.
+ /// This class will inject the Glimpse script tags in the resulting HTML output.
/// It will look for the last occurrence of the </body> tag and inject the snippet right before that tag.
- /// An instance of this class should be assigned as a filter to the outgoing response so that the injection can be done once all the rendering is completed.
///
- public class PreBodyTagFilter : Stream
+ public class ScriptTagsInjectionStream : Stream
{
private const string BodyClosingTag = "