Commits

Anonymous committed fed5ece

Added a new ELMAH bootstrapper with CoC operation

Comments (0)

Files changed (7)

src/Elmah.Bootstrapper/Elmah.Bootstrapper.csproj

+<?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>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{BA4487F4-AD1B-4743-B08B-D8BEE1789EB8}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Elmah.Bootstrapper</RootNamespace>
+    <AssemblyName>Elmah.Bootstrapper</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Elmah">
+      <HintPath>..\..\lib\Elmah.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+    <Reference Include="System" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Web" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ErrorLogHandlerMappingModule.cs" />
+    <Compile Include="HttpContextBaseExtensions.cs" />
+    <Compile Include="Ignition.cs" />
+    <Compile Include="Mannex\IServiceProvider.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.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">
+  </Target>
+  -->
+</Project>

src/Elmah.Bootstrapper/ErrorLogHandlerMappingModule.cs

+#region License, Terms and Author(s)
+//
+// ELMAH Sandbox
+// Copyright (c) 2010-11 Atif Aziz. All rights reserved.
+//
+//  Author(s):
+//
+//      Atif Aziz, http://www.raboof.com
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#endregion
+
+namespace Elmah.Bootstrapper
+{
+    #region Imports
+
+    using System;
+    using System.Text.RegularExpressions;
+    using System.Web;
+
+    #endregion
+
+    sealed class ErrorLogHandlerMappingModule : HttpModuleBase
+    {
+        private ErrorLogPageFactory _errorLogPageFactory;
+
+        private ErrorLogPageFactory HandlerFactory
+        {
+            get { return _errorLogPageFactory ?? (_errorLogPageFactory = new ErrorLogPageFactory()); }
+        }
+
+        protected override void OnInit(HttpApplication application)
+        {
+            application.Subscribe(h => application.PostMapRequestHandler += h, OnPostMapRequestHandler);
+            application.Subscribe(h => application.EndRequest += h, OnEndRequest);
+        }
+
+        private void OnPostMapRequestHandler(HttpContextBase context)
+        {
+            var request = context.Request;
+            
+            var url = request.FilePath;
+            if (!Regex.IsMatch(url, @"(?i:\belmah\b)", RegexOptions.CultureInvariant))
+                return;
+            
+            var pathTranslated = request.PhysicalApplicationPath;
+            var factory = HandlerFactory;
+            var handler = factory.GetHandler(context, request.HttpMethod, url, pathTranslated);
+            if (handler == null) 
+                return;
+            
+            context.Items[this] = new ContextState
+            {
+                Handler = handler,
+                HandlerFactory = factory,
+            };
+            
+            context.Handler = handler;
+        }
+
+        private void OnEndRequest(HttpContextBase context)
+        {
+            var state = context.Items[this] as ContextState;
+            if (state == null)
+                return;
+            state.HandlerFactory.ReleaseHandler(state.Handler);
+        }
+        
+        sealed class ContextState
+        {
+            public IHttpHandler Handler;
+            public IHttpHandlerFactory HandlerFactory;
+        }
+    }
+}

src/Elmah.Bootstrapper/HttpContextBaseExtensions.cs

+#region License, Terms and Author(s)
+//
+// ELMAH Sandbox
+// Copyright (c) 2010-11 Atif Aziz. All rights reserved.
+//
+//  Author(s):
+//
+//      Atif Aziz, http://www.raboof.com
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#endregion
+
+namespace Elmah.Bootstrapper
+{
+    #region Imports
+
+    using System;
+    using System.Web;
+    using Mannex;
+
+    #endregion
+
+    static class WebExtensions
+    {
+        public static void Subscribe(this HttpApplication application, Action<EventHandler> subscriber, Action<HttpContextBase> handler)
+        {
+            if (application == null) throw new ArgumentNullException("application");
+            if (subscriber == null) throw new ArgumentNullException("subscriber");
+            if (handler == null) throw new ArgumentNullException("handler");
+        
+            subscriber((sender, _) => handler(new HttpContextWrapper(((HttpApplication) sender).Context)));
+        }
+
+        public static IHttpHandler GetHandler(this IHttpHandlerFactory factory, HttpContextBase context, string requestType, string url, string pathTranslated)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return factory.GetHandler(context.GetWrappedContext(), requestType, url, pathTranslated);
+        }
+        
+        public static HttpContext GetWrappedContext(this HttpContextBase context)
+        {
+            if (context == null) throw new ArgumentNullException("context");
+            return context.GetRequiredService<HttpApplication>().Context;
+        }
+    }
+}

src/Elmah.Bootstrapper/Ignition.cs

+#region License, Terms and Author(s)
+//
+// ELMAH Sandbox
+// Copyright (c) 2010-11 Atif Aziz. All rights reserved.
+//
+//  Author(s):
+//
+//      Atif Aziz, http://www.raboof.com
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#endregion
+
+[assembly: System.Web.PreApplicationStartMethod(typeof(Elmah.Bootstrapper.Ignition), "Start")]
+
+namespace Elmah.Bootstrapper
+{
+    #region Imports
+
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.ComponentModel.Design;
+    using System.Configuration;
+    using System.IO;
+    using System.Linq;
+    using System.Security;
+    using System.Security.Permissions;
+    using System.Web;
+    using System.Web.Compilation;
+    using Elmah.Assertions;
+    using Microsoft.Web.Infrastructure.DynamicModuleHelper;
+
+    #endregion
+
+    public static class Ignition
+    {
+        private static readonly object _lock = new object();
+        private static bool _registered;
+
+        public static void Start()
+        {
+            lock (_lock)
+            {
+                if (_registered)
+                    return;
+                StartImpl();
+                _registered = true;
+            }
+        }
+
+        private static void StartImpl()
+        {
+            // TODO Consider what happens if registration fails halfway
+
+            ServiceCenter.Current = GetServiceProvider;
+
+            foreach (var type in DefaultModuleTypeSet)
+                DynamicModuleUtility.RegisterModule(type);
+        }
+
+        private static IEnumerable<Type> DefaultModuleTypeSet
+        {
+            get
+            {
+                yield return typeof(ErrorLogModule);
+                yield return typeof(ErrorMailModule);
+                yield return typeof(ErrorFilterModule);
+                yield return typeof(ErrorTweetModule);
+                yield return typeof(ErrorLogHandlerMappingModule);
+            }
+        }
+
+        public static IServiceProvider GetServiceProvider(object context)
+        {
+            return GetServiceProvider(AsHttpContextBase(context));
+        }
+
+        private static HttpContextBase AsHttpContextBase(object context)
+        {
+            if (context == null)
+                return null;
+            var httpContextBase = context as HttpContextBase;
+            if (httpContextBase != null)
+                return httpContextBase;
+            var httpContext = context as HttpContext;
+            return httpContext == null
+                 ? null
+                 : new HttpContextWrapper(httpContext);
+        }
+
+        private static readonly object _contextKey = new object();
+
+        private static IServiceProvider GetServiceProvider(HttpContextBase context)
+        {
+            if (context != null)
+            {
+                var sp = context.Items[_contextKey] as IServiceProvider;
+                if (sp != null)
+                    return sp;
+            }
+            
+            var container = new ServiceContainer(ServiceCenter.Default(context));
+
+            if (context != null)
+            {
+                var logPath = context.Server.MapPath("~/App_Data/errors/xmlstore");
+
+                container.AddService(typeof (ErrorLog), delegate
+                {
+                    return Directory.Exists(logPath) 
+                         ? new XmlFileErrorLog(logPath) 
+                         : (object) new MemoryErrorLog();
+                });
+
+                context.Items[_contextKey] = container;
+            }
+
+            return container;
+        }
+    }
+
+    /*
+    class ErrorFilterModule : Elmah.ErrorFilterModule
+    {
+        protected override void OnErrorModuleFiltering(object sender, ExceptionFilterEventArgs args)
+        {
+            base.OnErrorModuleFiltering(sender, args);
+
+            if (args.Dismissed)
+                return;
+
+            var type = BuildManager.GetType("", false, true);
+            var assertion = Activator.CreateInstance(type) as IAssertion;
+            if (assertion == null)
+                return;
+            if (assertion.Test(args.Context))
+                args.Dismiss();
+        }
+    }*/
+}

src/Elmah.Bootstrapper/Mannex/IServiceProvider.cs

+#region License, Terms and Author(s)
+//
+// Mannex - Extension methods for .NET
+// Copyright (c) 2009 Atif Aziz. All rights reserved.
+//
+//  Author(s):
+//
+//      Atif Aziz, http://www.raboof.com
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#endregion
+
+namespace Mannex
+{
+    using System;
+
+    /// <summary>
+    /// Extension methods for <see cref="IServiceProvider"/>.
+    /// </summary>
+
+    static partial class IServiceProviderExtensions
+    {
+        /// <summary>
+        /// Gets the service object of the specified type.
+        /// </summary>
+
+        public static T GetService<T>(this IServiceProvider sp) where T : class
+        {
+            if (sp == null) throw new ArgumentNullException("sp");
+            return (T) sp.GetService(typeof(T));
+        }
+
+        /// <summary>
+        /// Gets the service object of the specified type.
+        /// </summary>
+
+        public static T GetRequiredService<T>(this IServiceProvider sp) where T : class
+        {
+            var service = sp.GetService<T>();
+            if (service == null)
+                throw new Exception(string.Format("Service of type {0} is unavailable.", typeof(T)));
+            return service;
+        }
+    }
+}

src/Elmah.Bootstrapper/Properties/AssemblyInfo.cs

+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("Elmah.Bootstrapper")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Elmah.Bootstrapper")]
+[assembly: AssemblyCopyright("Copyright ©  2011")]
+[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("d8d0ae90-cde1-4b25-bc39-bfa61c4bf985")]
+
+// 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 Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

src/Elmah.Sandbox.sln

 # Visual Studio 2010
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elmah.Sandbox", "Sandbox\Elmah.Sandbox.csproj", "{4ECE273D-21E1-4366-923B-6DBA92299FD4}"
 EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{281EC512-0DC8-4579-964B-CFC68C258B18}"
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Elmah.Export", "Export\Elmah.Export.fsproj", "{0B5D9A27-DC97-483F-A779-13C0546C6FDC}"
 EndProject
-Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Elmah.Export", "Export\Elmah.Export.fsproj", "{0B5D9A27-DC97-483F-A779-13C0546C6FDC}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elmah.Bootstrapper", "Elmah.Bootstrapper\Elmah.Bootstrapper.csproj", "{BA4487F4-AD1B-4743-B08B-D8BEE1789EB8}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		{0B5D9A27-DC97-483F-A779-13C0546C6FDC}.Release|Mixed Platforms.Build.0 = Release|x86
 		{0B5D9A27-DC97-483F-A779-13C0546C6FDC}.Release|x86.ActiveCfg = Release|x86
 		{0B5D9A27-DC97-483F-A779-13C0546C6FDC}.Release|x86.Build.0 = Release|x86
+		{BA4487F4-AD1B-4743-B08B-D8BEE1789EB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{BA4487F4-AD1B-4743-B08B-D8BEE1789EB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BA4487F4-AD1B-4743-B08B-D8BEE1789EB8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{BA4487F4-AD1B-4743-B08B-D8BEE1789EB8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{BA4487F4-AD1B-4743-B08B-D8BEE1789EB8}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{BA4487F4-AD1B-4743-B08B-D8BEE1789EB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{BA4487F4-AD1B-4743-B08B-D8BEE1789EB8}.Release|Any CPU.Build.0 = Release|Any CPU
+		{BA4487F4-AD1B-4743-B08B-D8BEE1789EB8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{BA4487F4-AD1B-4743-B08B-D8BEE1789EB8}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{BA4487F4-AD1B-4743-B08B-D8BEE1789EB8}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE