From 1feee40a80c553f8049ff1057d5b73229fe2150e Mon Sep 17 00:00:00 2001 From: Wes Brown Date: Wed, 23 Nov 2011 16:08:49 -0500 Subject: [PATCH 1/9] Working on making a v3.5 configuration --- .../MvcMiniProfiler.EntityFramework.csproj | 32 ++++++++ .../MvcMiniProfiler.Tests.csproj | 33 ++++++++ .../MvcMiniProfiler.Wcf.csproj | 31 ++++++++ MvcMiniProfiler.sln | 30 +++++++ MvcMiniProfiler/MiniProfiler.cs | 55 ++++++++++++- MvcMiniProfiler/MvcMiniProfiler.csproj | 60 +++++++++++--- MvcMiniProfiler/SqlProfiler.cs | 78 +++++++++++++++++-- MvcMiniProfiler/UI/MiniProfilerHandler.cs | 23 +++++- Sample.Mvc/Sample.Mvc.csproj | 33 ++++++++ Sample.Wcf/Sample.Wcf.csproj | 28 +++++++ Sample.WebForms/Sample.WebForms.csproj | 31 ++++++++ 11 files changed, 413 insertions(+), 21 deletions(-) diff --git a/MvcMiniProfiler.EntityFramework/MvcMiniProfiler.EntityFramework.csproj b/MvcMiniProfiler.EntityFramework/MvcMiniProfiler.EntityFramework.csproj index cc1e981..c10cd70 100644 --- a/MvcMiniProfiler.EntityFramework/MvcMiniProfiler.EntityFramework.csproj +++ b/MvcMiniProfiler.EntityFramework/MvcMiniProfiler.EntityFramework.csproj @@ -36,6 +36,38 @@ miniprofiler.snk + + true + bin\NET35-Debug\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\MvcMiniProfiler.EntityFramework.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + + + bin\NET35-Release\ + TRACE + true + pdbonly + AnyCPU + bin\Release\MvcMiniProfiler.EntityFramework.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + True diff --git a/MvcMiniProfiler.Tests/MvcMiniProfiler.Tests.csproj b/MvcMiniProfiler.Tests/MvcMiniProfiler.Tests.csproj index 05fcd8b..f978617 100644 --- a/MvcMiniProfiler.Tests/MvcMiniProfiler.Tests.csproj +++ b/MvcMiniProfiler.Tests/MvcMiniProfiler.Tests.csproj @@ -38,6 +38,39 @@ Properties\MiniProfiler.Tests.snk + + true + bin\NET35-Debug\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\MvcMiniProfiler.Tests.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + + + bin\NET35-Release\ + TRACE + true + pdbonly + AnyCPU + bin\Release\MvcMiniProfiler.Tests.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + diff --git a/MvcMiniProfiler.Wcf/MvcMiniProfiler.Wcf.csproj b/MvcMiniProfiler.Wcf/MvcMiniProfiler.Wcf.csproj index 35db2a4..5f88f26 100644 --- a/MvcMiniProfiler.Wcf/MvcMiniProfiler.Wcf.csproj +++ b/MvcMiniProfiler.Wcf/MvcMiniProfiler.Wcf.csproj @@ -36,6 +36,37 @@ miniprofiler.snk + + true + bin\NET35-Debug\ + DEBUG;TRACE + full + AnyCPU + bin\Debug\MvcMiniProfiler.Wcf.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + + + bin\NET35-Release\ + TRACE + true + pdbonly + AnyCPU + bin\Release\MvcMiniProfiler.Wcf.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + diff --git a/MvcMiniProfiler.sln b/MvcMiniProfiler.sln index f4faa98..4388f71 100644 --- a/MvcMiniProfiler.sln +++ b/MvcMiniProfiler.sln @@ -38,35 +38,65 @@ Global EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + NET35-Debug|Any CPU = NET35-Debug|Any CPU + NET35-Release|Any CPU = NET35-Release|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {386222BD-6B6E-480F-A342-8DE1AB516E2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {386222BD-6B6E-480F-A342-8DE1AB516E2C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {386222BD-6B6E-480F-A342-8DE1AB516E2C}.NET35-Debug|Any CPU.ActiveCfg = NET35-Debug|Any CPU + {386222BD-6B6E-480F-A342-8DE1AB516E2C}.NET35-Debug|Any CPU.Build.0 = NET35-Debug|Any CPU + {386222BD-6B6E-480F-A342-8DE1AB516E2C}.NET35-Release|Any CPU.ActiveCfg = NET35-Release|Any CPU + {386222BD-6B6E-480F-A342-8DE1AB516E2C}.NET35-Release|Any CPU.Build.0 = NET35-Release|Any CPU {386222BD-6B6E-480F-A342-8DE1AB516E2C}.Release|Any CPU.ActiveCfg = Release|Any CPU {386222BD-6B6E-480F-A342-8DE1AB516E2C}.Release|Any CPU.Build.0 = Release|Any CPU {50A89C9B-7335-4626-B552-272CE56DC72E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {50A89C9B-7335-4626-B552-272CE56DC72E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {50A89C9B-7335-4626-B552-272CE56DC72E}.NET35-Debug|Any CPU.ActiveCfg = NET35-Debug|Any CPU + {50A89C9B-7335-4626-B552-272CE56DC72E}.NET35-Debug|Any CPU.Build.0 = NET35-Debug|Any CPU + {50A89C9B-7335-4626-B552-272CE56DC72E}.NET35-Release|Any CPU.ActiveCfg = NET35-Release|Any CPU + {50A89C9B-7335-4626-B552-272CE56DC72E}.NET35-Release|Any CPU.Build.0 = NET35-Release|Any CPU {50A89C9B-7335-4626-B552-272CE56DC72E}.Release|Any CPU.ActiveCfg = Release|Any CPU {50A89C9B-7335-4626-B552-272CE56DC72E}.Release|Any CPU.Build.0 = Release|Any CPU {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.NET35-Debug|Any CPU.ActiveCfg = NET35-Debug|Any CPU + {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.NET35-Debug|Any CPU.Build.0 = NET35-Debug|Any CPU + {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.NET35-Release|Any CPU.ActiveCfg = NET35-Release|Any CPU + {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.NET35-Release|Any CPU.Build.0 = NET35-Release|Any CPU {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.Release|Any CPU.ActiveCfg = Release|Any CPU {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.Release|Any CPU.Build.0 = Release|Any CPU {B4CA8022-257B-4893-97D8-76E05EBBAAB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B4CA8022-257B-4893-97D8-76E05EBBAAB0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B4CA8022-257B-4893-97D8-76E05EBBAAB0}.NET35-Debug|Any CPU.ActiveCfg = NET35-Debug|Any CPU + {B4CA8022-257B-4893-97D8-76E05EBBAAB0}.NET35-Debug|Any CPU.Build.0 = NET35-Debug|Any CPU + {B4CA8022-257B-4893-97D8-76E05EBBAAB0}.NET35-Release|Any CPU.ActiveCfg = NET35-Release|Any CPU + {B4CA8022-257B-4893-97D8-76E05EBBAAB0}.NET35-Release|Any CPU.Build.0 = NET35-Release|Any CPU {B4CA8022-257B-4893-97D8-76E05EBBAAB0}.Release|Any CPU.ActiveCfg = Release|Any CPU {B4CA8022-257B-4893-97D8-76E05EBBAAB0}.Release|Any CPU.Build.0 = Release|Any CPU {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Debug|Any CPU.ActiveCfg = NET35-Debug|Any CPU + {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Debug|Any CPU.Build.0 = NET35-Debug|Any CPU + {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Release|Any CPU.ActiveCfg = NET35-Release|Any CPU + {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Release|Any CPU.Build.0 = NET35-Release|Any CPU {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.Release|Any CPU.ActiveCfg = Release|Any CPU {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.Release|Any CPU.Build.0 = Release|Any CPU {C471B0E5-0AE4-48E0-A938-02AEDA030C5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C471B0E5-0AE4-48E0-A938-02AEDA030C5E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C471B0E5-0AE4-48E0-A938-02AEDA030C5E}.NET35-Debug|Any CPU.ActiveCfg = NET35-Debug|Any CPU + {C471B0E5-0AE4-48E0-A938-02AEDA030C5E}.NET35-Debug|Any CPU.Build.0 = NET35-Debug|Any CPU + {C471B0E5-0AE4-48E0-A938-02AEDA030C5E}.NET35-Release|Any CPU.ActiveCfg = NET35-Release|Any CPU + {C471B0E5-0AE4-48E0-A938-02AEDA030C5E}.NET35-Release|Any CPU.Build.0 = NET35-Release|Any CPU {C471B0E5-0AE4-48E0-A938-02AEDA030C5E}.Release|Any CPU.ActiveCfg = Release|Any CPU {C471B0E5-0AE4-48E0-A938-02AEDA030C5E}.Release|Any CPU.Build.0 = Release|Any CPU {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.NET35-Debug|Any CPU.ActiveCfg = NET35-Debug|Any CPU + {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.NET35-Debug|Any CPU.Build.0 = NET35-Debug|Any CPU + {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.NET35-Release|Any CPU.ActiveCfg = NET35-Release|Any CPU + {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.NET35-Release|Any CPU.Build.0 = NET35-Release|Any CPU {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.Release|Any CPU.ActiveCfg = Release|Any CPU {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection diff --git a/MvcMiniProfiler/MiniProfiler.cs b/MvcMiniProfiler/MiniProfiler.cs index 1287094..c62532e 100644 --- a/MvcMiniProfiler/MiniProfiler.cs +++ b/MvcMiniProfiler/MiniProfiler.cs @@ -320,7 +320,25 @@ public static IDisposable StepStatic(string name, ProfileLevel level = ProfileLe return MiniProfilerExtensions.Step(Current, name, level); } - /// +#if CSHARP30 + /// + /// Returns the css and javascript includes needed to display the MiniProfiler results UI. + /// + /// Which side of the page the profiler popup button should be displayed on (defaults to left) + /// Whether to show trivial timings by default (defaults to false) + /// Whether to show time the time with children column by default (defaults to false) + /// The maximum number of trace popups to show before removing the oldest (defaults to 15) + /// xhtml rendering mode, ensure script tag is closed ... etc + /// when true, shows buttons to minimize and clear MiniProfiler results + /// Script and link elements normally; an empty string when there is no active profiling session. + public static string RenderIncludes(RenderPosition? position = null, bool? showTrivial = null, bool? showTimeWithChildren = null, int? maxTracesToShow = null, bool xhtml = false, bool? showControls = null) + { + var result = UI.MiniProfilerHandler.RenderIncludes(Current, position, showTrivial, showTimeWithChildren, maxTracesToShow, xhtml, showControls); + + return result.ToString(); + } +#else + /// /// Returns the css and javascript includes needed to display the MiniProfiler results UI. /// /// Which side of the page the profiler popup button should be displayed on (defaults to left) @@ -334,8 +352,9 @@ public static IHtmlString RenderIncludes(RenderPosition? position = null, bool? { return UI.MiniProfilerHandler.RenderIncludes(Current, position, showTrivial, showTimeWithChildren, maxTracesToShow, xhtml, showControls); } +#endif - /// + /// /// Gets the currently running MiniProfiler for the current HttpContext; null if no MiniProfiler was ed. /// public static MiniProfiler Current @@ -486,10 +505,38 @@ public static void AddProfilerResults(this MiniProfiler profiler, MiniProfiler e profiler.Head.AddChild(externalProfiler.Root); } +#if CSHARP30 /// /// Returns an html-encoded string with a text-representation of ; returns "" when profiler is null. /// /// The current profiling session or null. + public static string Render(this MiniProfiler profiler) + { + if (profiler == null) return string.Empty; + + var text = new StringBuilder() + .Append(HttpUtility.HtmlEncode(Environment.MachineName)).Append(" at ").Append(DateTime.UtcNow).AppendLine(); + + Stack timings = new Stack(); + timings.Push(profiler.Root); + while (timings.Count > 0) + { + var timing = timings.Pop(); + string name = HttpUtility.HtmlEncode(timing.Name); + text.AppendFormat("{2} {0} = {1:###,##0.##}ms", name, timing.DurationMilliseconds, new string('>', timing.Depth)).AppendLine(); + if (timing.HasChildren) + { + IList children = timing.Children; + for (int i = children.Count - 1; i >= 0; i--) timings.Push(children[i]); + } + } + return text.ToString(); + } +#else + /// + /// Returns an html-encoded string with a text-representation of ; returns "" when profiler is null. + /// + /// The current profiling session or null. public static IHtmlString Render(this MiniProfiler profiler) { if (profiler == null) return new HtmlString(""); @@ -512,6 +559,6 @@ public static IHtmlString Render(this MiniProfiler profiler) } return new HtmlString(text.ToString()); } - - } +#endif + } } \ No newline at end of file diff --git a/MvcMiniProfiler/MvcMiniProfiler.csproj b/MvcMiniProfiler/MvcMiniProfiler.csproj index eac5ab0..fd8e70e 100644 --- a/MvcMiniProfiler/MvcMiniProfiler.csproj +++ b/MvcMiniProfiler/MvcMiniProfiler.csproj @@ -1,4 +1,4 @@ - + Debug @@ -10,12 +10,12 @@ Properties MvcMiniProfiler MvcMiniProfiler - v4.0 - 512 - + 512 - true + v4.0 + + true full false bin\Debug\ @@ -25,7 +25,9 @@ bin\Debug\MvcMiniProfiler.XML - pdbonly + v4.0 + + pdbonly true bin\Release\ TRACE;ASP_NET_MVC3 @@ -42,6 +44,43 @@ miniprofiler.snk + + v3.5 + + true + bin\NET35-Debug\ + TRACE;DEBUG;CSHARP30 + bin\Debug\MvcMiniProfiler.XML + full + AnyCPU + bin\Debug\MvcMiniProfiler.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + v3.5 + + bin\NET35-Release\ + TRACE;CSHARP30 + bin\Release\MvcMiniProfiler.xml + true + pdbonly + AnyCPU + bin\Release\MvcMiniProfiler.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + @@ -52,10 +91,11 @@ - - ..\..\StackOverflow\StackOverflow\lib\System.Web.Mvc.dll - - + + + + + diff --git a/MvcMiniProfiler/SqlProfiler.cs b/MvcMiniProfiler/SqlProfiler.cs index b0c3429..c979a66 100644 --- a/MvcMiniProfiler/SqlProfiler.cs +++ b/MvcMiniProfiler/SqlProfiler.cs @@ -3,21 +3,29 @@ using System.Data.Common; using MvcMiniProfiler.Data; using System.Linq; + +#if CSHARP30 +using Tuple = MvcMiniProfiler.Tuple; +#else using System.Collections.Concurrent; +#endif namespace MvcMiniProfiler { - - // TODO: refactor this out into MiniProfiler + // TODO: refactor this out into MiniProfiler /// /// Contains helper code to time sql statements. /// public class SqlProfiler { - ConcurrentDictionary, SqlTiming> _inProgress = new ConcurrentDictionary, SqlTiming>(); - ConcurrentDictionary _inProgressReaders = new ConcurrentDictionary(); - - /// +#if CSHARP30 + IConcurrentDictionary, SqlTiming> _inProgress = new MiniConcurrentDictionary, SqlTiming>(); + IConcurrentDictionary _inProgressReaders = new MiniConcurrentDictionary(); +#else + IConcurrentDictionary, SqlTiming> _inProgress = new MiniConcurrentDictionary, SqlTiming>(); + IConcurrentDictionary _inProgressReaders = new MiniConcurrentDictionary(); +#endif + /// /// The profiling session this SqlProfiler is part of. /// public MiniProfiler Profiler { get; private set; } @@ -112,4 +120,62 @@ public static void ReaderFinish(this SqlProfiler sqlProfiler, DbDataReader reade } } + + internal interface IConcurrentDictionary : IDictionary + { + bool TryRemove(TKey key, out TValue value); + } + +#if CSHARP30 + internal static class Tuple + { + public static Tuple Create(T1 item1, T2 item2) + { + return new Tuple(item1, item2); + } + } + + internal class Tuple + { + public Tuple(T1 item1, T2 item2) + { + Item1 = item1; + Item2 = item2; + } + + public T1 Item1 { get; private set; } + public T2 Item2 { get; private set; } + + public override int GetHashCode() + { + throw new NotImplementedException(); + } + + public override bool Equals(object obj) + { + throw new NotImplementedException(); + } + + public override string ToString() + { + throw new NotImplementedException(); + } + } + + internal class MiniConcurrentDictionary : Dictionary, IConcurrentDictionary + { + public bool TryRemove(TKey key, out TValue value) + { + throw new NotImplementedException(); + } + } +#else + internal class MiniConcurrentDictionary : ConcurrentDictionary, IConcurrentDictionary + { + bool IConcurrentDictionary.TryRemove(TKey key, out TValue value) + { + return base.TryRemove(key, out value); + } + } +#endif } \ No newline at end of file diff --git a/MvcMiniProfiler/UI/MiniProfilerHandler.cs b/MvcMiniProfiler/UI/MiniProfilerHandler.cs index 183f866..9b1cd8f 100644 --- a/MvcMiniProfiler/UI/MiniProfilerHandler.cs +++ b/MvcMiniProfiler/UI/MiniProfilerHandler.cs @@ -259,6 +259,27 @@ private static string NotFound(HttpContext context, string contentType = "text/p return message; } - } + +#if CSHARP30 + internal class HtmlString + { + public HtmlString() + : this(String.Empty) + { + } + + public HtmlString(string value) + { + _value = value; + } + + private string _value; + + public override string ToString() + { + return _value; + } + } +#endif } diff --git a/Sample.Mvc/Sample.Mvc.csproj b/Sample.Mvc/Sample.Mvc.csproj index b4388ee..5a09d95 100644 --- a/Sample.Mvc/Sample.Mvc.csproj +++ b/Sample.Mvc/Sample.Mvc.csproj @@ -33,6 +33,39 @@ prompt 4 + + true + bin\ + DEBUG;TRACE + full + AnyCPU + bin\SampleWeb.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + bin\ + TRACE + true + pdbonly + AnyCPU + bin\SampleWeb.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + True diff --git a/Sample.Wcf/Sample.Wcf.csproj b/Sample.Wcf/Sample.Wcf.csproj index e2c5cc1..33398b7 100644 --- a/Sample.Wcf/Sample.Wcf.csproj +++ b/Sample.Wcf/Sample.Wcf.csproj @@ -32,6 +32,34 @@ prompt 4 + + true + bin\ + DEBUG;TRACE + full + AnyCPU + bin\Sample.Wcf.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + + + bin\ + TRACE + true + pdbonly + AnyCPU + bin\Sample.Wcf.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + diff --git a/Sample.WebForms/Sample.WebForms.csproj b/Sample.WebForms/Sample.WebForms.csproj index f277dc8..0be6ed4 100644 --- a/Sample.WebForms/Sample.WebForms.csproj +++ b/Sample.WebForms/Sample.WebForms.csproj @@ -32,6 +32,37 @@ prompt 4 + + true + bin\ + DEBUG;TRACE + full + AnyCPU + bin\Sample.WebForms.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + bin\ + TRACE + true + pdbonly + AnyCPU + bin\Sample.WebForms.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + From 93e666c92e6a11c632da45570287502d0c853f7b Mon Sep 17 00:00:00 2001 From: Wes Brown Date: Wed, 23 Nov 2011 23:06:26 -0500 Subject: [PATCH 2/9] Completed initial implementation of 3.5 MvcMiniProfiler project. Still need to implement CurrentDictionary. --- MvcMiniProfiler/DotNet35Support.cs | 103 ++++++++++++++++++ MvcMiniProfiler/Helpers/ExtensionMethods.cs | 20 +++- MvcMiniProfiler/Helpers/StackTraceSnippet.cs | 2 +- MvcMiniProfiler/MiniProfiler.cs | 2 +- MvcMiniProfiler/MvcMiniProfiler.csproj | 33 +++--- .../SqlFormatters/SqlServerFormatter.cs | 2 +- MvcMiniProfiler/SqlProfiler.cs | 58 ---------- MvcMiniProfiler/SqlTiming.cs | 2 +- MvcMiniProfiler/Storage/SqlServerStorage.cs | 4 +- MvcMiniProfiler/UI/MiniProfilerHandler.cs | 4 +- MvcMiniProfiler/WebRequestProfilerProvider.cs | 23 +++- 11 files changed, 166 insertions(+), 87 deletions(-) create mode 100644 MvcMiniProfiler/DotNet35Support.cs diff --git a/MvcMiniProfiler/DotNet35Support.cs b/MvcMiniProfiler/DotNet35Support.cs new file mode 100644 index 0000000..ddb8a5f --- /dev/null +++ b/MvcMiniProfiler/DotNet35Support.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; + +#if !CSHARP30 +using System.Collections.Concurrent; +#endif + +namespace MvcMiniProfiler +{ + internal interface IConcurrentDictionary : IDictionary + { + bool TryRemove(TKey key, out TValue value); + } + +#if CSHARP30 + internal static class EnumHelper + { + public static bool TryParse(string value, out T e) + { + e = default(T); + + try + { + e = (T)Enum.Parse(typeof(T), value); + return true; + } + catch (Exception) + { + return false; + } + } + } + + internal static class GuidHelper + { + public static bool TryParse(string value, out Guid id) + { + id = Guid.Empty; + + try + { + id = new Guid(value); + return true; + } + catch (Exception) + { + return false; + } + } + } + + internal static class Tuple + { + public static Tuple Create(T1 item1, T2 item2) + { + return new Tuple(item1, item2); + } + } + + internal class Tuple + { + public Tuple(T1 item1, T2 item2) + { + Item1 = item1; + Item2 = item2; + } + + public T1 Item1 { get; private set; } + public T2 Item2 { get; private set; } + + public override int GetHashCode() + { + throw new NotImplementedException(); + } + + public override bool Equals(object obj) + { + throw new NotImplementedException(); + } + + public override string ToString() + { + throw new NotImplementedException(); + } + } + + internal class MiniConcurrentDictionary : Dictionary, IConcurrentDictionary + { + public bool TryRemove(TKey key, out TValue value) + { + throw new NotImplementedException(); + } + } +#else + internal class MiniConcurrentDictionary : ConcurrentDictionary, IConcurrentDictionary + { + bool IConcurrentDictionary.TryRemove(TKey key, out TValue value) + { + return base.TryRemove(key, out value); + } + } +#endif +} \ No newline at end of file diff --git a/MvcMiniProfiler/Helpers/ExtensionMethods.cs b/MvcMiniProfiler/Helpers/ExtensionMethods.cs index 0f60078..a27e047 100644 --- a/MvcMiniProfiler/Helpers/ExtensionMethods.cs +++ b/MvcMiniProfiler/Helpers/ExtensionMethods.cs @@ -17,7 +17,25 @@ internal static class ExtensionMethods /// internal static bool IsNullOrWhiteSpace(this string s) { +#if CSHARP30 + var result = false; + if (String.IsNullOrEmpty(s)) + { + result = true; + } + else if (s.Trim() == String.Empty) + { + result = true; + } + else + { + result = false; + } + + return result; +#else return string.IsNullOrWhiteSpace(s); +#endif } /// @@ -25,7 +43,7 @@ internal static bool IsNullOrWhiteSpace(this string s) /// internal static bool HasValue(this string s) { - return !string.IsNullOrWhiteSpace(s); + return !ExtensionMethods.IsNullOrWhiteSpace(s); } internal static string Truncate(this string s, int maxLength) diff --git a/MvcMiniProfiler/Helpers/StackTraceSnippet.cs b/MvcMiniProfiler/Helpers/StackTraceSnippet.cs index 1ca8fa7..d092068 100644 --- a/MvcMiniProfiler/Helpers/StackTraceSnippet.cs +++ b/MvcMiniProfiler/Helpers/StackTraceSnippet.cs @@ -43,7 +43,7 @@ public static string Get() } } - var result = string.Join(" ", methods); + var result = string.Join(" ", methods.ToArray()); if (result.Length > MiniProfiler.Settings.StackMaxLength) { diff --git a/MvcMiniProfiler/MiniProfiler.cs b/MvcMiniProfiler/MiniProfiler.cs index c62532e..d4dae7f 100644 --- a/MvcMiniProfiler/MiniProfiler.cs +++ b/MvcMiniProfiler/MiniProfiler.cs @@ -391,7 +391,7 @@ public static string ToJson(MiniProfiler profiler) /// public static MiniProfiler FromJson(string json) { - if (string.IsNullOrWhiteSpace(json)) return null; + if (ExtensionMethods.IsNullOrWhiteSpace(json)) return null; var result = new JavaScriptSerializer().Deserialize(json); return result; diff --git a/MvcMiniProfiler/MvcMiniProfiler.csproj b/MvcMiniProfiler/MvcMiniProfiler.csproj index fd8e70e..0ef2686 100644 --- a/MvcMiniProfiler/MvcMiniProfiler.csproj +++ b/MvcMiniProfiler/MvcMiniProfiler.csproj @@ -1,4 +1,4 @@ - + Debug @@ -10,12 +10,12 @@ Properties MvcMiniProfiler MvcMiniProfiler - 512 + 512 - v4.0 - - true + v4.0 + + true full false bin\Debug\ @@ -25,9 +25,9 @@ bin\Debug\MvcMiniProfiler.XML - v4.0 - - pdbonly + v4.0 + + pdbonly true bin\Release\ TRACE;ASP_NET_MVC3 @@ -45,9 +45,9 @@ miniprofiler.snk - v3.5 - - true + v3.5 + + true bin\NET35-Debug\ TRACE;DEBUG;CSHARP30 bin\Debug\MvcMiniProfiler.XML @@ -65,9 +65,9 @@ false - v3.5 - - bin\NET35-Release\ + v3.5 + + bin\NET35-Release\ TRACE;CSHARP30 bin\Release\MvcMiniProfiler.xml true @@ -92,10 +92,10 @@ - + - + @@ -104,6 +104,7 @@ + Code diff --git a/MvcMiniProfiler/SqlFormatters/SqlServerFormatter.cs b/MvcMiniProfiler/SqlFormatters/SqlServerFormatter.cs index f5c6f49..36f2a9e 100644 --- a/MvcMiniProfiler/SqlFormatters/SqlServerFormatter.cs +++ b/MvcMiniProfiler/SqlFormatters/SqlServerFormatter.cs @@ -72,7 +72,7 @@ public string FormatSql(SqlTiming timing) DbType parsed; string resolvedType = null; - if (!Enum.TryParse(p.DbType, out parsed)) + if (!EnumHelper.TryParse(p.DbType, out parsed)) { resolvedType = p.DbType; } diff --git a/MvcMiniProfiler/SqlProfiler.cs b/MvcMiniProfiler/SqlProfiler.cs index c979a66..38b1107 100644 --- a/MvcMiniProfiler/SqlProfiler.cs +++ b/MvcMiniProfiler/SqlProfiler.cs @@ -120,62 +120,4 @@ public static void ReaderFinish(this SqlProfiler sqlProfiler, DbDataReader reade } } - - internal interface IConcurrentDictionary : IDictionary - { - bool TryRemove(TKey key, out TValue value); - } - -#if CSHARP30 - internal static class Tuple - { - public static Tuple Create(T1 item1, T2 item2) - { - return new Tuple(item1, item2); - } - } - - internal class Tuple - { - public Tuple(T1 item1, T2 item2) - { - Item1 = item1; - Item2 = item2; - } - - public T1 Item1 { get; private set; } - public T2 Item2 { get; private set; } - - public override int GetHashCode() - { - throw new NotImplementedException(); - } - - public override bool Equals(object obj) - { - throw new NotImplementedException(); - } - - public override string ToString() - { - throw new NotImplementedException(); - } - } - - internal class MiniConcurrentDictionary : Dictionary, IConcurrentDictionary - { - public bool TryRemove(TKey key, out TValue value) - { - throw new NotImplementedException(); - } - } -#else - internal class MiniConcurrentDictionary : ConcurrentDictionary, IConcurrentDictionary - { - bool IConcurrentDictionary.TryRemove(TKey key, out TValue value) - { - return base.TryRemove(key, out value); - } - } -#endif } \ No newline at end of file diff --git a/MvcMiniProfiler/SqlTiming.cs b/MvcMiniProfiler/SqlTiming.cs index cf7e4b6..d1facf7 100644 --- a/MvcMiniProfiler/SqlTiming.cs +++ b/MvcMiniProfiler/SqlTiming.cs @@ -212,7 +212,7 @@ private List GetCommandParameters(DbCommand command) foreach (DbParameter dbParameter in command.Parameters) { - if (!string.IsNullOrWhiteSpace(dbParameter.ParameterName)) + if (!ExtensionMethods.IsNullOrWhiteSpace(dbParameter.ParameterName)) { var formattedParameterValue = GetFormattedParameterValue(dbParameter); result.Add(new SqlTimingParameter diff --git a/MvcMiniProfiler/Storage/SqlServerStorage.cs b/MvcMiniProfiler/Storage/SqlServerStorage.cs index a2d7a1b..ba91aad 100644 --- a/MvcMiniProfiler/Storage/SqlServerStorage.cs +++ b/MvcMiniProfiler/Storage/SqlServerStorage.cs @@ -265,7 +265,7 @@ protected virtual void SaveSqlTimingParameters(DbConnection conn, MiniProfiler p { typeof(SqlTimingParameter), "select * from MiniProfilerSqlTimingParameters where MiniProfilerId = @id" } }; - private static readonly string LoadSqlBatch = string.Join("\n", LoadSqlStatements.Select(pair => pair.Value)); + private static readonly string LoadSqlBatch = string.Join("\n", LoadSqlStatements.Select(pair => pair.Value).ToArray()); /// /// Loads the MiniProfiler identifed by 'id' from the database. @@ -297,7 +297,7 @@ private MiniProfiler LoadInBatch(DbConnection conn, object idParameter) { MiniProfiler result; - using (var multi = conn.QueryMultiple(LoadSqlBatch, idParameter)) + using (var multi = conn.QueryMultiple(LoadSqlBatch, idParameter, null, null, null)) { result = multi.Read().SingleOrDefault(); diff --git a/MvcMiniProfiler/UI/MiniProfilerHandler.cs b/MvcMiniProfiler/UI/MiniProfilerHandler.cs index 9b1cd8f..0d9a85b 100644 --- a/MvcMiniProfiler/UI/MiniProfilerHandler.cs +++ b/MvcMiniProfiler/UI/MiniProfilerHandler.cs @@ -178,11 +178,11 @@ private static string Results(HttpContext context) { // when we're rendering as a button/popup in the corner, we'll pass ?popup=1 // if it's absent, we're rendering results as a full page for sharing - var isPopup = !string.IsNullOrWhiteSpace(context.Request.QueryString["popup"]); + var isPopup = !ExtensionMethods.IsNullOrWhiteSpace(context.Request.QueryString["popup"]); // this guid is the MiniProfiler.Id property Guid id; - if (!Guid.TryParse(context.Request.QueryString["id"], out id)) + if (!GuidHelper.TryParse(context.Request.QueryString["id"], out id)) return isPopup ? NotFound(context) : NotFound(context, "text/plain", "No Guid id specified on the query string"); MiniProfiler.Settings.EnsureStorageStrategy(); diff --git a/MvcMiniProfiler/WebRequestProfilerProvider.cs b/MvcMiniProfiler/WebRequestProfilerProvider.cs index 483d67f..cbfa823 100644 --- a/MvcMiniProfiler/WebRequestProfilerProvider.cs +++ b/MvcMiniProfiler/WebRequestProfilerProvider.cs @@ -3,7 +3,13 @@ using System.Linq; using System.Text; using System.Web; + +#if CSHARP30 using System.Web.Routing; +#else +using System.Web.Mvc; +#endif + using MvcMiniProfiler.Helpers; namespace MvcMiniProfiler @@ -105,9 +111,18 @@ public override void Stop(bool discardResults) private static void EnsureName(MiniProfiler profiler, HttpRequest request) { // also set the profiler name to Controller/Action or /url - if (string.IsNullOrWhiteSpace(profiler.Name)) - { - var rc = request.RequestContext; + if (ExtensionMethods.IsNullOrWhiteSpace(profiler.Name)) + { +#if CSHARP30 + RequestContext rc = null; + var handler = ((MvcHandler)HttpContext.Current.Handler); + if (handler != null) + { + rc = handler.RequestContext; + } +#else + var rc = request.RequestContext; +#endif RouteValueDictionary values; if (rc != null && rc.RouteData != null && (values = rc.RouteData.Values).Count > 0) @@ -119,7 +134,7 @@ private static void EnsureName(MiniProfiler profiler, HttpRequest request) profiler.Name = controller.ToString() + "/" + action.ToString(); } - if (string.IsNullOrWhiteSpace(profiler.Name)) + if (ExtensionMethods.IsNullOrWhiteSpace(profiler.Name)) { profiler.Name = request.Url.AbsolutePath ?? ""; if (profiler.Name.Length > 50) From 968cab41e8c46d9b65b335d02ed88cdfcb803c0b Mon Sep 17 00:00:00 2001 From: Wes Brown Date: Wed, 23 Nov 2011 23:27:19 -0500 Subject: [PATCH 3/9] Fixed the references to load properly based on the config. VS doesn't appear to update these references when changed without restarting. --- MvcMiniProfiler/MvcMiniProfiler.csproj | 21 +++++++++++++------ MvcMiniProfiler/WebRequestProfilerProvider.cs | 9 ++------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/MvcMiniProfiler/MvcMiniProfiler.csproj b/MvcMiniProfiler/MvcMiniProfiler.csproj index 0ef2686..7cc93c8 100644 --- a/MvcMiniProfiler/MvcMiniProfiler.csproj +++ b/MvcMiniProfiler/MvcMiniProfiler.csproj @@ -1,4 +1,4 @@ - + Debug @@ -82,7 +82,6 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - @@ -91,12 +90,22 @@ - - - - + + + + + + + + + + + + + + IProfilerProvider.cs diff --git a/MvcMiniProfiler/WebRequestProfilerProvider.cs b/MvcMiniProfiler/WebRequestProfilerProvider.cs index cbfa823..4281084 100644 --- a/MvcMiniProfiler/WebRequestProfilerProvider.cs +++ b/MvcMiniProfiler/WebRequestProfilerProvider.cs @@ -1,13 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Web; +using System.Web; +using System.Web.Mvc; #if CSHARP30 using System.Web.Routing; -#else -using System.Web.Mvc; #endif using MvcMiniProfiler.Helpers; From e28dba736251c7310f7e170f90c26905e3d34c4e Mon Sep 17 00:00:00 2001 From: Wes Brown Date: Wed, 23 Nov 2011 23:40:01 -0500 Subject: [PATCH 4/9] Removed EF from 3.5 support. If you're using EF go ahead and updated to 4.0 already. --- .../MvcMiniProfiler.EntityFramework.csproj | 37 ++----------------- MvcMiniProfiler.sln | 8 ++-- 2 files changed, 7 insertions(+), 38 deletions(-) diff --git a/MvcMiniProfiler.EntityFramework/MvcMiniProfiler.EntityFramework.csproj b/MvcMiniProfiler.EntityFramework/MvcMiniProfiler.EntityFramework.csproj index c10cd70..b954236 100644 --- a/MvcMiniProfiler.EntityFramework/MvcMiniProfiler.EntityFramework.csproj +++ b/MvcMiniProfiler.EntityFramework/MvcMiniProfiler.EntityFramework.csproj @@ -1,4 +1,4 @@ - + Debug @@ -10,10 +10,10 @@ Properties MvcMiniProfiler.EntityFramework MvcMiniProfiler.EntityFramework - v4.0 512 + v4.0 true full false @@ -23,6 +23,7 @@ 4 + v4.0 pdbonly true bin\Release\ @@ -36,38 +37,6 @@ miniprofiler.snk - - true - bin\NET35-Debug\ - DEBUG;TRACE - full - AnyCPU - bin\Debug\MvcMiniProfiler.EntityFramework.dll.CodeAnalysisLog.xml - true - GlobalSuppressions.cs - prompt - MinimumRecommendedRules.ruleset - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - false - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - - - bin\NET35-Release\ - TRACE - true - pdbonly - AnyCPU - bin\Release\MvcMiniProfiler.EntityFramework.dll.CodeAnalysisLog.xml - true - GlobalSuppressions.cs - prompt - MinimumRecommendedRules.ruleset - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - false - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - false - false - True diff --git a/MvcMiniProfiler.sln b/MvcMiniProfiler.sln index 4388f71..090600f 100644 --- a/MvcMiniProfiler.sln +++ b/MvcMiniProfiler.sln @@ -77,10 +77,10 @@ Global {B4CA8022-257B-4893-97D8-76E05EBBAAB0}.Release|Any CPU.Build.0 = Release|Any CPU {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Debug|Any CPU.ActiveCfg = NET35-Debug|Any CPU - {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Debug|Any CPU.Build.0 = NET35-Debug|Any CPU - {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Release|Any CPU.ActiveCfg = NET35-Release|Any CPU - {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Release|Any CPU.Build.0 = NET35-Release|Any CPU + {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Debug|Any CPU.Build.0 = Debug|Any CPU + {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Release|Any CPU.ActiveCfg = Release|Any CPU + {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Release|Any CPU.Build.0 = Release|Any CPU {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.Release|Any CPU.ActiveCfg = Release|Any CPU {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.Release|Any CPU.Build.0 = Release|Any CPU {C471B0E5-0AE4-48E0-A938-02AEDA030C5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU From 35e6cc21e2c2f7ae6f88167a1a1f4bae14995fbb Mon Sep 17 00:00:00 2001 From: Wes Brown Date: Thu, 24 Nov 2011 10:04:25 -0500 Subject: [PATCH 5/9] Created simple implementation of MiniConcurrentDictionary for SqlProfiler. --- MvcMiniProfiler/DotNet35Support.cs | 173 ++++++++++++++++++++++++++++- 1 file changed, 170 insertions(+), 3 deletions(-) diff --git a/MvcMiniProfiler/DotNet35Support.cs b/MvcMiniProfiler/DotNet35Support.cs index ddb8a5f..d8ade24 100644 --- a/MvcMiniProfiler/DotNet35Support.cs +++ b/MvcMiniProfiler/DotNet35Support.cs @@ -1,6 +1,11 @@ using System; + +using System.Collections; + using System.Collections.Generic; +using System.Threading; + #if !CSHARP30 using System.Collections.Concurrent; #endif @@ -70,12 +75,25 @@ public Tuple(T1 item1, T2 item2) public override int GetHashCode() { - throw new NotImplementedException(); + return Item1.GetHashCode() ^ Item2.GetHashCode(); } public override bool Equals(object obj) { - throw new NotImplementedException(); + if (obj == null) + { + return false; + } + + var other = obj as Tuple; + if (other == null) + { + return false; + } + + var comparer1 = EqualityComparer.Default; + var comparer2 = EqualityComparer.Default; + return comparer1.Equals(Item1, other.Item1)&& comparer2.Equals(Item2, other.Item2); } public override string ToString() @@ -84,12 +102,161 @@ public override string ToString() } } - internal class MiniConcurrentDictionary : Dictionary, IConcurrentDictionary + /// + /// This is a dictionary that only implements the methods required by the . Concurrency is very simply implemented via a . + /// + /// The type of the key. + /// The type of the value. + internal class MiniConcurrentDictionary : IConcurrentDictionary { + private Dictionary _dict = new Dictionary(); + private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); + + public TValue this[TKey key] + { + get + { + _lock.EnterReadLock(); + try + { + return _dict[key]; + } + finally + { + _lock.ExitReadLock(); + } + } + set + { + _lock.EnterWriteLock(); + try + { + _dict[key] = value; + } + finally + { + _lock.ExitWriteLock(); + } + } + } + + public ICollection Values + { + get + { + _lock.EnterReadLock(); + try + { + return _dict.Values; + } + finally + { + _lock.ExitReadLock(); + } + } + } + + public bool TryGetValue(TKey key, out TValue value) + { + var result = false; + _lock.EnterReadLock(); + try + { + result = _dict.TryGetValue(key, out value); + } + finally + { + _lock.ExitReadLock(); + } + + return result; + } + public bool TryRemove(TKey key, out TValue value) + { + var result = false; + _lock.EnterWriteLock(); + try + { + if (_dict.TryGetValue(key, out value)) + { + result = _dict.Remove(key); + } + } + finally + { + _lock.ExitWriteLock(); + } + + return result; + } + + #region Not Implemented + + public IEnumerator> GetEnumerator() { throw new NotImplementedException(); } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public void Add(KeyValuePair item) + { + throw new NotImplementedException(); + } + + public void Clear() + { + throw new NotImplementedException(); + } + + public bool Contains(KeyValuePair item) + { + throw new NotImplementedException(); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public bool Remove(KeyValuePair item) + { + throw new NotImplementedException(); + } + + public int Count + { + get { throw new NotImplementedException(); } + } + public bool IsReadOnly + { + get { throw new NotImplementedException(); } + } + public bool ContainsKey(TKey key) + { + throw new NotImplementedException(); + } + + public void Add(TKey key, TValue value) + { + throw new NotImplementedException(); + } + + public bool Remove(TKey key) + { + throw new NotImplementedException(); + } + + public ICollection Keys + { + get { throw new NotImplementedException(); } + } + + #endregion } #else internal class MiniConcurrentDictionary : ConcurrentDictionary, IConcurrentDictionary From e263e46f0311ad4d1fb3e7e5fde6134d2f1d8156 Mon Sep 17 00:00:00 2001 From: Wes Brown Date: Thu, 24 Nov 2011 10:24:23 -0500 Subject: [PATCH 6/9] Finished initial implementation for 3.5. All tests pass but EntityFramework and Samples are not built in the 3.5 configurations. Need to test on an 2003/XP machine. --- MvcMiniProfiler.Tests/Data/IDbProfilerTest.cs | 3 +- .../MvcMiniProfiler.Tests.csproj | 11 +++--- .../Storage/SqlServerStorageTest.cs | 3 +- MvcMiniProfiler.sln | 20 ++++------- MvcMiniProfiler/Helpers/SqlMapper.cs | 36 +++++++++++++++++-- Sample.Mvc/Sample.Mvc.csproj | 35 +----------------- Sample.Wcf/Sample.Wcf.csproj | 30 +--------------- Sample.WebForms/Sample.WebForms.csproj | 33 +---------------- 8 files changed, 53 insertions(+), 118 deletions(-) diff --git a/MvcMiniProfiler.Tests/Data/IDbProfilerTest.cs b/MvcMiniProfiler.Tests/Data/IDbProfilerTest.cs index 9624cdd..7f0b783 100644 --- a/MvcMiniProfiler.Tests/Data/IDbProfilerTest.cs +++ b/MvcMiniProfiler.Tests/Data/IDbProfilerTest.cs @@ -140,6 +140,7 @@ public void Errors() } } +#if !CSHARP30 [Test] public void DataAdapter() { @@ -165,6 +166,6 @@ public void DataAdapter() Assert.That(mp.ExecutedScalars == 0); Assert.That(mp.ExecutedNonQueries == 0); } - +#endif } } diff --git a/MvcMiniProfiler.Tests/MvcMiniProfiler.Tests.csproj b/MvcMiniProfiler.Tests/MvcMiniProfiler.Tests.csproj index f978617..4b91f2e 100644 --- a/MvcMiniProfiler.Tests/MvcMiniProfiler.Tests.csproj +++ b/MvcMiniProfiler.Tests/MvcMiniProfiler.Tests.csproj @@ -1,4 +1,4 @@ - + Debug @@ -11,11 +11,11 @@ Properties MvcMiniProfiler.Tests MvcMiniProfiler.Tests - v4.0 512 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + v4.0 true full false @@ -25,6 +25,7 @@ 4 + v4.0 pdbonly true bin\Release\ @@ -39,9 +40,10 @@ Properties\MiniProfiler.Tests.snk + v3.5 true bin\NET35-Debug\ - DEBUG;TRACE + DEBUG;TRACE;CSHARP30 full AnyCPU bin\Debug\MvcMiniProfiler.Tests.dll.CodeAnalysisLog.xml @@ -55,8 +57,9 @@ true + v3.5 bin\NET35-Release\ - TRACE + TRACE;CSHARP30 true pdbonly AnyCPU diff --git a/MvcMiniProfiler.Tests/Storage/SqlServerStorageTest.cs b/MvcMiniProfiler.Tests/Storage/SqlServerStorageTest.cs index 2682c5f..4fb28c0 100644 --- a/MvcMiniProfiler.Tests/Storage/SqlServerStorageTest.cs +++ b/MvcMiniProfiler.Tests/Storage/SqlServerStorageTest.cs @@ -9,6 +9,7 @@ using System.Data.SqlServerCe; using MvcMiniProfiler.Helpers.Dapper; using MvcMiniProfiler.Data; +using MvcMiniProfiler.Helpers; namespace MvcMiniProfiler.Tests.Storage { @@ -18,7 +19,7 @@ public class SqlServerStorageTest : BaseTest [TestFixtureSetUp] public void TestFixtureSetUp() { - var sqlToExecute = SqlServerStorage.TableCreationScript.Replace("nvarchar(max)", "ntext").Split(';').Where(s => !string.IsNullOrWhiteSpace(s)); + var sqlToExecute = SqlServerStorage.TableCreationScript.Replace("nvarchar(max)", "ntext").Split(';').Where(s => !ExtensionMethods.IsNullOrWhiteSpace(s)); var connStr = CreateSqlCeDatabase(sqlToExecute: sqlToExecute); MiniProfiler.Settings.Storage = new SqlCeStorage(connStr); diff --git a/MvcMiniProfiler.sln b/MvcMiniProfiler.sln index 090600f..70755cb 100644 --- a/MvcMiniProfiler.sln +++ b/MvcMiniProfiler.sln @@ -53,18 +53,14 @@ Global {386222BD-6B6E-480F-A342-8DE1AB516E2C}.Release|Any CPU.Build.0 = Release|Any CPU {50A89C9B-7335-4626-B552-272CE56DC72E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {50A89C9B-7335-4626-B552-272CE56DC72E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {50A89C9B-7335-4626-B552-272CE56DC72E}.NET35-Debug|Any CPU.ActiveCfg = NET35-Debug|Any CPU - {50A89C9B-7335-4626-B552-272CE56DC72E}.NET35-Debug|Any CPU.Build.0 = NET35-Debug|Any CPU - {50A89C9B-7335-4626-B552-272CE56DC72E}.NET35-Release|Any CPU.ActiveCfg = NET35-Release|Any CPU - {50A89C9B-7335-4626-B552-272CE56DC72E}.NET35-Release|Any CPU.Build.0 = NET35-Release|Any CPU + {50A89C9B-7335-4626-B552-272CE56DC72E}.NET35-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {50A89C9B-7335-4626-B552-272CE56DC72E}.NET35-Release|Any CPU.ActiveCfg = Release|Any CPU {50A89C9B-7335-4626-B552-272CE56DC72E}.Release|Any CPU.ActiveCfg = Release|Any CPU {50A89C9B-7335-4626-B552-272CE56DC72E}.Release|Any CPU.Build.0 = Release|Any CPU {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.NET35-Debug|Any CPU.ActiveCfg = NET35-Debug|Any CPU - {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.NET35-Debug|Any CPU.Build.0 = NET35-Debug|Any CPU - {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.NET35-Release|Any CPU.ActiveCfg = NET35-Release|Any CPU - {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.NET35-Release|Any CPU.Build.0 = NET35-Release|Any CPU + {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.NET35-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.NET35-Release|Any CPU.ActiveCfg = Release|Any CPU {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.Release|Any CPU.ActiveCfg = Release|Any CPU {5D54F88D-4C79-4EAB-B7B7-C8DE78F5DDA7}.Release|Any CPU.Build.0 = Release|Any CPU {B4CA8022-257B-4893-97D8-76E05EBBAAB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -78,9 +74,7 @@ Global {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.Debug|Any CPU.Build.0 = Debug|Any CPU {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Debug|Any CPU.Build.0 = Debug|Any CPU {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Release|Any CPU.ActiveCfg = Release|Any CPU - {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.NET35-Release|Any CPU.Build.0 = Release|Any CPU {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.Release|Any CPU.ActiveCfg = Release|Any CPU {7F18DC76-61A2-4E7D-BA5A-FE159E789362}.Release|Any CPU.Build.0 = Release|Any CPU {C471B0E5-0AE4-48E0-A938-02AEDA030C5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -93,10 +87,8 @@ Global {C471B0E5-0AE4-48E0-A938-02AEDA030C5E}.Release|Any CPU.Build.0 = Release|Any CPU {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.NET35-Debug|Any CPU.ActiveCfg = NET35-Debug|Any CPU - {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.NET35-Debug|Any CPU.Build.0 = NET35-Debug|Any CPU - {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.NET35-Release|Any CPU.ActiveCfg = NET35-Release|Any CPU - {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.NET35-Release|Any CPU.Build.0 = NET35-Release|Any CPU + {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.NET35-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.NET35-Release|Any CPU.ActiveCfg = Release|Any CPU {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.Release|Any CPU.ActiveCfg = Release|Any CPU {2DD1E352-3FFE-49F8-ADAB-65F3FECE75E6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection diff --git a/MvcMiniProfiler/Helpers/SqlMapper.cs b/MvcMiniProfiler/Helpers/SqlMapper.cs index aebe4fa..23b3ba5 100644 --- a/MvcMiniProfiler/Helpers/SqlMapper.cs +++ b/MvcMiniProfiler/Helpers/SqlMapper.cs @@ -433,7 +433,16 @@ public bool Equals(Identity other) } #if CSHARP30 - /// + /// + /// Execute SQL + /// + /// Number of rows affected + public static int Execute(this IDbConnection cnn, string sql) + { + return Execute(cnn, sql, null, null, null, null); + } + + /// /// Execute parameterized SQL /// /// Number of rows affected @@ -441,7 +450,29 @@ public static int Execute(this IDbConnection cnn, string sql, object param) { return Execute(cnn, sql, param, null, null, null); } - /// + + /// + /// Executes a query, returning the data typed as per T + /// + public static IEnumerable Query(this IDbConnection cnn, string sql) + { + return Query(cnn, sql, null, null, true, null, null); + } + + /// + /// Executes a query, returning the data typed as per T + /// + public static IEnumerable Query(this IDbConnection cnn, string sql) + { + return Query(cnn, sql, null, null, true, null, null); + } + + public static IEnumerable Query(this IDbConnection cnn, string sql, object param) + { + return Query(cnn, sql, param, null, true, null, null); + } + + /// /// Executes a query, returning the data typed as per T /// /// the dynamic param may seem a bit odd, but this works around a major usability issue in vs, if it is Object vs completion gets annoying. Eg type new get new object @@ -452,7 +483,6 @@ public static IEnumerable Query(this IDbConnection cnn, string sql, object { return Query(cnn, sql, param, null, true, null, null); } - #endif /// /// Execute parameterized SQL diff --git a/Sample.Mvc/Sample.Mvc.csproj b/Sample.Mvc/Sample.Mvc.csproj index 5a09d95..95a9bd2 100644 --- a/Sample.Mvc/Sample.Mvc.csproj +++ b/Sample.Mvc/Sample.Mvc.csproj @@ -1,4 +1,4 @@ - + Debug @@ -33,39 +33,6 @@ prompt 4 - - true - bin\ - DEBUG;TRACE - full - AnyCPU - bin\SampleWeb.dll.CodeAnalysisLog.xml - true - GlobalSuppressions.cs - prompt - MinimumRecommendedRules.ruleset - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - true - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - true - false - - - bin\ - TRACE - true - pdbonly - AnyCPU - bin\SampleWeb.dll.CodeAnalysisLog.xml - true - GlobalSuppressions.cs - prompt - MinimumRecommendedRules.ruleset - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - false - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - false - True diff --git a/Sample.Wcf/Sample.Wcf.csproj b/Sample.Wcf/Sample.Wcf.csproj index 33398b7..46da249 100644 --- a/Sample.Wcf/Sample.Wcf.csproj +++ b/Sample.Wcf/Sample.Wcf.csproj @@ -1,4 +1,4 @@ - + Debug @@ -32,34 +32,6 @@ prompt 4 - - true - bin\ - DEBUG;TRACE - full - AnyCPU - bin\Sample.Wcf.dll.CodeAnalysisLog.xml - true - GlobalSuppressions.cs - prompt - MinimumRecommendedRules.ruleset - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - - - bin\ - TRACE - true - pdbonly - AnyCPU - bin\Sample.Wcf.dll.CodeAnalysisLog.xml - true - GlobalSuppressions.cs - prompt - MinimumRecommendedRules.ruleset - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - diff --git a/Sample.WebForms/Sample.WebForms.csproj b/Sample.WebForms/Sample.WebForms.csproj index 0be6ed4..7b5de34 100644 --- a/Sample.WebForms/Sample.WebForms.csproj +++ b/Sample.WebForms/Sample.WebForms.csproj @@ -1,4 +1,4 @@ - + Debug @@ -32,37 +32,6 @@ prompt 4 - - true - bin\ - DEBUG;TRACE - full - AnyCPU - bin\Sample.WebForms.dll.CodeAnalysisLog.xml - true - GlobalSuppressions.cs - prompt - MinimumRecommendedRules.ruleset - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - true - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - true - false - - - bin\ - TRACE - true - pdbonly - AnyCPU - bin\Sample.WebForms.dll.CodeAnalysisLog.xml - true - GlobalSuppressions.cs - prompt - MinimumRecommendedRules.ruleset - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - From ca2086bd4131462df7e28491520727db0ddbeb90 Mon Sep 17 00:00:00 2001 From: Wes Brown Date: Wed, 30 Nov 2011 14:32:05 -0500 Subject: [PATCH 7/9] Fixed casting bug when trying to get MvcHandler. --- MvcMiniProfiler/WebRequestProfilerProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MvcMiniProfiler/WebRequestProfilerProvider.cs b/MvcMiniProfiler/WebRequestProfilerProvider.cs index 4281084..1daee53 100644 --- a/MvcMiniProfiler/WebRequestProfilerProvider.cs +++ b/MvcMiniProfiler/WebRequestProfilerProvider.cs @@ -110,7 +110,7 @@ private static void EnsureName(MiniProfiler profiler, HttpRequest request) { #if CSHARP30 RequestContext rc = null; - var handler = ((MvcHandler)HttpContext.Current.Handler); + var handler = HttpContext.Current.Handler as MvcHandler; if (handler != null) { rc = handler.RequestContext; From 7edc43997a16f5a9b7a6955c032b561557780d35 Mon Sep 17 00:00:00 2001 From: Wes Brown Date: Wed, 30 Nov 2011 14:43:58 -0500 Subject: [PATCH 8/9] Minor whitespace edits to the project file. --- MvcMiniProfiler/MvcMiniProfiler.csproj | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/MvcMiniProfiler/MvcMiniProfiler.csproj b/MvcMiniProfiler/MvcMiniProfiler.csproj index 7cc93c8..9564b5d 100644 --- a/MvcMiniProfiler/MvcMiniProfiler.csproj +++ b/MvcMiniProfiler/MvcMiniProfiler.csproj @@ -1,4 +1,4 @@ - + Debug @@ -93,18 +93,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + From 1e176417ceefe92813b4e695c1fa9b2c645e25b7 Mon Sep 17 00:00:00 2001 From: Kevin Pullin Date: Tue, 10 Jan 2012 14:06:12 -0800 Subject: [PATCH 9/9] Fixed potential bug with the MiniConcurrentDictionary.Values --- MvcMiniProfiler/DotNet35Support.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MvcMiniProfiler/DotNet35Support.cs b/MvcMiniProfiler/DotNet35Support.cs index d8ade24..3941778 100644 --- a/MvcMiniProfiler/DotNet35Support.cs +++ b/MvcMiniProfiler/DotNet35Support.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Threading; +using System.Linq; #if !CSHARP30 using System.Collections.Concurrent; @@ -147,7 +148,7 @@ public ICollection Values _lock.EnterReadLock(); try { - return _dict.Values; + return _dict.Values.ToList(); } finally {