mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Adding MiniProfiler module
--HG-- branch : NH3
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ContainerModule.cs" company="Daniel Dabrowski - rod.42n.pl">
|
||||
// Copyright (c) 2008 Daniel Dabrowski - 42n. All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Defines the ContainerModule type.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace Four2n.Orchard.MiniProfiler
|
||||
{
|
||||
using System;
|
||||
|
||||
using Autofac;
|
||||
|
||||
using Four2n.Orchard.MiniProfiler.Data;
|
||||
|
||||
using global::Orchard.Environment;
|
||||
|
||||
using StackExchange.Profiling;
|
||||
using StackExchange.Profiling.Storage;
|
||||
|
||||
using Module = Autofac.Module;
|
||||
|
||||
public class ContainerModule : Module
|
||||
{
|
||||
private readonly IOrchardHost orchardHost;
|
||||
|
||||
public ContainerModule(IOrchardHost orchardHost)
|
||||
{
|
||||
this.orchardHost = orchardHost;
|
||||
}
|
||||
|
||||
protected override void Load(ContainerBuilder moduleBuilder)
|
||||
{
|
||||
InitProfilerSettings();
|
||||
var currentLogger = ((DefaultOrchardHost)this.orchardHost).Logger;
|
||||
if (currentLogger is OrchardHostProxyLogger)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
((DefaultOrchardHost)this.orchardHost).Logger = new OrchardHostProxyLogger(currentLogger);
|
||||
}
|
||||
|
||||
private static void InitProfilerSettings()
|
||||
{
|
||||
MiniProfiler.Settings.SqlFormatter = new PoorMansTSqlFormatter();
|
||||
MiniProfiler.Settings.Storage = new ProfilerStorage(TimeSpan.FromSeconds(30));
|
||||
MiniProfiler.Settings.StackMaxLength = 500;
|
||||
MiniProfiler.Settings.ExcludeAssembly("MiniProfiler");
|
||||
MiniProfiler.Settings.ExcludeAssembly("NHibernate");
|
||||
WebRequestProfilerProvider.Settings.UserProvider = new IpAddressIdentity();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PoorMansTSqlFormatter.cs" company="Daniel Dabrowski - rod.42n.pl">
|
||||
// Copyright (c) 2008 Daniel Dabrowski - 42n. All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Defines the PoorMansTSqlFormatter type.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace Four2n.Orchard.MiniProfiler.Data
|
||||
{
|
||||
using PoorMansTSqlFormatterLib;
|
||||
using PoorMansTSqlFormatterLib.Formatters;
|
||||
|
||||
using StackExchange.Profiling;
|
||||
using StackExchange.Profiling.SqlFormatters;
|
||||
|
||||
public class PoorMansTSqlFormatter : ISqlFormatter
|
||||
{
|
||||
|
||||
public string FormatSql(SqlTiming timing)
|
||||
{
|
||||
var sqlFormatter = new SqlServerFormatter();
|
||||
var sqlFormat = sqlFormatter.FormatSql(timing);
|
||||
|
||||
var poorMansFormatter = new TSqlStandardFormatter();
|
||||
var fullFormatter = new SqlFormattingManager(poorMansFormatter);
|
||||
return fullFormatter.Format(sqlFormat);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ProfiledSqlCeDataServicesProvider.cs" company="Daniel Dabrowski - rod.42n.pl">
|
||||
// Copyright (c) 2008 Daniel Dabrowski - 42n. All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Defines the ProfiledSqlCeDataServicesProvider type.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
using FluentNHibernate.Cfg.Db;
|
||||
using MsSqlCeConfiguration = Orchard.Data.Providers.MsSqlCeConfiguration;
|
||||
|
||||
namespace Four2n.Orchard.MiniProfiler.Data.Providers
|
||||
{
|
||||
using global::Orchard.Environment.Extensions;
|
||||
|
||||
[OrchardSuppressDependency("Orchard.Data.Providers.SqlCeDataServicesProvider")]
|
||||
public class ProfiledSqlCeDataServicesProvider : global::Orchard.Data.Providers.SqlCeDataServicesProvider
|
||||
{
|
||||
public ProfiledSqlCeDataServicesProvider(string dataFolder, string connectionString)
|
||||
: base(dataFolder, connectionString)
|
||||
{
|
||||
}
|
||||
|
||||
public static string ProviderName
|
||||
{
|
||||
get { return global::Orchard.Data.Providers.SqlCeDataServicesProvider.ProviderName; }
|
||||
}
|
||||
|
||||
public override IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase)
|
||||
{
|
||||
var persistence = (MsSqlCeConfiguration)base.GetPersistenceConfigurer(createDatabase);
|
||||
return persistence.Driver(typeof(ProfiledSqlServerCeDriver).AssemblyQualifiedName);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ProfiledSqlClientDriver.cs" company="Daniel Dabrowski - rod.42n.pl">
|
||||
// Copyright (c) 2008 Daniel Dabrowski - 42n. All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Defines the ProfiledSqlClientDriver type.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace Four2n.Orchard.MiniProfiler.Data.Providers
|
||||
{
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Diagnostics;
|
||||
|
||||
using NHibernate.Driver;
|
||||
|
||||
using StackExchange.Profiling.Data;
|
||||
|
||||
public class ProfiledSqlClientDriver : SqlClientDriver
|
||||
{
|
||||
public override IDbCommand CreateCommand()
|
||||
{
|
||||
var command = base.CreateCommand();
|
||||
if (StackExchange.Profiling.MiniProfiler.Current != null)
|
||||
{
|
||||
command = new ProfiledDbCommand(
|
||||
(DbCommand)command,
|
||||
(ProfiledDbConnection)command.Connection,
|
||||
StackExchange.Profiling.MiniProfiler.Current);
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
public override IDbConnection CreateConnection()
|
||||
{
|
||||
if (StackExchange.Profiling.MiniProfiler.Current == null)
|
||||
{
|
||||
return base.CreateConnection();
|
||||
}
|
||||
|
||||
return new ProfiledDbConnection(
|
||||
base.CreateConnection() as DbConnection,
|
||||
StackExchange.Profiling.MiniProfiler.Current);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ProfiledSqlServerCeDriver.cs" company="Daniel Dabrowski - rod.42n.pl">
|
||||
// Copyright (c) 2008 Daniel Dabrowski - 42n. All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Defines the ProfiledSqlServerCeDriver type.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace Four2n.Orchard.MiniProfiler.Data.Providers
|
||||
{
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Diagnostics;
|
||||
|
||||
using global::Orchard.Data.Providers;
|
||||
|
||||
using StackExchange.Profiling.Data;
|
||||
|
||||
public class ProfiledSqlServerCeDriver : SqlCeDataServicesProvider.OrchardSqlServerCeDriver
|
||||
{
|
||||
public override IDbCommand CreateCommand()
|
||||
{
|
||||
var command = base.CreateCommand();
|
||||
if (StackExchange.Profiling.MiniProfiler.Current != null)
|
||||
{
|
||||
command = new ProfiledDbCommand(
|
||||
(DbCommand)command,
|
||||
(ProfiledDbConnection)command.Connection,
|
||||
StackExchange.Profiling.MiniProfiler.Current);
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
public override IDbConnection CreateConnection()
|
||||
{
|
||||
if (StackExchange.Profiling.MiniProfiler.Current == null)
|
||||
{
|
||||
return base.CreateConnection();
|
||||
}
|
||||
|
||||
return new ProfiledDbConnection(
|
||||
base.CreateConnection() as DbConnection,
|
||||
StackExchange.Profiling.MiniProfiler.Current);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ProfiledSqlServerDataServicesProvider.cs" company="Daniel Dabrowski - rod.42n.pl">
|
||||
// Copyright (c) 2008 Daniel Dabrowski - 42n. All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Defines the ProfiledSqlServerDataServicesProvider type.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace Four2n.Orchard.MiniProfiler.Data.Providers
|
||||
{
|
||||
using System.Diagnostics;
|
||||
|
||||
using FluentNHibernate.Cfg.Db;
|
||||
|
||||
using global::Orchard.Environment.Extensions;
|
||||
|
||||
[OrchardSuppressDependency("Orchard.Data.Providers.SqlServerDataServicesProvider")]
|
||||
public class ProfiledSqlServerDataServicesProvider : global::Orchard.Data.Providers.SqlServerDataServicesProvider
|
||||
{
|
||||
public ProfiledSqlServerDataServicesProvider(string dataFolder, string connectionString)
|
||||
: base(dataFolder, connectionString)
|
||||
{
|
||||
}
|
||||
|
||||
public static string ProviderName
|
||||
{
|
||||
get { return global::Orchard.Data.Providers.SqlServerDataServicesProvider.ProviderName; }
|
||||
}
|
||||
|
||||
public override IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase)
|
||||
{
|
||||
var persistence = (MsSqlConfiguration)base.GetPersistenceConfigurer(createDatabase);
|
||||
Debug.WriteLine("[Four2n.MiniProfiler] - ProfiledSqlServerDataServicesProvider - GetPersistenceConfigurer ");
|
||||
return persistence.Driver(typeof(ProfiledSqlClientDriver).AssemblyQualifiedName);
|
||||
}
|
||||
}
|
||||
}
|
56
src/Orchard.Web/Modules/Four2n.MiniProfiler/Eventer.cs
Normal file
56
src/Orchard.Web/Modules/Four2n.MiniProfiler/Eventer.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
namespace Four2n.Orchard.MiniProfiler
|
||||
{
|
||||
using System.Diagnostics;
|
||||
|
||||
using global::Orchard.Environment;
|
||||
using global::Orchard.Environment.Extensions.Models;
|
||||
using global::Orchard.Environment.State;
|
||||
|
||||
public class Eventer : IFeatureEventHandler, IShellStateManagerEventHandler
|
||||
{
|
||||
public void Installing(Feature feature)
|
||||
{
|
||||
Debug.WriteLine("Installing");
|
||||
}
|
||||
|
||||
public void Installed(Feature feature)
|
||||
{
|
||||
Debug.WriteLine("Installed");
|
||||
}
|
||||
|
||||
public void Enabling(Feature feature)
|
||||
{
|
||||
Debug.WriteLine("Enabling");
|
||||
}
|
||||
|
||||
public void Enabled(Feature feature)
|
||||
{
|
||||
Debug.WriteLine("Enabled");
|
||||
}
|
||||
|
||||
public void Disabling(Feature feature)
|
||||
{
|
||||
Debug.WriteLine("Disabling");
|
||||
}
|
||||
|
||||
public void Disabled(Feature feature)
|
||||
{
|
||||
Debug.WriteLine("Disabled");
|
||||
}
|
||||
|
||||
public void Uninstalling(Feature feature)
|
||||
{
|
||||
Debug.WriteLine("Uninstalling");
|
||||
}
|
||||
|
||||
public void Uninstalled(Feature feature)
|
||||
{
|
||||
Debug.WriteLine("uninstalled");
|
||||
}
|
||||
|
||||
public void ApplyChanges()
|
||||
{
|
||||
Debug.WriteLine("ApplyChanges");
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,132 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ProfilerFilter.cs" company="Daniel Dabrowski - rod.42n.pl">
|
||||
// Copyright (c) 2008 Daniel Dabrowski - 42n. All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Filter for injecting profiler view code.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace Four2n.Orchard.MiniProfiler.Filters
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
|
||||
using global::Orchard;
|
||||
using global::Orchard.DisplayManagement;
|
||||
using global::Orchard.Mvc.Filters;
|
||||
using global::Orchard.Security;
|
||||
using global::Orchard.UI.Admin;
|
||||
using Four2n.Orchard.MiniProfiler.Services;
|
||||
|
||||
using StackExchange.Profiling;
|
||||
|
||||
/// <summary>
|
||||
/// Filter for injecting profiler view code.
|
||||
/// </summary>
|
||||
public class ProfilerFilter : FilterProvider, IResultFilter, IActionFilter
|
||||
{
|
||||
#region Constants and Fields
|
||||
|
||||
private readonly IAuthorizer authorizer;
|
||||
private readonly dynamic shapeFactory;
|
||||
|
||||
private readonly WorkContext workContext;
|
||||
|
||||
private readonly IProfilerService profiler;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors and Destructors
|
||||
|
||||
public ProfilerFilter(WorkContext workContext, IAuthorizer authorizer, IShapeFactory shapeFactory, IProfilerService profiler)
|
||||
{
|
||||
this.workContext = workContext;
|
||||
this.shapeFactory = shapeFactory;
|
||||
this.authorizer = authorizer;
|
||||
this.profiler = profiler;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public void OnActionExecuted(ActionExecutedContext filterContext)
|
||||
{
|
||||
this.profiler.StepStop(StepKeys.ActionFilter);
|
||||
}
|
||||
|
||||
public void OnActionExecuting(ActionExecutingContext filterContext)
|
||||
{
|
||||
var tokens = filterContext.RouteData.DataTokens;
|
||||
string area = tokens.ContainsKey("area") && !string.IsNullOrEmpty(tokens["area"].ToString()) ?
|
||||
string.Concat(tokens["area"], ".") :
|
||||
string.Empty;
|
||||
string controller = string.Concat(filterContext.Controller.ToString().Split('.').Last(), ".");
|
||||
string action = filterContext.ActionDescriptor.ActionName;
|
||||
this.profiler.StepStart(StepKeys.ActionFilter, "Controller: " + area + controller + action);
|
||||
}
|
||||
|
||||
public void OnResultExecuted(ResultExecutedContext filterContext)
|
||||
{
|
||||
// should only run on a full view rendering result
|
||||
if (!(filterContext.Result is ViewResult))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.IsActivable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.profiler.StepStop(StepKeys.ResultFilter);
|
||||
}
|
||||
|
||||
public void OnResultExecuting(ResultExecutingContext filterContext)
|
||||
{
|
||||
// should only run on a full view rendering result
|
||||
if (!(filterContext.Result is ViewResult))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.IsActivable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var place = this.workContext.Layout.Footer ?? this.workContext.Layout.Head;
|
||||
place.Add(this.shapeFactory.MiniProfilerTemplate());
|
||||
|
||||
this.profiler.StepStart(StepKeys.ResultFilter, string.Format("Result: {0}", filterContext.Result));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
private bool IsActivable()
|
||||
{
|
||||
// activate on front-end only
|
||||
if (AdminFilter.IsApplied(new RequestContext(this.workContext.HttpContext, new RouteData())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// if not logged as a site owner, still activate if it's a local request (development machine)
|
||||
if (!this.authorizer.Authorize(StandardPermissions.SiteOwner))
|
||||
{
|
||||
return this.workContext.HttpContext.Request.IsLocal;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,167 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{CAE8555E-F636-4C97-97A7-A041D3490D28}</ProjectGuid>
|
||||
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Four2n.Orchard.MiniProfiler</RootNamespace>
|
||||
<AssemblyName>Four2n.MiniProfiler</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<MvcBuildViews>false</MvcBuildViews>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
<TargetFrameworkProfile />
|
||||
<UseIISExpress>false</UseIISExpress>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Autofac, Version=2.6.1.841, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\lib\autofac\Autofac.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ClaySharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\lib\claysharp\ClaySharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FluentNHibernate, Version=1.3.0.733, Culture=neutral, PublicKeyToken=8aa435e3cb308880, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\lib\nhibernate\FluentNHibernate.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="MiniProfiler">
|
||||
<HintPath>..\..\lib\MiniProfiler\MiniProfiler.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NHibernate">
|
||||
<HintPath>..\..\..\..\lib\nhibernate\NHibernate.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PoorMansTSqlFormatterLib, Version=1.2.2.36561, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\lib\PoorMansTSqlFormatter\PoorMansTSqlFormatterLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.DynamicData" />
|
||||
<Reference Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Web.Abstractions" />
|
||||
<Reference Include="System.Web.Routing" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Web.config">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<Content Include="Views\Web.config">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<Content Include="Scripts\Web.config" />
|
||||
<Content Include="Styles\Web.config" />
|
||||
<Content Include="Properties\AssemblyInfo.cs" />
|
||||
<Content Include="Module.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ContainerModule.cs" />
|
||||
<Compile Include="Data\PoorMansTSqlFormatter.cs" />
|
||||
<Compile Include="Data\Providers\ProfiledSqlCeDataServicesProvider.cs" />
|
||||
<Compile Include="Data\Providers\ProfiledSqlClientDriver.cs" />
|
||||
<Compile Include="Data\Providers\ProfiledSqlServerCeDriver.cs" />
|
||||
<Compile Include="Data\Providers\ProfiledSqlServerDataServicesProvider.cs" />
|
||||
<Compile Include="Eventer.cs" />
|
||||
<Compile Include="Filters\ProfilerFilter.cs" />
|
||||
<Compile Include="Models\DummyRecord.cs" />
|
||||
<Compile Include="OrchardHostProxyLogger.cs" />
|
||||
<Compile Include="ProfilerStorage.cs" />
|
||||
<Compile Include="Overrides\ContentPartDriverCoordinator.cs" />
|
||||
<Compile Include="Overrides\DefaultContentDisplay.cs" />
|
||||
<Compile Include="Overrides\ProfilingOrchardEventBus.cs" />
|
||||
<Compile Include="Services\IProfilerService.cs" />
|
||||
<Compile Include="Services\ProfilerService.cs" />
|
||||
<Compile Include="ShapeProfiling.cs" />
|
||||
<Compile Include="StepKeys.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\MiniProfilerTemplate.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
|
||||
<Project>{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}</Project>
|
||||
<Name>Orchard.Framework</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Core\Orchard.Core.csproj">
|
||||
<Project>{9916839C-39FC-4CEB-A5AF-89CA7E87119F}</Project>
|
||||
<Name>Orchard.Core</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target> -->
|
||||
<Target Name="AfterBuild" DependsOnTargets="AfterBuildCompiler">
|
||||
<PropertyGroup>
|
||||
<AreasManifestDir>$(ProjectDir)\..\Manifests</AreasManifestDir>
|
||||
</PropertyGroup>
|
||||
<!-- If this is an area child project, uncomment the following line:
|
||||
<CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Child" AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" />
|
||||
-->
|
||||
<!-- If this is an area parent project, uncomment the following lines:
|
||||
<CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Parent" AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" />
|
||||
<CopyAreaManifests ManifestPath="$(AreasManifestDir)" CrossCopy="false" RenameViews="true" />
|
||||
-->
|
||||
</Target>
|
||||
<Target Name="AfterBuildCompiler" Condition="'$(MvcBuildViews)'=='true'">
|
||||
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)\..\$(ProjectName)" />
|
||||
</Target>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||
<WebProjectProperties>
|
||||
<UseIIS>False</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>45979</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>
|
||||
</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>True</UseCustomServer>
|
||||
<CustomServerUrl>http://orchard.codeplex.com</CustomServerUrl>
|
||||
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
|
||||
</WebProjectProperties>
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
@@ -0,0 +1,20 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="DummyRecord.cs" company="Daniel Dabrowski - rod.42n.pl">
|
||||
// Copyright (c) 2008 Daniel Dabrowski - 42n. All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Defines the DummyRecord type.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace Four2n.Orchard.MiniProfiler.Models
|
||||
{
|
||||
using global::Orchard.ContentManagement.Records;
|
||||
|
||||
/// <summary>
|
||||
/// Dummy record for including this module in data configuring.
|
||||
/// </summary>
|
||||
//public class DummyRecord : ContentPartRecord
|
||||
//{
|
||||
//}
|
||||
}
|
13
src/Orchard.Web/Modules/Four2n.MiniProfiler/Module.txt
Normal file
13
src/Orchard.Web/Modules/Four2n.MiniProfiler/Module.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
Name: Mini Profiler
|
||||
AntiForgery: enabled
|
||||
Author: 42n, Daniel Dabrowski
|
||||
Website: http://orchardprofiler.codeplex.com/
|
||||
Version: 0.4
|
||||
OrchardVersion: 1.4
|
||||
Description: Module which delivers profiler functionality.
|
||||
Mvc Mini profiler (http://code.google.com/p/mvc-mini-profiler/) is used for collecting profile data.
|
||||
Poor Man's T-SQL Formatter (http://www.architectshack.com/PoorMansTSqlFormatter.ashx) is used for nicer SQL timing format. Source code is hosted on GitHub (https://github.com/TaoK/PoorMansTSqlFormatter)
|
||||
|
||||
FeatureDescription: Profiling web site using mvc mini profiler.
|
||||
Category: Developer
|
||||
Tags: Profiler, Profiling, mvc-mini-profiler
|
@@ -0,0 +1,52 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="OrchardHostProxyLogger.cs" company="Daniel Dabrowski - rod.42n.pl">
|
||||
// Copyright (c) 2008 Daniel Dabrowski - 42n. All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Defines the OrchardHostProxyLogger type.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace Four2n.Orchard.MiniProfiler
|
||||
{
|
||||
using System;
|
||||
|
||||
using global::Orchard.Logging;
|
||||
|
||||
using StackExchange.Profiling;
|
||||
|
||||
public class OrchardHostProxyLogger : ILogger
|
||||
{
|
||||
private readonly ILogger logger;
|
||||
|
||||
public OrchardHostProxyLogger(ILogger logger)
|
||||
{
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public bool IsEnabled(LogLevel level)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Log(LogLevel level, Exception exception, string format, params object[] args)
|
||||
{
|
||||
if (level == LogLevel.Debug)
|
||||
{
|
||||
if ("BeginRequest".Equals(format))
|
||||
{
|
||||
MiniProfiler.Start(ProfileLevel.Verbose);
|
||||
}
|
||||
else if ("EndRequest".Equals(format))
|
||||
{
|
||||
MiniProfiler.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.logger.IsEnabled(level))
|
||||
{
|
||||
this.logger.Log(level, exception, format, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,109 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Four2n.Orchard.MiniProfiler.Services;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard;
|
||||
using System;
|
||||
|
||||
namespace Four2n.MiniProfilter.Overrides {
|
||||
[OrchardSuppressDependency("Orchard.ContentManagement.Drivers.Coordinators.ContentPartDriverCoordinator")]
|
||||
public class ProfilingContentPartDriverCoordinator : ContentHandlerBase {
|
||||
private readonly IEnumerable<IContentPartDriver> _drivers;
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
private readonly IProfilerService _profiler;
|
||||
|
||||
public ProfilingContentPartDriverCoordinator(IEnumerable<IContentPartDriver> drivers, IContentDefinitionManager contentDefinitionManager, IProfilerService profiler) {
|
||||
_drivers = drivers;
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
Logger = NullLogger.Instance;
|
||||
_profiler = profiler;
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public override void Activating(ActivatingContentContext context) {
|
||||
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentType);
|
||||
if (contentTypeDefinition == null)
|
||||
return;
|
||||
|
||||
var partInfos = _drivers.SelectMany(cpp => cpp.GetPartInfo());
|
||||
|
||||
foreach (var typePartDefinition in contentTypeDefinition.Parts) {
|
||||
var partName = typePartDefinition.PartDefinition.Name;
|
||||
var partInfo = partInfos.FirstOrDefault(pi => pi.PartName == partName);
|
||||
var part = partInfo != null
|
||||
? partInfo.Factory(typePartDefinition)
|
||||
: new ContentPart { TypePartDefinition = typePartDefinition };
|
||||
context.Builder.Weld(part);
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetContentItemMetadata(GetContentItemMetadataContext context) {
|
||||
_drivers.Invoke(driver => driver.GetContentItemMetadata(context), Logger);
|
||||
}
|
||||
|
||||
public override void BuildDisplay(BuildDisplayContext context) {
|
||||
_drivers.Invoke(driver => {
|
||||
var key = "Driver:"+driver.GetType().FullName;
|
||||
_profiler.StepStart(key, String.Format("ContentPartDriver: {0}", driver.GetType().FullName));
|
||||
var result = driver.BuildDisplay(context);
|
||||
|
||||
if (result != null) {
|
||||
var key2 = "DriverApply:" + driver.GetType().FullName;
|
||||
_profiler.StepStart(key2, String.Format("ApplyDriver", driver.GetType().FullName));
|
||||
result.Apply(context);
|
||||
_profiler.StepStop(key2);
|
||||
}
|
||||
|
||||
_profiler.StepStop(key);
|
||||
|
||||
}, Logger);
|
||||
}
|
||||
|
||||
public override void BuildEditor(BuildEditorContext context) {
|
||||
_drivers.Invoke(driver => {
|
||||
var result = driver.BuildEditor(context);
|
||||
if (result != null)
|
||||
result.Apply(context);
|
||||
}, Logger);
|
||||
}
|
||||
|
||||
public override void UpdateEditor(UpdateEditorContext context) {
|
||||
_drivers.Invoke(driver => {
|
||||
var result = driver.UpdateEditor(context);
|
||||
if (result != null)
|
||||
result.Apply(context);
|
||||
}, Logger);
|
||||
}
|
||||
|
||||
public override void Importing(ImportContentContext context) {
|
||||
foreach (var contentPartDriver in _drivers) {
|
||||
contentPartDriver.Importing(context);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Imported(ImportContentContext context) {
|
||||
foreach (var contentPartDriver in _drivers) {
|
||||
contentPartDriver.Imported(context);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Exporting(ExportContentContext context) {
|
||||
foreach (var contentPartDriver in _drivers) {
|
||||
contentPartDriver.Exporting(context);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Exported(ExportContentContext context) {
|
||||
foreach (var contentPartDriver in _drivers) {
|
||||
contentPartDriver.Exported(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
using ClaySharp.Implementation;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.DisplayManagement.Descriptors;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
using Orchard.Logging;
|
||||
using Orchard.UI.Zones;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Four2n.Orchard.MiniProfiler.Services;
|
||||
|
||||
namespace Orchard.ContentManagement {
|
||||
[OrchardSuppressDependency("Orchard.ContentManagement.DefaultContentDisplay")]
|
||||
public class ProfilingContentDisplay : IContentDisplay {
|
||||
private readonly Lazy<IEnumerable<IContentHandler>> _handlers;
|
||||
private readonly IShapeFactory _shapeFactory;
|
||||
private readonly Lazy<IShapeTableLocator> _shapeTableLocator;
|
||||
|
||||
private readonly RequestContext _requestContext;
|
||||
private readonly IVirtualPathProvider _virtualPathProvider;
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IProfilerService _profiler;
|
||||
public ProfilingContentDisplay(
|
||||
Lazy<IEnumerable<IContentHandler>> handlers,
|
||||
IShapeFactory shapeFactory,
|
||||
Lazy<IShapeTableLocator> shapeTableLocator,
|
||||
RequestContext requestContext,
|
||||
IVirtualPathProvider virtualPathProvider,
|
||||
IWorkContextAccessor workContextAccessor,
|
||||
IProfilerService profiler) {
|
||||
|
||||
_handlers = handlers;
|
||||
_shapeFactory = shapeFactory;
|
||||
_shapeTableLocator = shapeTableLocator;
|
||||
_requestContext = requestContext;
|
||||
_virtualPathProvider = virtualPathProvider;
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_profiler = profiler;
|
||||
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public dynamic BuildDisplay(IContent content, string displayType, string groupId) {
|
||||
var contentKey = "ContentDisplay:" + content.Id.ToString();
|
||||
_profiler.StepStart(contentKey, String.Format("Content Display: {0} ({1})", content.Id, displayType));
|
||||
var contentTypeDefinition = content.ContentItem.TypeDefinition;
|
||||
string stereotype;
|
||||
if (!contentTypeDefinition.Settings.TryGetValue("Stereotype", out stereotype))
|
||||
stereotype = "Content";
|
||||
|
||||
var actualShapeType = stereotype;
|
||||
var actualDisplayType = string.IsNullOrWhiteSpace(displayType) ? "Detail" : displayType;
|
||||
|
||||
dynamic itemShape = CreateItemShape(actualShapeType);
|
||||
itemShape.ContentItem = content.ContentItem;
|
||||
itemShape.Metadata.DisplayType = actualDisplayType;
|
||||
|
||||
var context = new BuildDisplayContext(itemShape, content, actualDisplayType, groupId, _shapeFactory);
|
||||
BindPlacement(context, actualDisplayType, stereotype);
|
||||
|
||||
_handlers.Value.Invoke(handler => {
|
||||
var key = String.Format("ContentDisplay:{0}:{1}", content.Id, handler.GetType().FullName);
|
||||
_profiler.StepStart(key, String.Format("Content Display: {0}", handler.GetType().FullName));
|
||||
handler.BuildDisplay(context);
|
||||
_profiler.StepStop(key);
|
||||
}, Logger);
|
||||
_profiler.StepStop(contentKey);
|
||||
return context.Shape;
|
||||
}
|
||||
|
||||
public dynamic BuildEditor(IContent content, string groupId) {
|
||||
var contentKey = "ContentEditor:" + content.Id.ToString();
|
||||
_profiler.StepStart(contentKey, String.Format("Content Editor: {0}", content.Id));
|
||||
var contentTypeDefinition = content.ContentItem.TypeDefinition;
|
||||
string stereotype;
|
||||
if (!contentTypeDefinition.Settings.TryGetValue("Stereotype", out stereotype))
|
||||
stereotype = "Content";
|
||||
|
||||
var actualShapeType = stereotype + "_Edit";
|
||||
|
||||
dynamic itemShape = CreateItemShape(actualShapeType);
|
||||
itemShape.ContentItem = content.ContentItem;
|
||||
|
||||
var context = new BuildEditorContext(itemShape, content, groupId, _shapeFactory);
|
||||
BindPlacement(context, null, stereotype);
|
||||
|
||||
_handlers.Value.Invoke(handler => {
|
||||
var key = String.Format("ContentEditor:{0}:{1}", content.Id, handler.GetType().FullName);
|
||||
_profiler.StepStart(key, String.Format("Content Editor: {0}", content.Id));
|
||||
handler.BuildEditor(context);
|
||||
_profiler.StepStop(key);
|
||||
}
|
||||
, Logger);
|
||||
|
||||
_profiler.StepStop(contentKey);
|
||||
return context.Shape;
|
||||
}
|
||||
|
||||
public dynamic UpdateEditor(IContent content, IUpdateModel updater, string groupInfoId) {
|
||||
var contentKey = "ContentUpdate:" + content.Id.ToString();
|
||||
_profiler.StepStart(contentKey, String.Format("Content Update: {0}", content.Id));
|
||||
var contentTypeDefinition = content.ContentItem.TypeDefinition;
|
||||
string stereotype;
|
||||
if (!contentTypeDefinition.Settings.TryGetValue("Stereotype", out stereotype))
|
||||
stereotype = "Content";
|
||||
|
||||
var actualShapeType = stereotype + "_Edit";
|
||||
|
||||
dynamic itemShape = CreateItemShape(actualShapeType);
|
||||
itemShape.ContentItem = content.ContentItem;
|
||||
|
||||
var theme = _workContextAccessor.GetContext().CurrentTheme;
|
||||
var shapeTable = _shapeTableLocator.Value.Lookup(theme.Id);
|
||||
|
||||
var context = new UpdateEditorContext(itemShape, content, updater, groupInfoId, _shapeFactory, shapeTable);
|
||||
BindPlacement(context, null, stereotype);
|
||||
|
||||
_handlers.Value.Invoke(handler => {
|
||||
var key = String.Format("ContentUpdate:{0}:{1}", content.Id, handler.GetType().FullName);
|
||||
_profiler.StepStart(key, String.Format("Content Update: {0}", handler.GetType().FullName));
|
||||
handler.UpdateEditor(context);
|
||||
_profiler.StepStop(key);
|
||||
|
||||
}, Logger);
|
||||
|
||||
_profiler.StepStop(contentKey);
|
||||
return context.Shape;
|
||||
}
|
||||
|
||||
private dynamic CreateItemShape(string actualShapeType) {
|
||||
Func<dynamic> call = () => _shapeFactory.Create("ContentZone", Arguments.Empty());
|
||||
var zoneHoldingBehavior = new ZoneHoldingBehavior(call, _workContextAccessor.GetContext().Layout);
|
||||
return _shapeFactory.Create(actualShapeType, Arguments.Empty(), new[] { zoneHoldingBehavior });
|
||||
}
|
||||
|
||||
private void BindPlacement(BuildShapeContext context, string displayType, string stereotype) {
|
||||
context.FindPlacement = (partShapeType, differentiator, defaultLocation) => {
|
||||
|
||||
var workContext = _workContextAccessor.GetContext(_requestContext.HttpContext);
|
||||
|
||||
var theme = workContext.CurrentTheme;
|
||||
var shapeTable = _shapeTableLocator.Value.Lookup(theme.Id);
|
||||
|
||||
var request = _requestContext.HttpContext.Request;
|
||||
|
||||
ShapeDescriptor descriptor;
|
||||
if (shapeTable.Descriptors.TryGetValue(partShapeType, out descriptor)) {
|
||||
var placementContext = new ShapePlacementContext {
|
||||
ContentType = context.ContentItem.ContentType,
|
||||
Stereotype = stereotype,
|
||||
DisplayType = displayType,
|
||||
Differentiator = differentiator,
|
||||
Path = VirtualPathUtility.AppendTrailingSlash(_virtualPathProvider.ToAppRelative(request.Path)) // get the current app-relative path, i.e. ~/my-blog/foo
|
||||
};
|
||||
|
||||
// define which location should be used if none placement is hit
|
||||
descriptor.DefaultPlacement = defaultLocation;
|
||||
|
||||
var placement = descriptor.Placement(placementContext);
|
||||
if (placement != null) {
|
||||
placement.Source = placementContext.Source;
|
||||
return placement;
|
||||
}
|
||||
}
|
||||
|
||||
return new PlacementInfo {
|
||||
Location = defaultLocation,
|
||||
Source = String.Empty
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,135 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Orchard.Exceptions;
|
||||
using Orchard.Localization;
|
||||
|
||||
using Orchard.Events;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Four2n.Orchard.MiniProfiler.Services;
|
||||
|
||||
namespace Four2n.Orchard.MiniProfiler.Overrides {
|
||||
[OrchardSuppressDependency("Orchard.Events.DefaultOrchardEventBus")]
|
||||
public class DefaultOrchardEventBus : IEventBus {
|
||||
private readonly Func<IEnumerable<IEventHandler>> _eventHandlers;
|
||||
private readonly IExceptionPolicy _exceptionPolicy;
|
||||
private static readonly ConcurrentDictionary<string, MethodInfo> _interfaceMethodsCache = new ConcurrentDictionary<string, MethodInfo>();
|
||||
private readonly IProfilerService _profiler;
|
||||
public DefaultOrchardEventBus(Func<IEnumerable<IEventHandler>> eventHandlers, IExceptionPolicy exceptionPolicy, IProfilerService profiler) {
|
||||
_eventHandlers = eventHandlers;
|
||||
_exceptionPolicy = exceptionPolicy;
|
||||
_profiler = profiler;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
|
||||
public IEnumerable Notify(string messageName, IDictionary<string, object> eventData) {
|
||||
// NOTE: We can't profile everything because EventsInterceptor performs some work that's a bit harder to profile without forking or getting our
|
||||
// own interceptor working...
|
||||
_profiler.StepStart("EventBusNotify","EventBus: "+messageName);
|
||||
// call ToArray to ensure evaluation has taken place
|
||||
var result = NotifyHandlers(messageName, eventData).ToArray();
|
||||
_profiler.StepStop("EventBusNotify");
|
||||
return result;
|
||||
}
|
||||
|
||||
private IEnumerable<object> NotifyHandlers(string messageName, IDictionary<string, object> eventData) {
|
||||
string[] parameters = messageName.Split('.');
|
||||
if (parameters.Length != 2) {
|
||||
throw new ArgumentException(T("{0} is not formatted correctly", messageName).Text);
|
||||
}
|
||||
string interfaceName = parameters[0];
|
||||
string methodName = parameters[1];
|
||||
|
||||
var eventHandlers = _eventHandlers();
|
||||
foreach (var eventHandler in eventHandlers) {
|
||||
IEnumerable returnValue;
|
||||
if (TryNotifyHandler(eventHandler, messageName, interfaceName, methodName, eventData, out returnValue)) {
|
||||
if (returnValue != null) {
|
||||
foreach (var value in returnValue) {
|
||||
yield return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryNotifyHandler(IEventHandler eventHandler, string messageName, string interfaceName, string methodName, IDictionary<string, object> eventData, out IEnumerable returnValue) {
|
||||
try {
|
||||
return TryInvoke(eventHandler, interfaceName, methodName, eventData, out returnValue, _profiler);
|
||||
}
|
||||
catch (Exception exception) {
|
||||
if (!_exceptionPolicy.HandleException(this, exception)) {
|
||||
throw;
|
||||
}
|
||||
|
||||
returnValue = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryInvoke(IEventHandler eventHandler, string interfaceName, string methodName, IDictionary<string, object> arguments, out IEnumerable returnValue, IProfilerService profiler) {
|
||||
Type type = eventHandler.GetType();
|
||||
foreach (var interfaceType in type.GetInterfaces()) {
|
||||
if (String.Equals(interfaceType.Name, interfaceName, StringComparison.OrdinalIgnoreCase)) {
|
||||
return TryInvokeMethod(eventHandler, interfaceType, methodName, arguments, out returnValue, profiler);
|
||||
}
|
||||
}
|
||||
returnValue = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool TryInvokeMethod(IEventHandler eventHandler, Type interfaceType, string methodName, IDictionary<string, object> arguments, out IEnumerable returnValue, IProfilerService profiler) {
|
||||
MethodInfo method = _interfaceMethodsCache.GetOrAdd(String.Concat(eventHandler.GetType().Name + "_" + interfaceType.Name, "_", methodName, "_", String.Join("_", arguments.Keys)), GetMatchingMethod(eventHandler, interfaceType, methodName, arguments));
|
||||
|
||||
if (method != null) {
|
||||
var parameters = new List<object>();
|
||||
foreach (var methodParameter in method.GetParameters()) {
|
||||
parameters.Add(arguments[methodParameter.Name]);
|
||||
}
|
||||
var key= "EventBus:"+eventHandler.GetType().FullName +"."+ methodName;
|
||||
profiler.StepStart(key,String.Format("EventBus: {0}",eventHandler.GetType().FullName +"."+ methodName),true);
|
||||
var result = method.Invoke(eventHandler, parameters.ToArray());
|
||||
profiler.StepStop(key);
|
||||
returnValue = result as IEnumerable;
|
||||
if (returnValue == null && result != null)
|
||||
returnValue = new[] { result };
|
||||
return true;
|
||||
}
|
||||
returnValue = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static MethodInfo GetMatchingMethod(IEventHandler eventHandler, Type interfaceType, string methodName, IDictionary<string, object> arguments) {
|
||||
var allMethods = new List<MethodInfo>(interfaceType.GetMethods());
|
||||
var candidates = new List<MethodInfo>(allMethods);
|
||||
|
||||
foreach (var method in allMethods) {
|
||||
if (String.Equals(method.Name, methodName, StringComparison.OrdinalIgnoreCase)) {
|
||||
ParameterInfo[] parameterInfos = method.GetParameters();
|
||||
foreach (var parameter in parameterInfos) {
|
||||
if (!arguments.ContainsKey(parameter.Name)) {
|
||||
candidates.Remove(method);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
candidates.Remove(method);
|
||||
}
|
||||
}
|
||||
|
||||
if (candidates.Count != 0) {
|
||||
return candidates.OrderBy(x => x.GetParameters().Length).Last();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
157
src/Orchard.Web/Modules/Four2n.MiniProfiler/ProfilerStorage.cs
Normal file
157
src/Orchard.Web/Modules/Four2n.MiniProfiler/ProfilerStorage.cs
Normal file
@@ -0,0 +1,157 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ProfilerStorage.cs" company="Daniel Dabrowski - rod.42n.pl">
|
||||
// Copyright (c) 2008 Daniel Dabrowski - 42n. All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace Four2n.Orchard.MiniProfiler
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Web;
|
||||
|
||||
using StackExchange.Profiling;
|
||||
using StackExchange.Profiling.Storage;
|
||||
|
||||
public class ProfilerStorage : IStorage
|
||||
{
|
||||
/// <summary>
|
||||
/// The string that prefixes all keys that MiniProfilers are saved under, e.g.
|
||||
/// "mini-profiler-ecfb0050-7ce8-4bf1-bf82-2cb38e90e31e".
|
||||
/// </summary>
|
||||
public const string CacheKeyPrefix = "mini-profiler-";
|
||||
|
||||
/// <summary>
|
||||
/// How long to cache each <see cref="MiniProfiler"/> for (i.e. the absolute expiration parameter of
|
||||
/// <see cref="System.Web.Caching.Cache.Insert(string, object, System.Web.Caching.CacheDependency, System.DateTime, System.TimeSpan, System.Web.Caching.CacheItemUpdateCallback)"/>)
|
||||
/// </summary>
|
||||
public TimeSpan CacheDuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new HttpRuntimeCacheStorage class that will cache MiniProfilers for the specified duration.
|
||||
/// </summary>
|
||||
public ProfilerStorage(TimeSpan cacheDuration)
|
||||
{
|
||||
CacheDuration = cacheDuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves <paramref name="profiler"/> to the HttpRuntime.Cache under a key concated with <see cref="CacheKeyPrefix"/>
|
||||
/// and the parameter's <see cref="MiniProfiler.Id"/>.
|
||||
/// </summary>
|
||||
public void Save(MiniProfiler profiler)
|
||||
{
|
||||
InsertIntoCache(GetCacheKey(profiler.Id), profiler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// remembers we did not view the profile
|
||||
/// </summary>
|
||||
public void SetUnviewed(string user, Guid id)
|
||||
{
|
||||
var ids = GetPerUserUnviewedIds(user);
|
||||
lock (ids)
|
||||
{
|
||||
if (!ids.Contains(id))
|
||||
{
|
||||
ids.Add(id);
|
||||
if (ids.Count > 20)
|
||||
{
|
||||
ids.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the profile to viewed for this user
|
||||
/// </summary>
|
||||
public void SetViewed(string user, Guid id)
|
||||
{
|
||||
var ids = GetPerUserUnviewedIds(user);
|
||||
|
||||
lock (ids)
|
||||
{
|
||||
ids.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the saved <see cref="MiniProfiler"/> identified by <paramref name="id"/>. Also marks the resulting
|
||||
/// profiler <see cref="MiniProfiler.HasUserViewed"/> to true.
|
||||
/// </summary>
|
||||
public MiniProfiler Load(Guid id)
|
||||
{
|
||||
var result = HttpRuntime.Cache[GetCacheKey(id)] as MiniProfiler;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of <see cref="MiniProfiler.Id"/>s that haven't been seen by <paramref name="user"/>.
|
||||
/// </summary>
|
||||
/// <param name="user">User identified by the current <see cref="MiniProfiler.Settings.UserProvider"/>.</param>
|
||||
public List<Guid> GetUnviewedIds(string user)
|
||||
{
|
||||
var ids = GetPerUserUnviewedIds(user);
|
||||
lock (ids)
|
||||
{
|
||||
return new List<Guid>(ids);
|
||||
}
|
||||
}
|
||||
|
||||
private void InsertIntoCache(string key, object value)
|
||||
{
|
||||
// use insert instead of add; add fails if the item already exists
|
||||
HttpRuntime.Cache.Insert(
|
||||
key: key,
|
||||
value: value,
|
||||
dependencies: null,
|
||||
absoluteExpiration: DateTime.Now.Add(CacheDuration), // servers will cache based on local now
|
||||
slidingExpiration: System.Web.Caching.Cache.NoSlidingExpiration,
|
||||
priority: System.Web.Caching.CacheItemPriority.Low,
|
||||
onRemoveCallback: null);
|
||||
}
|
||||
|
||||
private string GetCacheKey(Guid id)
|
||||
{
|
||||
return CacheKeyPrefix + id;
|
||||
}
|
||||
|
||||
private string GetPerUserUnviewedCacheKey(string user)
|
||||
{
|
||||
return CacheKeyPrefix + "unviewed-for-user-" + user;
|
||||
}
|
||||
|
||||
private List<Guid> GetPerUserUnviewedIds(MiniProfiler profiler)
|
||||
{
|
||||
return GetPerUserUnviewedIds(profiler.User);
|
||||
}
|
||||
|
||||
private List<Guid> GetPerUserUnviewedIds(string user)
|
||||
{
|
||||
var key = GetPerUserUnviewedCacheKey(user);
|
||||
var result = HttpRuntime.Cache[key] as List<Guid>;
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
lock (AddPerUserUnviewedIdsLock)
|
||||
{
|
||||
// check again, as we could have been waiting
|
||||
result = HttpRuntime.Cache[key] as List<Guid>;
|
||||
if (result == null)
|
||||
{
|
||||
result = new List<Guid>();
|
||||
InsertIntoCache(key, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Syncs access to runtime cache when adding a new list of ids for a user.
|
||||
/// </summary>
|
||||
private static readonly object AddPerUserUnviewedIdsLock = new object();
|
||||
}
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Four2n.MiniProfiler")]
|
||||
[assembly: AssemblyDescription("MiniProfiler Orchard Module")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyProduct("MiniProfiler")]
|
||||
[assembly: AssemblyCopyright("Copyright (c) 2008 Daniel Dabrowski - 42n. All rights reserved.")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("f15f52be-3cad-4c2e-9a91-8ec5ee8b4df2")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("0.4.0.*")]
|
||||
[assembly: AssemblyFileVersion("0.4.0.*")]
|
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
</appSettings>
|
||||
<system.web>
|
||||
<httpHandlers>
|
||||
<!-- iis6 - for any request in this location, return via managed static file handler -->
|
||||
<add path="*" verb="*" type="System.Web.StaticFileHandler" />
|
||||
</httpHandlers>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<handlers accessPolicy="Script,Read">
|
||||
<!--
|
||||
iis7 - for any request to a file exists on disk, return it via native http module.
|
||||
accessPolicy 'Script' is to allow for a managed 404 page.
|
||||
-->
|
||||
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
@@ -0,0 +1,20 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="IProfilerService.cs" company="Daniel Dabrowski - rod.42n.pl">
|
||||
// Copyright (c) 2008 Daniel Dabrowski - 42n. All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Defines the IProfilerService type.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace Four2n.Orchard.MiniProfiler.Services
|
||||
{
|
||||
using global::Orchard;
|
||||
|
||||
public interface IProfilerService : IDependency
|
||||
{
|
||||
void StepStart(string key, string message, bool isVerbose = false);
|
||||
|
||||
void StepStop(string key);
|
||||
}
|
||||
}
|
@@ -0,0 +1,83 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ProfilerService.cs" company="Daniel Dabrowski - rod.42n.pl">
|
||||
// Copyright (c) 2008 Daniel Dabrowski - 42n. All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Defines the ProfilerService type.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace Four2n.Orchard.MiniProfiler.Services
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
|
||||
using StackExchange.Profiling;
|
||||
|
||||
public class ProfilerService : IProfilerService, IDisposable
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, ConcurrentStack<IDisposable>> steps = new ConcurrentDictionary<string, ConcurrentStack<IDisposable>>();
|
||||
|
||||
private MiniProfiler profiler;
|
||||
|
||||
public ProfilerService()
|
||||
{
|
||||
this.profiler = MiniProfiler.Current;
|
||||
}
|
||||
|
||||
protected MiniProfiler Profiler
|
||||
{
|
||||
get
|
||||
{
|
||||
// The event bus starts in a different scope where there's no MiniProfiler.Current, set it now
|
||||
return this.profiler ?? (this.profiler = MiniProfiler.Current);
|
||||
}
|
||||
}
|
||||
|
||||
public void StepStart(string key, string message, bool isVerbose = false)
|
||||
{
|
||||
if (this.Profiler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var stack = this.steps.GetOrAdd(key, k => new ConcurrentStack<IDisposable>());
|
||||
var step = this.Profiler.Step(message, isVerbose ? ProfileLevel.Verbose : ProfileLevel.Info);
|
||||
stack.Push(step);
|
||||
}
|
||||
|
||||
public void StepStop(string key)
|
||||
{
|
||||
if (this.Profiler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IDisposable step;
|
||||
if (this.steps[key].TryPop(out step))
|
||||
{
|
||||
step.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopAll()
|
||||
{
|
||||
// Dispose any orphaned steps
|
||||
foreach (var stack in this.steps.Values)
|
||||
{
|
||||
IDisposable step;
|
||||
while (stack.TryPop(out step))
|
||||
{
|
||||
step.Dispose();
|
||||
Debug.WriteLine("[Four2n.MiniProfiler] - ProfilerService - StopAll There is some left");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.StopAll();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,93 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ShapeProfiling.cs" company="Daniel Dabrowski - rod.42n.pl">
|
||||
// Copyright (c) 2008 Daniel Dabrowski - 42n. All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Defines the ShapeProfiling type.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace Four2n.Orchard.MiniProfiler
|
||||
{
|
||||
using Four2n.Orchard.MiniProfiler.Services;
|
||||
|
||||
using global::Orchard.ContentManagement;
|
||||
|
||||
using global::Orchard.DisplayManagement.Implementation;
|
||||
|
||||
using global::Orchard.DisplayManagement.Shapes;
|
||||
|
||||
public class ShapeProfiling : IShapeFactoryEvents
|
||||
{
|
||||
private readonly IProfilerService profiler;
|
||||
|
||||
public ShapeProfiling(IProfilerService profiler)
|
||||
{
|
||||
this.profiler = profiler;
|
||||
}
|
||||
|
||||
public void Creating(ShapeCreatingContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void Created(ShapeCreatedContext context)
|
||||
{
|
||||
var shapeMetadata = (ShapeMetadata)context.Shape.Metadata;
|
||||
/*
|
||||
if (shapeMetadata.Type.Equals("Zone") || context.Shape.ContentItem == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
shapeMetadata.OnDisplaying(this.OnDisplaying);
|
||||
shapeMetadata.OnDisplayed(this.OnDisplayed);
|
||||
}
|
||||
|
||||
public void Displaying(ShapeDisplayingContext context)
|
||||
{
|
||||
if (context.ShapeMetadata.Type.Equals("Zone"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.profiler.StepStart(StepKeys.ShapeProfiling, context.ShapeMetadata.Type + " - Display");
|
||||
}
|
||||
|
||||
public void Displayed(ShapeDisplayedContext context)
|
||||
{
|
||||
if (context.ShapeMetadata.Type.Equals("Zone"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.profiler.StepStop(StepKeys.ShapeProfiling);
|
||||
}
|
||||
|
||||
public void OnDisplaying(ShapeDisplayingContext context)
|
||||
{
|
||||
IContent content = null;
|
||||
if (context.Shape.ContentItem != null)
|
||||
{
|
||||
content = context.Shape.ContentItem;
|
||||
}
|
||||
else if (context.Shape.ContentPart != null)
|
||||
{
|
||||
content = context.Shape.ContentPart;
|
||||
}
|
||||
|
||||
var message = string.Format(
|
||||
"Shape Display: {0} ({1}) ({2})",
|
||||
context.ShapeMetadata.Type,
|
||||
context.ShapeMetadata.DisplayType,
|
||||
(string)(content != null ? content.ContentItem.ContentType : "non-content"));
|
||||
|
||||
this.profiler.StepStart(StepKeys.ShapeProfiling, message, true);
|
||||
}
|
||||
|
||||
public void OnDisplayed(ShapeDisplayedContext context)
|
||||
{
|
||||
this.profiler.StepStop(StepKeys.ShapeProfiling);
|
||||
}
|
||||
}
|
||||
}
|
20
src/Orchard.Web/Modules/Four2n.MiniProfiler/StepKeys.cs
Normal file
20
src/Orchard.Web/Modules/Four2n.MiniProfiler/StepKeys.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="StepKeys.cs" company="Daniel Dabrowski - rod.42n.pl">
|
||||
// Copyright (c) 2008 Daniel Dabrowski - 42n. All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Defines the StepKeys type.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace Four2n.Orchard.MiniProfiler
|
||||
{
|
||||
public class StepKeys
|
||||
{
|
||||
public const string ActionFilter = "ActionFilter";
|
||||
|
||||
public const string ResultFilter = "ResultFilter";
|
||||
|
||||
public const string ShapeProfiling = "ShapeProfiling";
|
||||
}
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
</appSettings>
|
||||
<system.web>
|
||||
<httpHandlers>
|
||||
<!-- iis6 - for any request in this location, return via managed static file handler -->
|
||||
<add path="*" verb="*" type="System.Web.StaticFileHandler" />
|
||||
</httpHandlers>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<handlers accessPolicy="Script,Read">
|
||||
<!--
|
||||
iis7 - for any request to a file exists on disk, return it via native http module.
|
||||
accessPolicy 'Script' is to allow for a managed 404 page.
|
||||
-->
|
||||
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
@@ -0,0 +1,4 @@
|
||||
@{
|
||||
Script.Require("jQuery");
|
||||
}
|
||||
@StackExchange.Profiling.MiniProfiler.RenderIncludes(xhtml: true, showControls: true)
|
41
src/Orchard.Web/Modules/Four2n.MiniProfiler/Views/Web.config
Normal file
41
src/Orchard.Web/Modules/Four2n.MiniProfiler/Views/Web.config
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
</appSettings>
|
||||
<system.web>
|
||||
<httpHandlers>
|
||||
</httpHandlers>
|
||||
|
||||
<!--
|
||||
Enabling request validation in view pages would cause validation to occur
|
||||
after the input has already been processed by the controller. By default
|
||||
MVC performs request validation before a controller processes the input.
|
||||
To change this behavior apply the ValidateInputAttribute to a
|
||||
controller or action.
|
||||
-->
|
||||
<pages
|
||||
validateRequest="false"
|
||||
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"
|
||||
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"
|
||||
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<controls>
|
||||
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" namespace="System.Web.Mvc" tagPrefix="mvc" />
|
||||
</controls>
|
||||
</pages>
|
||||
</system.web>
|
||||
|
||||
<system.webServer>
|
||||
<validation validateIntegratedModeConfiguration="false"/>
|
||||
<handlers>
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="2.0.0.0" newVersion="3.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
40
src/Orchard.Web/Modules/Four2n.MiniProfiler/Web.config
Normal file
40
src/Orchard.Web/Modules/Four2n.MiniProfiler/Web.config
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
|
||||
<configSections>
|
||||
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<remove name="host" />
|
||||
<remove name="pages" />
|
||||
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
|
||||
<pages pageBaseType="Orchard.Mvc.ViewEngines.Razor.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="System.Web.Mvc" />
|
||||
<add namespace="System.Web.Mvc.Ajax" />
|
||||
<add namespace="System.Web.Mvc.Html" />
|
||||
<add namespace="System.Web.Routing" />
|
||||
<add namespace="System.Linq"/>
|
||||
<add namespace="System.Collections.Generic"/>
|
||||
<add namespace="Orchard.Mvc.Html"/>
|
||||
</namespaces>
|
||||
</pages>
|
||||
</system.web.webPages.razor>
|
||||
|
||||
<system.web>
|
||||
<compilation targetFramework="4.0">
|
||||
<assemblies>
|
||||
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
|
||||
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
|
||||
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
|
||||
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
|
||||
<add assembly="MiniProfiler"/>
|
||||
</assemblies>
|
||||
</compilation>
|
||||
</system.web>
|
||||
|
||||
</configuration>
|
@@ -148,6 +148,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.ContentPicker", "Or
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.ContentPermissions", "Orchard.Web\Modules\Orchard.ContentPermissions\Orchard.ContentPermissions.csproj", "{E826F796-8CE3-4B5B-8423-5AA5F81D2FC3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Four2n.MiniProfiler", "Orchard.Web\Modules\Four2n.MiniProfiler\Four2n.MiniProfiler.csproj", "{CAE8555E-F636-4C97-97A7-A041D3490D28}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
CodeCoverage|Any CPU = CodeCoverage|Any CPU
|
||||
@@ -805,6 +807,16 @@ Global
|
||||
{E826F796-8CE3-4B5B-8423-5AA5F81D2FC3}.FxCop|Any CPU.Build.0 = Release|Any CPU
|
||||
{E826F796-8CE3-4B5B-8423-5AA5F81D2FC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E826F796-8CE3-4B5B-8423-5AA5F81D2FC3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CAE8555E-F636-4C97-97A7-A041D3490D28}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CAE8555E-F636-4C97-97A7-A041D3490D28}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{CAE8555E-F636-4C97-97A7-A041D3490D28}.Coverage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CAE8555E-F636-4C97-97A7-A041D3490D28}.Coverage|Any CPU.Build.0 = Release|Any CPU
|
||||
{CAE8555E-F636-4C97-97A7-A041D3490D28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CAE8555E-F636-4C97-97A7-A041D3490D28}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CAE8555E-F636-4C97-97A7-A041D3490D28}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CAE8555E-F636-4C97-97A7-A041D3490D28}.FxCop|Any CPU.Build.0 = Release|Any CPU
|
||||
{CAE8555E-F636-4C97-97A7-A041D3490D28}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CAE8555E-F636-4C97-97A7-A041D3490D28}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -858,6 +870,7 @@ Global
|
||||
{2CF067CA-064B-43C6-8B88-5E3B99A65F1D} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
|
||||
{F301EF7D-F19C-4D83-AA94-CB64F29C037D} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
|
||||
{E826F796-8CE3-4B5B-8423-5AA5F81D2FC3} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
|
||||
{CAE8555E-F636-4C97-97A7-A041D3490D28} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
|
||||
{ABC826D4-2FA1-4F2F-87DE-E6095F653810} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA}
|
||||
{F112851D-B023-4746-B6B1-8D2E5AD8F7AA} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA}
|
||||
{6CB3EB30-F725-45C0-9742-42599BA8E8D2} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA}
|
||||
|
Reference in New Issue
Block a user