From d020ee61629851450b7004aab0291cea81f84d1e Mon Sep 17 00:00:00 2001 From: evilz Date: Mon, 25 Apr 2016 10:26:36 +0200 Subject: [PATCH 1/2] Initial Code in 4.5 --- .../0.CodeBase/Log/LibLog.cs | 1998 ----------------- .../0.CodeBase/Models/Deal.cs | 24 - .../0.CodeBase/packages.config | 6 - Src/Solid-TradeService/1.CQS_Maybe/App.config | 6 - .../1.CQS_Maybe/DealService.cs | 57 - .../Log/ColoredConsoleLogProvider.cs | 85 - .../1.CQS_Maybe/Log/LibLog.cs | 1998 ----------------- Src/Solid-TradeService/1.CQS_Maybe/Maybe.cs | 33 - .../1.CQS_Maybe/Models/OrderDirection.cs | 8 - Src/Solid-TradeService/1.CQS_Maybe/Program.cs | 53 - .../1.CQS_Maybe/Properties/AssemblyInfo.cs | 36 - Src/Solid-TradeService/1.CQS_Maybe/Readme.md | 11 - .../1.CQS_Maybe/TradeApp.csproj | 76 - .../1.CQS_Maybe/packages.config | 6 - Src/Solid-TradeService/2.SRP/App.config | 6 - Src/Solid-TradeService/2.SRP/DealCaching.cs | 25 - .../2.SRP/DealSerializer.cs | 18 - Src/Solid-TradeService/2.SRP/DealService.cs | 64 - .../2.SRP/DealServiceDiagram.cd | 65 - .../2.SRP/DealServiceLogger.cs | 35 - Src/Solid-TradeService/2.SRP/DealStorage.cs | 22 - .../2.SRP/Log/ColoredConsoleLogProvider.cs | 85 - Src/Solid-TradeService/2.SRP/Log/LibLog.cs | 1998 ----------------- Src/Solid-TradeService/2.SRP/Maybe.cs | 33 - Src/Solid-TradeService/2.SRP/Models/Deal.cs | 48 - .../2.SRP/Models/OrderDirection.cs | 8 - Src/Solid-TradeService/2.SRP/Program.cs | 39 - .../2.SRP/Properties/AssemblyInfo.cs | 36 - Src/Solid-TradeService/2.SRP/Readme.md | 9 - Src/Solid-TradeService/2.SRP/TradeApp.csproj | 81 - Src/Solid-TradeService/2.SRP/packages.config | 6 - Src/Solid-TradeService/3.OCP/App.config | 6 - Src/Solid-TradeService/3.OCP/DealCaching.cs | 25 - .../3.OCP/DealSerializer.cs | 18 - Src/Solid-TradeService/3.OCP/DealService.cs | 77 - .../3.OCP/DealServiceDiagram.cd | 65 - .../3.OCP/DealServiceLogger.cs | 35 - Src/Solid-TradeService/3.OCP/DealStorage.cs | 22 - .../3.OCP/Log/ColoredConsoleLogProvider.cs | 85 - Src/Solid-TradeService/3.OCP/Log/LibLog.cs | 1998 ----------------- Src/Solid-TradeService/3.OCP/Maybe.cs | 33 - Src/Solid-TradeService/3.OCP/Models/Deal.cs | 48 - .../3.OCP/Models/OrderDirection.cs | 8 - Src/Solid-TradeService/3.OCP/Program.cs | 39 - .../3.OCP/Properties/AssemblyInfo.cs | 36 - Src/Solid-TradeService/3.OCP/Readme.md | 6 - Src/Solid-TradeService/3.OCP/TradeApp.csproj | 81 - Src/Solid-TradeService/3.OCP/packages.config | 6 - Src/Solid-TradeService/4.LSP/App.config | 6 - Src/Solid-TradeService/4.LSP/DealCaching.cs | 25 - .../4.LSP/DealSerializer.cs | 18 - Src/Solid-TradeService/4.LSP/DealService.cs | 77 - .../4.LSP/DealServiceDiagram.cd | 65 - .../4.LSP/DealServiceLogger.cs | 35 - Src/Solid-TradeService/4.LSP/DealStorage.cs | 22 - .../4.LSP/Log/ColoredConsoleLogProvider.cs | 85 - Src/Solid-TradeService/4.LSP/Log/LibLog.cs | 1998 ----------------- Src/Solid-TradeService/4.LSP/Maybe.cs | 33 - Src/Solid-TradeService/4.LSP/Models/Deal.cs | 48 - .../4.LSP/Models/OrderDirection.cs | 8 - Src/Solid-TradeService/4.LSP/Program.cs | 39 - .../4.LSP/Properties/AssemblyInfo.cs | 36 - Src/Solid-TradeService/4.LSP/Readme.md | 7 - .../4.LSP/SQLDealStorage.cs | 45 - Src/Solid-TradeService/4.LSP/TradeApp.csproj | 85 - Src/Solid-TradeService/4.LSP/packages.config | 7 - Src/Solid-TradeService/5.ISP/App.config | 6 - .../5.ISP/Caching/DealCaching.cs | 25 - .../5.ISP/Caching/IDealCaching.cs | 11 - Src/Solid-TradeService/5.ISP/DealService.cs | 62 - .../5.ISP/DealServiceDiagram.cd | 65 - .../5.ISP/Log/ColoredConsoleLogProvider.cs | 85 - Src/Solid-TradeService/5.ISP/Log/LibLog.cs | 1998 ----------------- .../5.ISP/Logger/DealServiceLogger.cs | 35 - .../5.ISP/Logger/IDealServiceLogger.cs | 13 - Src/Solid-TradeService/5.ISP/Maybe.cs | 33 - Src/Solid-TradeService/5.ISP/Models/Deal.cs | 48 - .../5.ISP/Models/OrderDirection.cs | 8 - Src/Solid-TradeService/5.ISP/Program.cs | 39 - .../5.ISP/Properties/AssemblyInfo.cs | 36 - Src/Solid-TradeService/5.ISP/Readme.md | 37 - .../5.ISP/Serializer/DealSerializer.cs | 29 - .../5.ISP/Serializer/IDealSerializer.cs | 10 - .../5.ISP/Storage/FileDealStorage.cs | 41 - .../5.ISP/Storage/IDealStorage.cs | 8 - .../5.ISP/Storage/IFileLocator.cs | 9 - .../5.ISP/Storage/SQLDealStorage.cs | 43 - Src/Solid-TradeService/5.ISP/TradeApp.csproj | 134 -- Src/Solid-TradeService/5.ISP/packages.config | 7 - Src/Solid-TradeService/6.DIP/App.config | 6 - .../6.DIP/Caching/DealCaching.cs | 33 - Src/Solid-TradeService/6.DIP/DealService.cs | 34 - .../6.DIP/DealServiceDiagram.cd | 65 - Src/Solid-TradeService/6.DIP/IDealReader.cs | 9 - Src/Solid-TradeService/6.DIP/IDealWriter.cs | 9 - .../6.DIP/Log/ColoredConsoleLogProvider.cs | 85 - Src/Solid-TradeService/6.DIP/Log/LibLog.cs | 1998 ----------------- .../6.DIP/Logger/DealServiceLogger.cs | 71 - Src/Solid-TradeService/6.DIP/Maybe.cs | 42 - Src/Solid-TradeService/6.DIP/Models/Deal.cs | 48 - .../6.DIP/Models/OrderDirection.cs | 8 - Src/Solid-TradeService/6.DIP/Program.cs | 49 - .../6.DIP/Properties/AssemblyInfo.cs | 36 - Src/Solid-TradeService/6.DIP/Readme.md | 5 - .../6.DIP/Serializer/DealSerializer.cs | 26 - .../6.DIP/Serializer/IDealSerializer.cs | 10 - .../6.DIP/Storage/FileDealStorage.cs | 69 - .../6.DIP/Storage/IDealStorage.cs | 8 - .../6.DIP/Storage/IFileLocator.cs | 9 - .../6.DIP/Storage/SQLDealStorage.cs | 43 - Src/Solid-TradeService/6.DIP/TradeApp.csproj | 134 -- Src/Solid-TradeService/6.DIP/packages.config | 7 - Src/Solid-TradeService/7.IOC/App.config | 6 - .../7.IOC/Caching/DealCaching.cs | 34 - Src/Solid-TradeService/7.IOC/DealService.cs | 28 - .../7.IOC/DealServiceDiagram.cd | 65 - .../7.IOC/Log/ColoredConsoleLogProvider.cs | 85 - Src/Solid-TradeService/7.IOC/Log/LibLog.cs | 1998 ----------------- .../7.IOC/Logger/DealServiceLogger.cs | 72 - Src/Solid-TradeService/7.IOC/Models/Deal.cs | 48 - .../7.IOC/Models/IIdentifiable.cs | 7 - .../7.IOC/Models/OrderDirection.cs | 8 - Src/Solid-TradeService/7.IOC/Program.cs | 61 - .../7.IOC/Properties/AssemblyInfo.cs | 36 - Src/Solid-TradeService/7.IOC/Readme.md | 5 - .../7.IOC/Serializer/DealSerializer.cs | 27 - .../7.IOC/Serializer/IDealSerializer.cs | 11 - .../7.IOC/Storage/FileStorage.cs | 49 - .../7.IOC/Storage/IFileLocator.cs | 10 - .../7.IOC/Storage/SQLDealStorage.cs | 47 - Src/Solid-TradeService/7.IOC/TradeApp.csproj | 141 -- Src/Solid-TradeService/7.IOC/UsersManager.cs | 21 - Src/Solid-TradeService/7.IOC/packages.config | 9 - .../{0.CodeBase => }/App.config | 6 +- .../{0.CodeBase => }/DealService.cs | 0 .../Log/ColoredConsoleLogProvider.cs | 0 .../{1.CQS_Maybe => }/Models/Deal.cs | 16 +- .../{0.CodeBase => }/Models/OrderDirection.cs | 0 .../{0.CodeBase => }/Program.cs | 10 +- .../Properties/AssemblyInfo.cs | 0 Src/Solid-TradeService/Solid-TradeService.sln | 74 +- .../{0.CodeBase => }/TradeApp.csproj | 17 +- 142 files changed, 26 insertions(+), 20653 deletions(-) delete mode 100644 Src/Solid-TradeService/0.CodeBase/Log/LibLog.cs delete mode 100644 Src/Solid-TradeService/0.CodeBase/Models/Deal.cs delete mode 100644 Src/Solid-TradeService/0.CodeBase/packages.config delete mode 100644 Src/Solid-TradeService/1.CQS_Maybe/App.config delete mode 100644 Src/Solid-TradeService/1.CQS_Maybe/DealService.cs delete mode 100644 Src/Solid-TradeService/1.CQS_Maybe/Log/ColoredConsoleLogProvider.cs delete mode 100644 Src/Solid-TradeService/1.CQS_Maybe/Log/LibLog.cs delete mode 100644 Src/Solid-TradeService/1.CQS_Maybe/Maybe.cs delete mode 100644 Src/Solid-TradeService/1.CQS_Maybe/Models/OrderDirection.cs delete mode 100644 Src/Solid-TradeService/1.CQS_Maybe/Program.cs delete mode 100644 Src/Solid-TradeService/1.CQS_Maybe/Properties/AssemblyInfo.cs delete mode 100644 Src/Solid-TradeService/1.CQS_Maybe/Readme.md delete mode 100644 Src/Solid-TradeService/1.CQS_Maybe/TradeApp.csproj delete mode 100644 Src/Solid-TradeService/1.CQS_Maybe/packages.config delete mode 100644 Src/Solid-TradeService/2.SRP/App.config delete mode 100644 Src/Solid-TradeService/2.SRP/DealCaching.cs delete mode 100644 Src/Solid-TradeService/2.SRP/DealSerializer.cs delete mode 100644 Src/Solid-TradeService/2.SRP/DealService.cs delete mode 100644 Src/Solid-TradeService/2.SRP/DealServiceDiagram.cd delete mode 100644 Src/Solid-TradeService/2.SRP/DealServiceLogger.cs delete mode 100644 Src/Solid-TradeService/2.SRP/DealStorage.cs delete mode 100644 Src/Solid-TradeService/2.SRP/Log/ColoredConsoleLogProvider.cs delete mode 100644 Src/Solid-TradeService/2.SRP/Log/LibLog.cs delete mode 100644 Src/Solid-TradeService/2.SRP/Maybe.cs delete mode 100644 Src/Solid-TradeService/2.SRP/Models/Deal.cs delete mode 100644 Src/Solid-TradeService/2.SRP/Models/OrderDirection.cs delete mode 100644 Src/Solid-TradeService/2.SRP/Program.cs delete mode 100644 Src/Solid-TradeService/2.SRP/Properties/AssemblyInfo.cs delete mode 100644 Src/Solid-TradeService/2.SRP/Readme.md delete mode 100644 Src/Solid-TradeService/2.SRP/TradeApp.csproj delete mode 100644 Src/Solid-TradeService/2.SRP/packages.config delete mode 100644 Src/Solid-TradeService/3.OCP/App.config delete mode 100644 Src/Solid-TradeService/3.OCP/DealCaching.cs delete mode 100644 Src/Solid-TradeService/3.OCP/DealSerializer.cs delete mode 100644 Src/Solid-TradeService/3.OCP/DealService.cs delete mode 100644 Src/Solid-TradeService/3.OCP/DealServiceDiagram.cd delete mode 100644 Src/Solid-TradeService/3.OCP/DealServiceLogger.cs delete mode 100644 Src/Solid-TradeService/3.OCP/DealStorage.cs delete mode 100644 Src/Solid-TradeService/3.OCP/Log/ColoredConsoleLogProvider.cs delete mode 100644 Src/Solid-TradeService/3.OCP/Log/LibLog.cs delete mode 100644 Src/Solid-TradeService/3.OCP/Maybe.cs delete mode 100644 Src/Solid-TradeService/3.OCP/Models/Deal.cs delete mode 100644 Src/Solid-TradeService/3.OCP/Models/OrderDirection.cs delete mode 100644 Src/Solid-TradeService/3.OCP/Program.cs delete mode 100644 Src/Solid-TradeService/3.OCP/Properties/AssemblyInfo.cs delete mode 100644 Src/Solid-TradeService/3.OCP/Readme.md delete mode 100644 Src/Solid-TradeService/3.OCP/TradeApp.csproj delete mode 100644 Src/Solid-TradeService/3.OCP/packages.config delete mode 100644 Src/Solid-TradeService/4.LSP/App.config delete mode 100644 Src/Solid-TradeService/4.LSP/DealCaching.cs delete mode 100644 Src/Solid-TradeService/4.LSP/DealSerializer.cs delete mode 100644 Src/Solid-TradeService/4.LSP/DealService.cs delete mode 100644 Src/Solid-TradeService/4.LSP/DealServiceDiagram.cd delete mode 100644 Src/Solid-TradeService/4.LSP/DealServiceLogger.cs delete mode 100644 Src/Solid-TradeService/4.LSP/DealStorage.cs delete mode 100644 Src/Solid-TradeService/4.LSP/Log/ColoredConsoleLogProvider.cs delete mode 100644 Src/Solid-TradeService/4.LSP/Log/LibLog.cs delete mode 100644 Src/Solid-TradeService/4.LSP/Maybe.cs delete mode 100644 Src/Solid-TradeService/4.LSP/Models/Deal.cs delete mode 100644 Src/Solid-TradeService/4.LSP/Models/OrderDirection.cs delete mode 100644 Src/Solid-TradeService/4.LSP/Program.cs delete mode 100644 Src/Solid-TradeService/4.LSP/Properties/AssemblyInfo.cs delete mode 100644 Src/Solid-TradeService/4.LSP/Readme.md delete mode 100644 Src/Solid-TradeService/4.LSP/SQLDealStorage.cs delete mode 100644 Src/Solid-TradeService/4.LSP/TradeApp.csproj delete mode 100644 Src/Solid-TradeService/4.LSP/packages.config delete mode 100644 Src/Solid-TradeService/5.ISP/App.config delete mode 100644 Src/Solid-TradeService/5.ISP/Caching/DealCaching.cs delete mode 100644 Src/Solid-TradeService/5.ISP/Caching/IDealCaching.cs delete mode 100644 Src/Solid-TradeService/5.ISP/DealService.cs delete mode 100644 Src/Solid-TradeService/5.ISP/DealServiceDiagram.cd delete mode 100644 Src/Solid-TradeService/5.ISP/Log/ColoredConsoleLogProvider.cs delete mode 100644 Src/Solid-TradeService/5.ISP/Log/LibLog.cs delete mode 100644 Src/Solid-TradeService/5.ISP/Logger/DealServiceLogger.cs delete mode 100644 Src/Solid-TradeService/5.ISP/Logger/IDealServiceLogger.cs delete mode 100644 Src/Solid-TradeService/5.ISP/Maybe.cs delete mode 100644 Src/Solid-TradeService/5.ISP/Models/Deal.cs delete mode 100644 Src/Solid-TradeService/5.ISP/Models/OrderDirection.cs delete mode 100644 Src/Solid-TradeService/5.ISP/Program.cs delete mode 100644 Src/Solid-TradeService/5.ISP/Properties/AssemblyInfo.cs delete mode 100644 Src/Solid-TradeService/5.ISP/Readme.md delete mode 100644 Src/Solid-TradeService/5.ISP/Serializer/DealSerializer.cs delete mode 100644 Src/Solid-TradeService/5.ISP/Serializer/IDealSerializer.cs delete mode 100644 Src/Solid-TradeService/5.ISP/Storage/FileDealStorage.cs delete mode 100644 Src/Solid-TradeService/5.ISP/Storage/IDealStorage.cs delete mode 100644 Src/Solid-TradeService/5.ISP/Storage/IFileLocator.cs delete mode 100644 Src/Solid-TradeService/5.ISP/Storage/SQLDealStorage.cs delete mode 100644 Src/Solid-TradeService/5.ISP/TradeApp.csproj delete mode 100644 Src/Solid-TradeService/5.ISP/packages.config delete mode 100644 Src/Solid-TradeService/6.DIP/App.config delete mode 100644 Src/Solid-TradeService/6.DIP/Caching/DealCaching.cs delete mode 100644 Src/Solid-TradeService/6.DIP/DealService.cs delete mode 100644 Src/Solid-TradeService/6.DIP/DealServiceDiagram.cd delete mode 100644 Src/Solid-TradeService/6.DIP/IDealReader.cs delete mode 100644 Src/Solid-TradeService/6.DIP/IDealWriter.cs delete mode 100644 Src/Solid-TradeService/6.DIP/Log/ColoredConsoleLogProvider.cs delete mode 100644 Src/Solid-TradeService/6.DIP/Log/LibLog.cs delete mode 100644 Src/Solid-TradeService/6.DIP/Logger/DealServiceLogger.cs delete mode 100644 Src/Solid-TradeService/6.DIP/Maybe.cs delete mode 100644 Src/Solid-TradeService/6.DIP/Models/Deal.cs delete mode 100644 Src/Solid-TradeService/6.DIP/Models/OrderDirection.cs delete mode 100644 Src/Solid-TradeService/6.DIP/Program.cs delete mode 100644 Src/Solid-TradeService/6.DIP/Properties/AssemblyInfo.cs delete mode 100644 Src/Solid-TradeService/6.DIP/Readme.md delete mode 100644 Src/Solid-TradeService/6.DIP/Serializer/DealSerializer.cs delete mode 100644 Src/Solid-TradeService/6.DIP/Serializer/IDealSerializer.cs delete mode 100644 Src/Solid-TradeService/6.DIP/Storage/FileDealStorage.cs delete mode 100644 Src/Solid-TradeService/6.DIP/Storage/IDealStorage.cs delete mode 100644 Src/Solid-TradeService/6.DIP/Storage/IFileLocator.cs delete mode 100644 Src/Solid-TradeService/6.DIP/Storage/SQLDealStorage.cs delete mode 100644 Src/Solid-TradeService/6.DIP/TradeApp.csproj delete mode 100644 Src/Solid-TradeService/6.DIP/packages.config delete mode 100644 Src/Solid-TradeService/7.IOC/App.config delete mode 100644 Src/Solid-TradeService/7.IOC/Caching/DealCaching.cs delete mode 100644 Src/Solid-TradeService/7.IOC/DealService.cs delete mode 100644 Src/Solid-TradeService/7.IOC/DealServiceDiagram.cd delete mode 100644 Src/Solid-TradeService/7.IOC/Log/ColoredConsoleLogProvider.cs delete mode 100644 Src/Solid-TradeService/7.IOC/Log/LibLog.cs delete mode 100644 Src/Solid-TradeService/7.IOC/Logger/DealServiceLogger.cs delete mode 100644 Src/Solid-TradeService/7.IOC/Models/Deal.cs delete mode 100644 Src/Solid-TradeService/7.IOC/Models/IIdentifiable.cs delete mode 100644 Src/Solid-TradeService/7.IOC/Models/OrderDirection.cs delete mode 100644 Src/Solid-TradeService/7.IOC/Program.cs delete mode 100644 Src/Solid-TradeService/7.IOC/Properties/AssemblyInfo.cs delete mode 100644 Src/Solid-TradeService/7.IOC/Readme.md delete mode 100644 Src/Solid-TradeService/7.IOC/Serializer/DealSerializer.cs delete mode 100644 Src/Solid-TradeService/7.IOC/Serializer/IDealSerializer.cs delete mode 100644 Src/Solid-TradeService/7.IOC/Storage/FileStorage.cs delete mode 100644 Src/Solid-TradeService/7.IOC/Storage/IFileLocator.cs delete mode 100644 Src/Solid-TradeService/7.IOC/Storage/SQLDealStorage.cs delete mode 100644 Src/Solid-TradeService/7.IOC/TradeApp.csproj delete mode 100644 Src/Solid-TradeService/7.IOC/UsersManager.cs delete mode 100644 Src/Solid-TradeService/7.IOC/packages.config rename Src/Solid-TradeService/{0.CodeBase => }/App.config (60%) rename Src/Solid-TradeService/{0.CodeBase => }/DealService.cs (100%) rename Src/Solid-TradeService/{0.CodeBase => }/Log/ColoredConsoleLogProvider.cs (100%) rename Src/Solid-TradeService/{1.CQS_Maybe => }/Models/Deal.cs (52%) rename Src/Solid-TradeService/{0.CodeBase => }/Models/OrderDirection.cs (100%) rename Src/Solid-TradeService/{0.CodeBase => }/Program.cs (77%) rename Src/Solid-TradeService/{0.CodeBase => }/Properties/AssemblyInfo.cs (100%) rename Src/Solid-TradeService/{0.CodeBase => }/TradeApp.csproj (84%) diff --git a/Src/Solid-TradeService/0.CodeBase/Log/LibLog.cs b/Src/Solid-TradeService/0.CodeBase/Log/LibLog.cs deleted file mode 100644 index f761084..0000000 --- a/Src/Solid-TradeService/0.CodeBase/Log/LibLog.cs +++ /dev/null @@ -1,1998 +0,0 @@ -//=============================================================================== -// LibLog -// -// https://github.com/damianh/LibLog -//=============================================================================== -// Copyright © 2011-2015 Damian Hickey. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//=============================================================================== - -// ReSharper disable PossibleNullReferenceException - -// Define LIBLOG_PORTABLE conditional compilation symbol for PCL compatibility -// -// Define LIBLOG_PUBLIC to enable ability to GET a logger (LogProvider.For<>() etc) from outside this library. NOTE: -// this can have unintended consequences of consumers of your library using your library to resolve a logger. If the -// reason is because you want to open this functionality to other projects within your solution, -// consider [InternalVisibleTo] instead. -// -// Define LIBLOG_PROVIDERS_ONLY if your library provides its own logging API and you just want to use the -// LibLog providers internally to provide built in support for popular logging frameworks. - -#pragma warning disable 1591 - -// If you copied this file manually, you need to change all "YourRootNameSpace" so not to clash with other libraries -// that use LibLog -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog -#else -namespace TradeApp.Logging -#endif -{ - using System.Collections.Generic; -#if LIBLOG_PROVIDERS_ONLY - using TradeApp.LibLog.LogProviders; -#else - using TradeApp.Logging.LogProviders; -#endif - using System; -#if !LIBLOG_PROVIDERS_ONLY - using System.Diagnostics; -#if !LIBLOG_PORTABLE - using System.Runtime.CompilerServices; -#endif -#endif - -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - delegate bool Logger(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters); - -#if !LIBLOG_PROVIDERS_ONLY - /// - /// Simple interface that represent a logger. - /// -#if LIBLOG_PUBLIC - public -#else - internal -#endif - interface ILog - { - /// - /// Log a message the specified log level. - /// - /// The log level. - /// The message function. - /// An optional exception. - /// Optional format parameters for the message generated by the messagefunc. - /// true if the message was logged. Otherwise false. - /// - /// Note to implementers: the message func should not be called if the loglevel is not enabled - /// so as not to incur performance penalties. - /// - /// To check IsEnabled call Log with only LogLevel and check the return value, no event will be written. - /// - bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters ); - } -#endif - - /// - /// The log level. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - enum LogLevel - { - Trace, - Debug, - Info, - Warn, - Error, - Fatal - } - -#if !LIBLOG_PROVIDERS_ONLY -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static partial class LogExtensions - { - public static bool IsDebugEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Debug, null); - } - - public static bool IsErrorEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Error, null); - } - - public static bool IsFatalEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Fatal, null); - } - - public static bool IsInfoEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Info, null); - } - - public static bool IsTraceEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Trace, null); - } - - public static bool IsWarnEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Warn, null); - } - - public static void Debug(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Debug, messageFunc); - } - - public static void Debug(this ILog logger, string message) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc()); - } - } - - public static void DebugFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsDebugEnabled()) - { - logger.LogFormat(LogLevel.Debug, message, args); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception, formatParams); - } - } - - public static void Error(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Error, messageFunc); - } - - public static void Error(this ILog logger, string message) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc()); - } - } - - public static void ErrorFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsErrorEnabled()) - { - logger.LogFormat(LogLevel.Error, message, args); - } - } - - public static void ErrorException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc(), exception, formatParams); - } - } - - public static void Fatal(this ILog logger, Func messageFunc) - { - logger.Log(LogLevel.Fatal, messageFunc); - } - - public static void Fatal(this ILog logger, string message) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc()); - } - } - - public static void FatalFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsFatalEnabled()) - { - logger.LogFormat(LogLevel.Fatal, message, args); - } - } - - public static void FatalException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc(), exception, formatParams); - } - } - - public static void Info(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Info, messageFunc); - } - - public static void Info(this ILog logger, string message) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc()); - } - } - - public static void InfoFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsInfoEnabled()) - { - logger.LogFormat(LogLevel.Info, message, args); - } - } - - public static void InfoException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc(), exception, formatParams); - } - } - - public static void Trace(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Trace, messageFunc); - } - - public static void Trace(this ILog logger, string message) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc()); - } - } - - public static void TraceFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsTraceEnabled()) - { - logger.LogFormat(LogLevel.Trace, message, args); - } - } - - public static void TraceException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc(), exception, formatParams); - } - } - - public static void Warn(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Warn, messageFunc); - } - - public static void Warn(this ILog logger, string message) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc()); - } - } - - public static void WarnFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsWarnEnabled()) - { - logger.LogFormat(LogLevel.Warn, message, args); - } - } - - public static void WarnException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc(), exception, formatParams); - } - } - - // ReSharper disable once UnusedParameter.Local - private static void GuardAgainstNullLogger(ILog logger) - { - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - } - - private static void LogFormat(this ILog logger, LogLevel logLevel, string message, params object[] args) - { - logger.Log(logLevel, message.AsFunc(), null, args); - } - - // Avoid the closure allocation, see https://gist.github.com/AArnott/d285feef75c18f6ecd2b - private static Func AsFunc(this T value) where T : class - { - return value.Return; - } - - private static T Return(this T value) - { - return value; - } - } -#endif - - /// - /// Represents a way to get a - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - interface ILogProvider - { - /// - /// Gets the specified named logger. - /// - /// Name of the logger. - /// The logger reference. - Logger GetLogger(string name); - - /// - /// Opens a nested diagnostics context. Not supported in EntLib logging. - /// - /// The message to add to the diagnostics context. - /// A disposable that when disposed removes the message from the context. - IDisposable OpenNestedContext(string message); - - /// - /// Opens a mapped diagnostics context. Not supported in EntLib logging. - /// - /// A key. - /// A value. - /// A disposable that when disposed removes the map from the context. - IDisposable OpenMappedContext(string key, string value); - } - - /// - /// Provides a mechanism to create instances of objects. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - static class LogProvider - { -#if !LIBLOG_PROVIDERS_ONLY - /// - /// The disable logging environment variable. If the environment variable is set to 'true', then logging - /// will be disabled. - /// - public const string DisableLoggingEnvironmentVariable = "TradeApp_LIBLOG_DISABLE"; - private const string NullLogProvider = "Current Log Provider is not set. Call SetCurrentLogProvider " + - "with a non-null value first."; - private static dynamic s_currentLogProvider; - private static Action s_onCurrentLogProviderSet; - - static LogProvider() - { - IsDisabled = false; - } - - /// - /// Sets the current log provider. - /// - /// The log provider. - public static void SetCurrentLogProvider(ILogProvider logProvider) - { - s_currentLogProvider = logProvider; - - RaiseOnCurrentLogProviderSet(); - } - - /// - /// Gets or sets a value indicating whether this is logging is disabled. - /// - /// - /// true if logging is disabled; otherwise, false. - /// - public static bool IsDisabled { get; set; } - - /// - /// Sets an action that is invoked when a consumer of your library has called SetCurrentLogProvider. It is - /// important that hook into this if you are using child libraries (especially ilmerged ones) that are using - /// LibLog (or other logging abstraction) so you adapt and delegate to them. - /// - /// - internal static Action OnCurrentLogProviderSet - { - set - { - s_onCurrentLogProviderSet = value; - RaiseOnCurrentLogProviderSet(); - } - } - - internal static ILogProvider CurrentLogProvider - { - get - { - return s_currentLogProvider; - } - } - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog For() - { - return GetLogger(typeof(T)); - } - -#if !LIBLOG_PORTABLE - /// - /// Gets a logger for the current class. - /// - /// An instance of - [MethodImpl(MethodImplOptions.NoInlining)] -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetCurrentClassLogger() - { - var stackFrame = new StackFrame(1, false); - return GetLogger(stackFrame.GetMethod().DeclaringType); - } -#endif - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(Type type) - { - return GetLogger(type.FullName); - } - - /// - /// Gets a logger with the specified name. - /// - /// The name. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(string name) - { - ILogProvider logProvider = CurrentLogProvider ?? ResolveLogProvider(); - return logProvider == null - ? NoOpLogger.Instance - : (ILog)new LoggerExecutionWrapper(logProvider.GetLogger(name), () => IsDisabled); - } - - /// - /// Opens a nested diagnostics context. - /// - /// A message. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenNestedContext(string message) - { - if(CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenNestedContext(message); - } - - /// - /// Opens a mapped diagnostics context. - /// - /// A key. - /// A value. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenMappedContext(string key, string value) - { - if (CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenMappedContext(key, value); - } -#endif - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate bool IsLoggerAvailable(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate ILogProvider CreateLogProvider(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - static readonly List> LogProviderResolvers = - new List> - { - new Tuple(SerilogLogProvider.IsLoggerAvailable, () => new SerilogLogProvider()), - new Tuple(NLogLogProvider.IsLoggerAvailable, () => new NLogLogProvider()), - new Tuple(Log4NetLogProvider.IsLoggerAvailable, () => new Log4NetLogProvider()), - new Tuple(EntLibLogProvider.IsLoggerAvailable, () => new EntLibLogProvider()), - new Tuple(LoupeLogProvider.IsLoggerAvailable, () => new LoupeLogProvider()), - }; - -#if !LIBLOG_PROVIDERS_ONLY - private static void RaiseOnCurrentLogProviderSet() - { - if (s_onCurrentLogProviderSet != null) - { - s_onCurrentLogProviderSet(s_currentLogProvider); - } - } -#endif - - internal static ILogProvider ResolveLogProvider() - { - try - { - foreach (var providerResolver in LogProviderResolvers) - { - if (providerResolver.Item1()) - { - return providerResolver.Item2(); - } - } - } - catch (Exception ex) - { -#if LIBLOG_PORTABLE - Debug.WriteLine( -#else - Console.WriteLine( -#endif - "Exception occurred resolving a log provider. Logging for this assembly {0} is disabled. {1}", - typeof(LogProvider).GetAssemblyPortable().FullName, - ex); - } - return null; - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class NoOpLogger : ILog - { - internal static readonly NoOpLogger Instance = new NoOpLogger(); - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - return false; - } - } -#endif - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class LoggerExecutionWrapper : ILog - { - private readonly Logger _logger; - private readonly Func _getIsDisabled; - internal const string FailedToGenerateLogMessage = "Failed to generate log message"; - - internal LoggerExecutionWrapper(Logger logger, Func getIsDisabled = null) - { - _logger = logger; - _getIsDisabled = getIsDisabled ?? (() => false); - } - - internal Logger WrappedLogger - { - get { return _logger; } - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters) - { - if (_getIsDisabled()) - { - return false; - } -#if !LIBLOG_PORTABLE - var envVar = Environment.GetEnvironmentVariable(LogProvider.DisableLoggingEnvironmentVariable); - - if (envVar != null && envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) - { - return false; - } -#endif - - if (messageFunc == null) - { - return _logger(logLevel, null); - } - - Func wrappedMessageFunc = () => - { - try - { - return messageFunc(); - } - catch (Exception ex) - { - Log(LogLevel.Error, () => FailedToGenerateLogMessage, ex); - } - return null; - }; - return _logger(logLevel, wrappedMessageFunc, exception, formatParameters); - } - } -#endif -} - -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog.LogProviders -#else -namespace TradeApp.Logging.LogProviders -#endif -{ - using System; - using System.Collections.Generic; -#if !LIBLOG_PORTABLE - using System.Diagnostics; -#endif - using System.Globalization; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; -#if !LIBLOG_PORTABLE - using System.Text; -#endif - using System.Text.RegularExpressions; - - internal abstract class LogProviderBase : ILogProvider - { - protected delegate IDisposable OpenNdc(string message); - protected delegate IDisposable OpenMdc(string key, string value); - - private readonly Lazy _lazyOpenNdcMethod; - private readonly Lazy _lazyOpenMdcMethod; - private static readonly IDisposable NoopDisposableInstance = new DisposableAction(); - - protected LogProviderBase() - { - _lazyOpenNdcMethod - = new Lazy(GetOpenNdcMethod); - _lazyOpenMdcMethod - = new Lazy(GetOpenMdcMethod); - } - - public abstract Logger GetLogger(string name); - - public IDisposable OpenNestedContext(string message) - { - return _lazyOpenNdcMethod.Value(message); - } - - public IDisposable OpenMappedContext(string key, string value) - { - return _lazyOpenMdcMethod.Value(key, value); - } - - protected virtual OpenNdc GetOpenNdcMethod() - { - return _ => NoopDisposableInstance; - } - - protected virtual OpenMdc GetOpenMdcMethod() - { - return (_, __) => NoopDisposableInstance; - } - } - - internal class NLogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public NLogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("NLog.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new NLogLogger(_getLoggerByNameDelegate(name)).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("NLog.NestedDiagnosticsContext, NLog"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("NLog.MappedDiagnosticsContext, NLog"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("NLog.LogManager, NLog"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class NLogLogger - { - private readonly dynamic _logger; - - internal NLogLogger(dynamic logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - if(exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.Debug(messageFunc()); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.Info(messageFunc()); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.Warn(messageFunc()); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.Error(messageFunc()); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.Fatal(messageFunc()); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.Trace(messageFunc()); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.DebugException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.InfoException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.WarnException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.ErrorException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.FatalException(messageFunc(), exception); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.TraceException(messageFunc(), exception); - return true; - } - break; - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Debug: - return _logger.IsDebugEnabled; - case LogLevel.Info: - return _logger.IsInfoEnabled; - case LogLevel.Warn: - return _logger.IsWarnEnabled; - case LogLevel.Error: - return _logger.IsErrorEnabled; - case LogLevel.Fatal: - return _logger.IsFatalEnabled; - default: - return _logger.IsTraceEnabled; - } - } - } - } - - internal class Log4NetLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public Log4NetLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("log4net.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new Log4NetLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("log4net.NDC, log4net"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("log4net.MDC, log4net"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("log4net.LogManager, log4net"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class Log4NetLogger - { - private readonly dynamic _logger; - private static Type s_callerStackBoundaryType; - private static readonly object CallerStackBoundaryTypeSync = new object(); - - private readonly object _levelDebug; - private readonly object _levelInfo; - private readonly object _levelWarn; - private readonly object _levelError; - private readonly object _levelFatal; - private readonly Func _isEnabledForDelegate; - private readonly Action _logDelegate; - - internal Log4NetLogger(dynamic logger) - { - _logger = logger.Logger; - - var logEventLevelType = Type.GetType("log4net.Core.Level, log4net"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type log4net.Core.Level was not found."); - } - - var levelFields = logEventLevelType.GetFieldsPortable().ToList(); - _levelDebug = levelFields.First(x => x.Name == "Debug").GetValue(null); - _levelInfo = levelFields.First(x => x.Name == "Info").GetValue(null); - _levelWarn = levelFields.First(x => x.Name == "Warn").GetValue(null); - _levelError = levelFields.First(x => x.Name == "Error").GetValue(null); - _levelFatal = levelFields.First(x => x.Name == "Fatal").GetValue(null); - - // Func isEnabledFor = (logger, level) => { return ((log4net.Core.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("log4net.Core.ILogger, log4net"); - if (loggerType == null) - { - throw new InvalidOperationException("Type log4net.Core.ILogger, was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabledFor", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression callerStackBoundaryDeclaringTypeParam = Expression.Parameter(typeof(Type)); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - _isEnabledForDelegate = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Log = - // (logger, callerStackBoundaryDeclaringType, level, message, exception) => { ((ILogger)logger).Write(callerStackBoundaryDeclaringType, level, message, exception); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Log", - typeof(Type), - logEventLevelType, - typeof(string), - typeof(Exception)); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - var writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - callerStackBoundaryDeclaringTypeParam, - levelCast, - messageParam, - exceptionParam); - _logDelegate = Expression.Lambda>( - writeMethodExp, - instanceParam, - callerStackBoundaryDeclaringTypeParam, - levelParam, - messageParam, - exceptionParam).Compile(); - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - - if (!IsLogLevelEnable(logLevel)) - { - return false; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - // determine correct caller - this might change due to jit optimizations with method inlining - if (s_callerStackBoundaryType == null) - { - lock (CallerStackBoundaryTypeSync) - { -#if !LIBLOG_PORTABLE - StackTrace stack = new StackTrace(); - Type thisType = GetType(); - s_callerStackBoundaryType = Type.GetType("LoggerExecutionWrapper"); - for (var i = 1; i < stack.FrameCount; i++) - { - if (!IsInTypeHierarchy(thisType, stack.GetFrame(i).GetMethod().DeclaringType)) - { - s_callerStackBoundaryType = stack.GetFrame(i - 1).GetMethod().DeclaringType; - break; - } - } -#else - s_callerStackBoundaryType = typeof (LoggerExecutionWrapper); -#endif - } - } - - var translatedLevel = TranslateLevel(logLevel); - _logDelegate(_logger, s_callerStackBoundaryType, translatedLevel, messageFunc(), exception); - return true; - } - - private bool IsInTypeHierarchy(Type currentType, Type checkType) - { - while (currentType != null && currentType != typeof(object)) - { - if (currentType == checkType) - { - return true; - } - currentType = currentType.GetBaseTypePortable(); - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - var level = TranslateLevel(logLevel); - return _isEnabledForDelegate(_logger, level); - } - - private object TranslateLevel(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - case LogLevel.Debug: - return _levelDebug; - case LogLevel.Info: - return _levelInfo; - case LogLevel.Warn: - return _levelWarn; - case LogLevel.Error: - return _levelError; - case LogLevel.Fatal: - return _levelFatal; - default: - throw new ArgumentOutOfRangeException("logLevel", logLevel, null); - } - } - } - } - - internal class EntLibLogProvider : LogProviderBase - { - private const string TypeTemplate = "Microsoft.Practices.EnterpriseLibrary.Logging.{0}, Microsoft.Practices.EnterpriseLibrary.Logging"; - private static bool s_providerIsAvailableOverride = true; - private static readonly Type LogEntryType; - private static readonly Type LoggerType; - private static readonly Type TraceEventTypeType; - private static readonly Action WriteLogEntry; - private static readonly Func ShouldLogEntry; - - static EntLibLogProvider() - { - LogEntryType = Type.GetType(string.Format(TypeTemplate, "LogEntry")); - LoggerType = Type.GetType(string.Format(TypeTemplate, "Logger")); - TraceEventTypeType = TraceEventTypeValues.Type; - if (LogEntryType == null - || TraceEventTypeType == null - || LoggerType == null) - { - return; - } - WriteLogEntry = GetWriteLogEntry(); - ShouldLogEntry = GetShouldLogEntry(); - } - - public EntLibLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Microsoft.Practices.EnterpriseLibrary.Logging.Logger not found"); - } - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new EntLibLogger(name, WriteLogEntry, ShouldLogEntry).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride - && TraceEventTypeType != null - && LogEntryType != null; - } - - private static Action GetWriteLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var messageParameter = Expression.Parameter(typeof(string), "message"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - messageParameter, - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("Write", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - messageParameter, - severityParameter).Compile(); - } - - private static Func GetShouldLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - Expression.Constant("***dummy***"), - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("ShouldLog", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - severityParameter).Compile(); - } - - private static MemberInitExpression GetWriteLogExpression(Expression message, - Expression severityParameter, ParameterExpression logNameParameter) - { - var entryType = LogEntryType; - MemberInitExpression memberInit = Expression.MemberInit(Expression.New(entryType), - Expression.Bind(entryType.GetPropertyPortable("Message"), message), - Expression.Bind(entryType.GetPropertyPortable("Severity"), severityParameter), - Expression.Bind( - entryType.GetPropertyPortable("TimeStamp"), - Expression.Property(null, typeof (DateTime).GetPropertyPortable("UtcNow"))), - Expression.Bind( - entryType.GetPropertyPortable("Categories"), - Expression.ListInit( - Expression.New(typeof (List)), - typeof (List).GetMethodPortable("Add", typeof (string)), - logNameParameter))); - return memberInit; - } - - internal class EntLibLogger - { - private readonly string _loggerName; - private readonly Action _writeLog; - private readonly Func _shouldLog; - - internal EntLibLogger(string loggerName, Action writeLog, Func shouldLog) - { - _loggerName = loggerName; - _writeLog = writeLog; - _shouldLog = shouldLog; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - var severity = MapSeverity(logLevel); - if (messageFunc == null) - { - return _shouldLog(_loggerName, severity); - } - - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - if (exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - _writeLog(_loggerName, messageFunc(), severity); - return true; - } - - public bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - var severity = MapSeverity(logLevel); - var message = messageFunc() + Environment.NewLine + exception; - _writeLog(_loggerName, message, severity); - return true; - } - - private static int MapSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Info: - return TraceEventTypeValues.Information; - default: - return TraceEventTypeValues.Verbose; - } - } - } - } - - internal class SerilogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public SerilogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Serilog.Log not found"); - } - _getLoggerByNameDelegate = GetForContextMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new SerilogLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - return message => GetPushProperty()("NDC", message); - } - - protected override OpenMdc GetOpenMdcMethod() - { - return (key, value) => GetPushProperty()(key, value); - } - - private static Func GetPushProperty() - { - Type ndcContextType = Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"); - MethodInfo pushPropertyMethod = ndcContextType.GetMethodPortable( - "PushProperty", - typeof(string), - typeof(object), - typeof(bool)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression pushPropertyMethodCall = Expression - .Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam); - var pushProperty = Expression - .Lambda>( - pushPropertyMethodCall, - nameParam, - valueParam, - destructureObjectParam) - .Compile(); - - return (key, value) => pushProperty(key, value, false); - } - - private static Type GetLogManagerType() - { - return Type.GetType("Serilog.Log, Serilog"); - } - - private static Func GetForContextMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("ForContext", typeof(string), typeof(object), typeof(bool)); - ParameterExpression propertyNameParam = Expression.Parameter(typeof(string), "propertyName"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectsParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression methodCall = Expression.Call(null, method, new Expression[] - { - propertyNameParam, - valueParam, - destructureObjectsParam - }); - var func = Expression.Lambda>( - methodCall, - propertyNameParam, - valueParam, - destructureObjectsParam) - .Compile(); - return name => func("Name", name, false); - } - - internal class SerilogLogger - { - private readonly object _logger; - private static readonly object DebugLevel; - private static readonly object ErrorLevel; - private static readonly object FatalLevel; - private static readonly object InformationLevel; - private static readonly object VerboseLevel; - private static readonly object WarningLevel; - private static readonly Func IsEnabled; - private static readonly Action Write; - private static readonly Action WriteException; - - static SerilogLogger() - { - var logEventLevelType = Type.GetType("Serilog.Events.LogEventLevel, Serilog"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type Serilog.Events.LogEventLevel was not found."); - } - DebugLevel = Enum.Parse(logEventLevelType, "Debug", false); - ErrorLevel = Enum.Parse(logEventLevelType, "Error", false); - FatalLevel = Enum.Parse(logEventLevelType, "Fatal", false); - InformationLevel = Enum.Parse(logEventLevelType, "Information", false); - VerboseLevel = Enum.Parse(logEventLevelType, "Verbose", false); - WarningLevel = Enum.Parse(logEventLevelType, "Warning", false); - - // Func isEnabled = (logger, level) => { return ((SeriLog.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("Serilog.ILogger, Serilog"); - if (loggerType == null) - { - throw new InvalidOperationException("Type Serilog.ILogger was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabled", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - IsEnabled = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Write = - // (logger, level, message, params) => { ((SeriLog.ILoggerILogger)logger).Write(level, message, params); } - MethodInfo writeMethodInfo = loggerType.GetMethodPortable("Write", logEventLevelType, typeof(string), typeof(object[])); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - ParameterExpression propertyValuesParam = Expression.Parameter(typeof(object[])); - MethodCallExpression writeMethodExp = Expression.Call( - instanceCast, - writeMethodInfo, - levelCast, - messageParam, - propertyValuesParam); - var expression = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - messageParam, - propertyValuesParam); - Write = expression.Compile(); - - // Action WriteException = - // (logger, level, exception, message) => { ((ILogger)logger).Write(level, exception, message, new object[]); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Write", - logEventLevelType, - typeof(Exception), - typeof(string), - typeof(object[])); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - levelCast, - exceptionParam, - messageParam, - propertyValuesParam); - WriteException = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - exceptionParam, - messageParam, - propertyValuesParam).Compile(); - } - - internal SerilogLogger(object logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsEnabled(_logger, logLevel); - } - if (exception != null) - { - return LogException(logLevel, messageFunc, exception, formatParameters); - } - - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - Write(_logger, DebugLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - Write(_logger, InformationLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - Write(_logger, WarningLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - Write(_logger, ErrorLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - Write(_logger, FatalLevel, messageFunc(), formatParameters); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - Write(_logger, VerboseLevel, messageFunc(), formatParameters); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception, object[] formatParams) - { - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - WriteException(_logger, DebugLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - WriteException(_logger, InformationLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - WriteException(_logger, WarningLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - WriteException(_logger, ErrorLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - WriteException(_logger, FatalLevel, exception, messageFunc(), formatParams); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - WriteException(_logger, VerboseLevel, exception, messageFunc(), formatParams); - return true; - } - break; - } - return false; - } - } - } - - internal class LoupeLogProvider : LogProviderBase - { - /// - /// The form of the Loupe Log.Write method we're using - /// - internal delegate void WriteDelegate( - int severity, - string logSystem, - int skipFrames, - Exception exception, - bool attributeToException, - int writeMode, - string detailsXml, - string category, - string caption, - string description, - params object[] args - ); - - private static bool s_providerIsAvailableOverride = true; - private readonly WriteDelegate _logWriteDelegate; - - public LoupeLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Gibraltar.Agent.Log (Loupe) not found"); - } - - _logWriteDelegate = GetLogWriteDelegate(); - } - - /// - /// Gets or sets a value indicating whether [provider is available override]. Used in tests. - /// - /// - /// true if [provider is available override]; otherwise, false. - /// - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new LoupeLogger(name, _logWriteDelegate).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - private static Type GetLogManagerType() - { - return Type.GetType("Gibraltar.Agent.Log, Gibraltar.Agent"); - } - - private static WriteDelegate GetLogWriteDelegate() - { - Type logManagerType = GetLogManagerType(); - Type logMessageSeverityType = Type.GetType("Gibraltar.Agent.LogMessageSeverity, Gibraltar.Agent"); - Type logWriteModeType = Type.GetType("Gibraltar.Agent.LogWriteMode, Gibraltar.Agent"); - - MethodInfo method = logManagerType.GetMethodPortable( - "Write", - logMessageSeverityType, typeof(string), typeof(int), typeof(Exception), typeof(bool), - logWriteModeType, typeof(string), typeof(string), typeof(string), typeof(string), typeof(object[])); - - var callDelegate = (WriteDelegate)method.CreateDelegate(typeof(WriteDelegate)); - return callDelegate; - } - - internal class LoupeLogger - { - private const string LogSystem = "LibLog"; - - private readonly string _category; - private readonly WriteDelegate _logWriteDelegate; - private readonly int _skipLevel; - - internal LoupeLogger(string category, WriteDelegate logWriteDelegate) - { - _category = category; - _logWriteDelegate = logWriteDelegate; -#if DEBUG - _skipLevel = 2; -#else - _skipLevel = 1; -#endif - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - //nothing to log.. - return true; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - _logWriteDelegate(ToLogMessageSeverity(logLevel), LogSystem, _skipLevel, exception, true, 0, null, - _category, null, messageFunc.Invoke()); - - return true; - } - - private int ToLogMessageSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - return TraceEventTypeValues.Verbose; - case LogLevel.Debug: - return TraceEventTypeValues.Verbose; - case LogLevel.Info: - return TraceEventTypeValues.Information; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - default: - throw new ArgumentOutOfRangeException("logLevel"); - } - } - } - } - - internal static class TraceEventTypeValues - { - internal static readonly Type Type; - internal static readonly int Verbose; - internal static readonly int Information; - internal static readonly int Warning; - internal static readonly int Error; - internal static readonly int Critical; - - static TraceEventTypeValues() - { - var assembly = typeof(Uri).GetAssemblyPortable(); // This is to get to the System.dll assembly in a PCL compatible way. - if (assembly == null) - { - return; - } - Type = assembly.GetType("System.Diagnostics.TraceEventType"); - if (Type == null) return; - Verbose = (int)Enum.Parse(Type, "Verbose", false); - Information = (int)Enum.Parse(Type, "Information", false); - Warning = (int)Enum.Parse(Type, "Warning", false); - Error = (int)Enum.Parse(Type, "Error", false); - Critical = (int)Enum.Parse(Type, "Critical", false); - } - } - - internal static class LogMessageFormatter - { - private static readonly Regex Pattern = new Regex(@"\{@?\w{1,}\}"); - - /// - /// Some logging frameworks support structured logging, such as serilog. This will allow you to add names to structured data in a format string: - /// For example: Log("Log message to {user}", user). This only works with serilog, but as the user of LibLog, you don't know if serilog is actually - /// used. So, this class simulates that. it will replace any text in {curly braces} with an index number. - /// - /// "Log {message} to {user}" would turn into => "Log {0} to {1}". Then the format parameters are handled using regular .net string.Format. - /// - /// The message builder. - /// The format parameters. - /// - public static Func SimulateStructuredLogging(Func messageBuilder, object[] formatParameters) - { - if (formatParameters == null || formatParameters.Length == 0) - { - return messageBuilder; - } - - return () => - { - string targetMessage = messageBuilder(); - int argumentIndex = 0; - foreach (Match match in Pattern.Matches(targetMessage)) - { - int notUsed; - if (!int.TryParse(match.Value.Substring(1, match.Value.Length -2), out notUsed)) - { - targetMessage = ReplaceFirst(targetMessage, match.Value, - "{" + argumentIndex++ + "}"); - } - } - try - { - return string.Format(CultureInfo.InvariantCulture, targetMessage, formatParameters); - } - catch (FormatException ex) - { - throw new FormatException("The input string '" + targetMessage + "' could not be formatted using string.Format", ex); - } - }; - } - - private static string ReplaceFirst(string text, string search, string replace) - { - int pos = text.IndexOf(search, StringComparison.Ordinal); - if (pos < 0) - { - return text; - } - return text.Substring(0, pos) + replace + text.Substring(pos + search.Length); - } - } - - internal static class TypeExtensions - { - internal static MethodInfo GetMethodPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, new Type[]{}); -#else - return type.GetMethod(name); -#endif - } - - internal static MethodInfo GetMethodPortable(this Type type, string name, params Type[] types) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, types); -#else - return type.GetMethod(name, types); -#endif - } - - internal static PropertyInfo GetPropertyPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeProperty(name); -#else - return type.GetProperty(name); -#endif - } - - internal static IEnumerable GetFieldsPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeFields(); -#else - return type.GetFields(); -#endif - } - - internal static Type GetBaseTypePortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().BaseType; -#else - return type.BaseType; -#endif - } - -#if LIBLOG_PORTABLE - internal static MethodInfo GetGetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.GetMethod; - } - - internal static MethodInfo GetSetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.SetMethod; - } -#endif - -#if !LIBLOG_PORTABLE - internal static object CreateDelegate(this MethodInfo methodInfo, Type delegateType) - { - return Delegate.CreateDelegate(delegateType, methodInfo); - } -#endif - - internal static Assembly GetAssemblyPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().Assembly; -#else - return type.Assembly; -#endif - } - } - - internal class DisposableAction : IDisposable - { - private readonly Action _onDispose; - - public DisposableAction(Action onDispose = null) - { - _onDispose = onDispose; - } - - public void Dispose() - { - if(_onDispose != null) - { - _onDispose(); - } - } - } -} diff --git a/Src/Solid-TradeService/0.CodeBase/Models/Deal.cs b/Src/Solid-TradeService/0.CodeBase/Models/Deal.cs deleted file mode 100644 index b67a5d7..0000000 --- a/Src/Solid-TradeService/0.CodeBase/Models/Deal.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -namespace TradeApp.Models -{ - public class Deal - { - public string Id { get; set; } - public double Price { get; internal set; } - public DateTime Time { get; internal set; } - public int Quantity { get; internal set; } - - public string Symbol { get; set; } - - public OrderDirection Direction - { - get { - return Quantity >= 0 ? OrderDirection.Buy : OrderDirection.Sell; - } - } - public override string ToString() - { - return string.Format("OrderId: {0} {1} order for {2} unit{3} of {4}", Id,Direction, Quantity, Quantity == 1 ? "" : "s", Symbol); - } - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/0.CodeBase/packages.config b/Src/Solid-TradeService/0.CodeBase/packages.config deleted file mode 100644 index 557b51e..0000000 --- a/Src/Solid-TradeService/0.CodeBase/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/1.CQS_Maybe/App.config b/Src/Solid-TradeService/1.CQS_Maybe/App.config deleted file mode 100644 index 8324aa6..0000000 --- a/Src/Solid-TradeService/1.CQS_Maybe/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/1.CQS_Maybe/DealService.cs b/Src/Solid-TradeService/1.CQS_Maybe/DealService.cs deleted file mode 100644 index 4f392aa..0000000 --- a/Src/Solid-TradeService/1.CQS_Maybe/DealService.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Collections.Immutable; -using System.IO; -using Newtonsoft.Json; -using TradeApp.Logging; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealService - { - private ImmutableDictionary _cache; - private static readonly ILog _logger = LogProvider.For(); - - public DealService(string username) - { - if(username == null) - { throw new ArgumentNullException(nameof(username)); } - - if (!Directory.Exists(username)) - { Directory.CreateDirectory(username); } - - Username = username; - _cache = ImmutableDictionary.Empty; - } - - public string Username { get; } - - public void Save(string id, Deal deal) - { - _logger.Info("Saving deal "+ deal.Id); - var path = GetFileName(id); - File.WriteAllText(path, JsonConvert.SerializeObject(deal)); - var savedDeal = ImmutableInterlocked.AddOrUpdate(ref _cache, id, deal, (i, d) => deal ); - _logger.Info("Saved deal " + savedDeal.Id ); - } - - public Maybe Load(string id) - { - _logger.Info("Loading deal " + id); - var path = GetFileName(id); - - if (!File.Exists(path)) - { return new Maybe(); } - - var deal = ImmutableInterlocked.GetOrAdd(ref _cache, id, - _ => JsonConvert.DeserializeObject(File.ReadAllText(path))); - _logger.Info("Returning deal " + id); - return new Maybe(deal); - } - - public string GetFileName(string id) - { - return Path.Combine(Username, id + ".json"); - } - } -} diff --git a/Src/Solid-TradeService/1.CQS_Maybe/Log/ColoredConsoleLogProvider.cs b/Src/Solid-TradeService/1.CQS_Maybe/Log/ColoredConsoleLogProvider.cs deleted file mode 100644 index 6853892..0000000 --- a/Src/Solid-TradeService/1.CQS_Maybe/Log/ColoredConsoleLogProvider.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using TradeApp.Logging; - -namespace TradeApp.App_Packages.LibLog._4._2 -{ - public class ColoredConsoleLogProvider : ILogProvider - { - private static readonly Dictionary Colors = new Dictionary - { - {LogLevel.Fatal, ConsoleColor.Red}, - {LogLevel.Error, ConsoleColor.Yellow}, - {LogLevel.Warn, ConsoleColor.Magenta}, - {LogLevel.Info, ConsoleColor.White}, - {LogLevel.Debug, ConsoleColor.Gray}, - {LogLevel.Trace, ConsoleColor.DarkGray}, - }; - - public Logger GetLogger(string name) - { - return (logLevel, messageFunc, exception, formatParameters) => - { - if (messageFunc == null) - { - return true; // All log levels are enabled - } - - ConsoleColor consoleColor; - if (Colors.TryGetValue(logLevel, out consoleColor)) - { - var originalForground = Console.ForegroundColor; - try - { - Console.ForegroundColor = consoleColor; - WriteMessage(logLevel, name, messageFunc, formatParameters, exception); - } - finally - { - Console.ForegroundColor = originalForground; - } - } - else - { - WriteMessage(logLevel, name, messageFunc, formatParameters, exception); - } - - return true; - }; - } - - private static void WriteMessage( - LogLevel logLevel, - string name, - Func messageFunc, - object[] formatParameters, - Exception exception) - { - var message = string.Format(CultureInfo.InvariantCulture, messageFunc(), formatParameters); - if (exception != null) - { - message = message + "|" + exception; - } - Console.WriteLine("{0} | {1} | {2} | {3}", DateTime.UtcNow, logLevel, name, message); - } - - public IDisposable OpenNestedContext(string message) - { - return NullDisposable.Instance; - } - - public IDisposable OpenMappedContext(string key, string value) - { - return NullDisposable.Instance; - } - - private class NullDisposable : IDisposable - { - internal static readonly IDisposable Instance = new NullDisposable(); - - public void Dispose() - { } - } - } -} diff --git a/Src/Solid-TradeService/1.CQS_Maybe/Log/LibLog.cs b/Src/Solid-TradeService/1.CQS_Maybe/Log/LibLog.cs deleted file mode 100644 index f761084..0000000 --- a/Src/Solid-TradeService/1.CQS_Maybe/Log/LibLog.cs +++ /dev/null @@ -1,1998 +0,0 @@ -//=============================================================================== -// LibLog -// -// https://github.com/damianh/LibLog -//=============================================================================== -// Copyright © 2011-2015 Damian Hickey. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//=============================================================================== - -// ReSharper disable PossibleNullReferenceException - -// Define LIBLOG_PORTABLE conditional compilation symbol for PCL compatibility -// -// Define LIBLOG_PUBLIC to enable ability to GET a logger (LogProvider.For<>() etc) from outside this library. NOTE: -// this can have unintended consequences of consumers of your library using your library to resolve a logger. If the -// reason is because you want to open this functionality to other projects within your solution, -// consider [InternalVisibleTo] instead. -// -// Define LIBLOG_PROVIDERS_ONLY if your library provides its own logging API and you just want to use the -// LibLog providers internally to provide built in support for popular logging frameworks. - -#pragma warning disable 1591 - -// If you copied this file manually, you need to change all "YourRootNameSpace" so not to clash with other libraries -// that use LibLog -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog -#else -namespace TradeApp.Logging -#endif -{ - using System.Collections.Generic; -#if LIBLOG_PROVIDERS_ONLY - using TradeApp.LibLog.LogProviders; -#else - using TradeApp.Logging.LogProviders; -#endif - using System; -#if !LIBLOG_PROVIDERS_ONLY - using System.Diagnostics; -#if !LIBLOG_PORTABLE - using System.Runtime.CompilerServices; -#endif -#endif - -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - delegate bool Logger(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters); - -#if !LIBLOG_PROVIDERS_ONLY - /// - /// Simple interface that represent a logger. - /// -#if LIBLOG_PUBLIC - public -#else - internal -#endif - interface ILog - { - /// - /// Log a message the specified log level. - /// - /// The log level. - /// The message function. - /// An optional exception. - /// Optional format parameters for the message generated by the messagefunc. - /// true if the message was logged. Otherwise false. - /// - /// Note to implementers: the message func should not be called if the loglevel is not enabled - /// so as not to incur performance penalties. - /// - /// To check IsEnabled call Log with only LogLevel and check the return value, no event will be written. - /// - bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters ); - } -#endif - - /// - /// The log level. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - enum LogLevel - { - Trace, - Debug, - Info, - Warn, - Error, - Fatal - } - -#if !LIBLOG_PROVIDERS_ONLY -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static partial class LogExtensions - { - public static bool IsDebugEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Debug, null); - } - - public static bool IsErrorEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Error, null); - } - - public static bool IsFatalEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Fatal, null); - } - - public static bool IsInfoEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Info, null); - } - - public static bool IsTraceEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Trace, null); - } - - public static bool IsWarnEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Warn, null); - } - - public static void Debug(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Debug, messageFunc); - } - - public static void Debug(this ILog logger, string message) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc()); - } - } - - public static void DebugFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsDebugEnabled()) - { - logger.LogFormat(LogLevel.Debug, message, args); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception, formatParams); - } - } - - public static void Error(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Error, messageFunc); - } - - public static void Error(this ILog logger, string message) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc()); - } - } - - public static void ErrorFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsErrorEnabled()) - { - logger.LogFormat(LogLevel.Error, message, args); - } - } - - public static void ErrorException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc(), exception, formatParams); - } - } - - public static void Fatal(this ILog logger, Func messageFunc) - { - logger.Log(LogLevel.Fatal, messageFunc); - } - - public static void Fatal(this ILog logger, string message) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc()); - } - } - - public static void FatalFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsFatalEnabled()) - { - logger.LogFormat(LogLevel.Fatal, message, args); - } - } - - public static void FatalException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc(), exception, formatParams); - } - } - - public static void Info(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Info, messageFunc); - } - - public static void Info(this ILog logger, string message) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc()); - } - } - - public static void InfoFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsInfoEnabled()) - { - logger.LogFormat(LogLevel.Info, message, args); - } - } - - public static void InfoException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc(), exception, formatParams); - } - } - - public static void Trace(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Trace, messageFunc); - } - - public static void Trace(this ILog logger, string message) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc()); - } - } - - public static void TraceFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsTraceEnabled()) - { - logger.LogFormat(LogLevel.Trace, message, args); - } - } - - public static void TraceException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc(), exception, formatParams); - } - } - - public static void Warn(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Warn, messageFunc); - } - - public static void Warn(this ILog logger, string message) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc()); - } - } - - public static void WarnFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsWarnEnabled()) - { - logger.LogFormat(LogLevel.Warn, message, args); - } - } - - public static void WarnException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc(), exception, formatParams); - } - } - - // ReSharper disable once UnusedParameter.Local - private static void GuardAgainstNullLogger(ILog logger) - { - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - } - - private static void LogFormat(this ILog logger, LogLevel logLevel, string message, params object[] args) - { - logger.Log(logLevel, message.AsFunc(), null, args); - } - - // Avoid the closure allocation, see https://gist.github.com/AArnott/d285feef75c18f6ecd2b - private static Func AsFunc(this T value) where T : class - { - return value.Return; - } - - private static T Return(this T value) - { - return value; - } - } -#endif - - /// - /// Represents a way to get a - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - interface ILogProvider - { - /// - /// Gets the specified named logger. - /// - /// Name of the logger. - /// The logger reference. - Logger GetLogger(string name); - - /// - /// Opens a nested diagnostics context. Not supported in EntLib logging. - /// - /// The message to add to the diagnostics context. - /// A disposable that when disposed removes the message from the context. - IDisposable OpenNestedContext(string message); - - /// - /// Opens a mapped diagnostics context. Not supported in EntLib logging. - /// - /// A key. - /// A value. - /// A disposable that when disposed removes the map from the context. - IDisposable OpenMappedContext(string key, string value); - } - - /// - /// Provides a mechanism to create instances of objects. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - static class LogProvider - { -#if !LIBLOG_PROVIDERS_ONLY - /// - /// The disable logging environment variable. If the environment variable is set to 'true', then logging - /// will be disabled. - /// - public const string DisableLoggingEnvironmentVariable = "TradeApp_LIBLOG_DISABLE"; - private const string NullLogProvider = "Current Log Provider is not set. Call SetCurrentLogProvider " + - "with a non-null value first."; - private static dynamic s_currentLogProvider; - private static Action s_onCurrentLogProviderSet; - - static LogProvider() - { - IsDisabled = false; - } - - /// - /// Sets the current log provider. - /// - /// The log provider. - public static void SetCurrentLogProvider(ILogProvider logProvider) - { - s_currentLogProvider = logProvider; - - RaiseOnCurrentLogProviderSet(); - } - - /// - /// Gets or sets a value indicating whether this is logging is disabled. - /// - /// - /// true if logging is disabled; otherwise, false. - /// - public static bool IsDisabled { get; set; } - - /// - /// Sets an action that is invoked when a consumer of your library has called SetCurrentLogProvider. It is - /// important that hook into this if you are using child libraries (especially ilmerged ones) that are using - /// LibLog (or other logging abstraction) so you adapt and delegate to them. - /// - /// - internal static Action OnCurrentLogProviderSet - { - set - { - s_onCurrentLogProviderSet = value; - RaiseOnCurrentLogProviderSet(); - } - } - - internal static ILogProvider CurrentLogProvider - { - get - { - return s_currentLogProvider; - } - } - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog For() - { - return GetLogger(typeof(T)); - } - -#if !LIBLOG_PORTABLE - /// - /// Gets a logger for the current class. - /// - /// An instance of - [MethodImpl(MethodImplOptions.NoInlining)] -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetCurrentClassLogger() - { - var stackFrame = new StackFrame(1, false); - return GetLogger(stackFrame.GetMethod().DeclaringType); - } -#endif - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(Type type) - { - return GetLogger(type.FullName); - } - - /// - /// Gets a logger with the specified name. - /// - /// The name. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(string name) - { - ILogProvider logProvider = CurrentLogProvider ?? ResolveLogProvider(); - return logProvider == null - ? NoOpLogger.Instance - : (ILog)new LoggerExecutionWrapper(logProvider.GetLogger(name), () => IsDisabled); - } - - /// - /// Opens a nested diagnostics context. - /// - /// A message. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenNestedContext(string message) - { - if(CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenNestedContext(message); - } - - /// - /// Opens a mapped diagnostics context. - /// - /// A key. - /// A value. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenMappedContext(string key, string value) - { - if (CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenMappedContext(key, value); - } -#endif - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate bool IsLoggerAvailable(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate ILogProvider CreateLogProvider(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - static readonly List> LogProviderResolvers = - new List> - { - new Tuple(SerilogLogProvider.IsLoggerAvailable, () => new SerilogLogProvider()), - new Tuple(NLogLogProvider.IsLoggerAvailable, () => new NLogLogProvider()), - new Tuple(Log4NetLogProvider.IsLoggerAvailable, () => new Log4NetLogProvider()), - new Tuple(EntLibLogProvider.IsLoggerAvailable, () => new EntLibLogProvider()), - new Tuple(LoupeLogProvider.IsLoggerAvailable, () => new LoupeLogProvider()), - }; - -#if !LIBLOG_PROVIDERS_ONLY - private static void RaiseOnCurrentLogProviderSet() - { - if (s_onCurrentLogProviderSet != null) - { - s_onCurrentLogProviderSet(s_currentLogProvider); - } - } -#endif - - internal static ILogProvider ResolveLogProvider() - { - try - { - foreach (var providerResolver in LogProviderResolvers) - { - if (providerResolver.Item1()) - { - return providerResolver.Item2(); - } - } - } - catch (Exception ex) - { -#if LIBLOG_PORTABLE - Debug.WriteLine( -#else - Console.WriteLine( -#endif - "Exception occurred resolving a log provider. Logging for this assembly {0} is disabled. {1}", - typeof(LogProvider).GetAssemblyPortable().FullName, - ex); - } - return null; - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class NoOpLogger : ILog - { - internal static readonly NoOpLogger Instance = new NoOpLogger(); - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - return false; - } - } -#endif - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class LoggerExecutionWrapper : ILog - { - private readonly Logger _logger; - private readonly Func _getIsDisabled; - internal const string FailedToGenerateLogMessage = "Failed to generate log message"; - - internal LoggerExecutionWrapper(Logger logger, Func getIsDisabled = null) - { - _logger = logger; - _getIsDisabled = getIsDisabled ?? (() => false); - } - - internal Logger WrappedLogger - { - get { return _logger; } - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters) - { - if (_getIsDisabled()) - { - return false; - } -#if !LIBLOG_PORTABLE - var envVar = Environment.GetEnvironmentVariable(LogProvider.DisableLoggingEnvironmentVariable); - - if (envVar != null && envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) - { - return false; - } -#endif - - if (messageFunc == null) - { - return _logger(logLevel, null); - } - - Func wrappedMessageFunc = () => - { - try - { - return messageFunc(); - } - catch (Exception ex) - { - Log(LogLevel.Error, () => FailedToGenerateLogMessage, ex); - } - return null; - }; - return _logger(logLevel, wrappedMessageFunc, exception, formatParameters); - } - } -#endif -} - -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog.LogProviders -#else -namespace TradeApp.Logging.LogProviders -#endif -{ - using System; - using System.Collections.Generic; -#if !LIBLOG_PORTABLE - using System.Diagnostics; -#endif - using System.Globalization; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; -#if !LIBLOG_PORTABLE - using System.Text; -#endif - using System.Text.RegularExpressions; - - internal abstract class LogProviderBase : ILogProvider - { - protected delegate IDisposable OpenNdc(string message); - protected delegate IDisposable OpenMdc(string key, string value); - - private readonly Lazy _lazyOpenNdcMethod; - private readonly Lazy _lazyOpenMdcMethod; - private static readonly IDisposable NoopDisposableInstance = new DisposableAction(); - - protected LogProviderBase() - { - _lazyOpenNdcMethod - = new Lazy(GetOpenNdcMethod); - _lazyOpenMdcMethod - = new Lazy(GetOpenMdcMethod); - } - - public abstract Logger GetLogger(string name); - - public IDisposable OpenNestedContext(string message) - { - return _lazyOpenNdcMethod.Value(message); - } - - public IDisposable OpenMappedContext(string key, string value) - { - return _lazyOpenMdcMethod.Value(key, value); - } - - protected virtual OpenNdc GetOpenNdcMethod() - { - return _ => NoopDisposableInstance; - } - - protected virtual OpenMdc GetOpenMdcMethod() - { - return (_, __) => NoopDisposableInstance; - } - } - - internal class NLogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public NLogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("NLog.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new NLogLogger(_getLoggerByNameDelegate(name)).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("NLog.NestedDiagnosticsContext, NLog"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("NLog.MappedDiagnosticsContext, NLog"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("NLog.LogManager, NLog"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class NLogLogger - { - private readonly dynamic _logger; - - internal NLogLogger(dynamic logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - if(exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.Debug(messageFunc()); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.Info(messageFunc()); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.Warn(messageFunc()); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.Error(messageFunc()); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.Fatal(messageFunc()); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.Trace(messageFunc()); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.DebugException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.InfoException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.WarnException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.ErrorException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.FatalException(messageFunc(), exception); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.TraceException(messageFunc(), exception); - return true; - } - break; - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Debug: - return _logger.IsDebugEnabled; - case LogLevel.Info: - return _logger.IsInfoEnabled; - case LogLevel.Warn: - return _logger.IsWarnEnabled; - case LogLevel.Error: - return _logger.IsErrorEnabled; - case LogLevel.Fatal: - return _logger.IsFatalEnabled; - default: - return _logger.IsTraceEnabled; - } - } - } - } - - internal class Log4NetLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public Log4NetLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("log4net.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new Log4NetLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("log4net.NDC, log4net"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("log4net.MDC, log4net"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("log4net.LogManager, log4net"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class Log4NetLogger - { - private readonly dynamic _logger; - private static Type s_callerStackBoundaryType; - private static readonly object CallerStackBoundaryTypeSync = new object(); - - private readonly object _levelDebug; - private readonly object _levelInfo; - private readonly object _levelWarn; - private readonly object _levelError; - private readonly object _levelFatal; - private readonly Func _isEnabledForDelegate; - private readonly Action _logDelegate; - - internal Log4NetLogger(dynamic logger) - { - _logger = logger.Logger; - - var logEventLevelType = Type.GetType("log4net.Core.Level, log4net"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type log4net.Core.Level was not found."); - } - - var levelFields = logEventLevelType.GetFieldsPortable().ToList(); - _levelDebug = levelFields.First(x => x.Name == "Debug").GetValue(null); - _levelInfo = levelFields.First(x => x.Name == "Info").GetValue(null); - _levelWarn = levelFields.First(x => x.Name == "Warn").GetValue(null); - _levelError = levelFields.First(x => x.Name == "Error").GetValue(null); - _levelFatal = levelFields.First(x => x.Name == "Fatal").GetValue(null); - - // Func isEnabledFor = (logger, level) => { return ((log4net.Core.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("log4net.Core.ILogger, log4net"); - if (loggerType == null) - { - throw new InvalidOperationException("Type log4net.Core.ILogger, was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabledFor", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression callerStackBoundaryDeclaringTypeParam = Expression.Parameter(typeof(Type)); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - _isEnabledForDelegate = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Log = - // (logger, callerStackBoundaryDeclaringType, level, message, exception) => { ((ILogger)logger).Write(callerStackBoundaryDeclaringType, level, message, exception); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Log", - typeof(Type), - logEventLevelType, - typeof(string), - typeof(Exception)); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - var writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - callerStackBoundaryDeclaringTypeParam, - levelCast, - messageParam, - exceptionParam); - _logDelegate = Expression.Lambda>( - writeMethodExp, - instanceParam, - callerStackBoundaryDeclaringTypeParam, - levelParam, - messageParam, - exceptionParam).Compile(); - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - - if (!IsLogLevelEnable(logLevel)) - { - return false; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - // determine correct caller - this might change due to jit optimizations with method inlining - if (s_callerStackBoundaryType == null) - { - lock (CallerStackBoundaryTypeSync) - { -#if !LIBLOG_PORTABLE - StackTrace stack = new StackTrace(); - Type thisType = GetType(); - s_callerStackBoundaryType = Type.GetType("LoggerExecutionWrapper"); - for (var i = 1; i < stack.FrameCount; i++) - { - if (!IsInTypeHierarchy(thisType, stack.GetFrame(i).GetMethod().DeclaringType)) - { - s_callerStackBoundaryType = stack.GetFrame(i - 1).GetMethod().DeclaringType; - break; - } - } -#else - s_callerStackBoundaryType = typeof (LoggerExecutionWrapper); -#endif - } - } - - var translatedLevel = TranslateLevel(logLevel); - _logDelegate(_logger, s_callerStackBoundaryType, translatedLevel, messageFunc(), exception); - return true; - } - - private bool IsInTypeHierarchy(Type currentType, Type checkType) - { - while (currentType != null && currentType != typeof(object)) - { - if (currentType == checkType) - { - return true; - } - currentType = currentType.GetBaseTypePortable(); - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - var level = TranslateLevel(logLevel); - return _isEnabledForDelegate(_logger, level); - } - - private object TranslateLevel(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - case LogLevel.Debug: - return _levelDebug; - case LogLevel.Info: - return _levelInfo; - case LogLevel.Warn: - return _levelWarn; - case LogLevel.Error: - return _levelError; - case LogLevel.Fatal: - return _levelFatal; - default: - throw new ArgumentOutOfRangeException("logLevel", logLevel, null); - } - } - } - } - - internal class EntLibLogProvider : LogProviderBase - { - private const string TypeTemplate = "Microsoft.Practices.EnterpriseLibrary.Logging.{0}, Microsoft.Practices.EnterpriseLibrary.Logging"; - private static bool s_providerIsAvailableOverride = true; - private static readonly Type LogEntryType; - private static readonly Type LoggerType; - private static readonly Type TraceEventTypeType; - private static readonly Action WriteLogEntry; - private static readonly Func ShouldLogEntry; - - static EntLibLogProvider() - { - LogEntryType = Type.GetType(string.Format(TypeTemplate, "LogEntry")); - LoggerType = Type.GetType(string.Format(TypeTemplate, "Logger")); - TraceEventTypeType = TraceEventTypeValues.Type; - if (LogEntryType == null - || TraceEventTypeType == null - || LoggerType == null) - { - return; - } - WriteLogEntry = GetWriteLogEntry(); - ShouldLogEntry = GetShouldLogEntry(); - } - - public EntLibLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Microsoft.Practices.EnterpriseLibrary.Logging.Logger not found"); - } - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new EntLibLogger(name, WriteLogEntry, ShouldLogEntry).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride - && TraceEventTypeType != null - && LogEntryType != null; - } - - private static Action GetWriteLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var messageParameter = Expression.Parameter(typeof(string), "message"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - messageParameter, - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("Write", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - messageParameter, - severityParameter).Compile(); - } - - private static Func GetShouldLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - Expression.Constant("***dummy***"), - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("ShouldLog", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - severityParameter).Compile(); - } - - private static MemberInitExpression GetWriteLogExpression(Expression message, - Expression severityParameter, ParameterExpression logNameParameter) - { - var entryType = LogEntryType; - MemberInitExpression memberInit = Expression.MemberInit(Expression.New(entryType), - Expression.Bind(entryType.GetPropertyPortable("Message"), message), - Expression.Bind(entryType.GetPropertyPortable("Severity"), severityParameter), - Expression.Bind( - entryType.GetPropertyPortable("TimeStamp"), - Expression.Property(null, typeof (DateTime).GetPropertyPortable("UtcNow"))), - Expression.Bind( - entryType.GetPropertyPortable("Categories"), - Expression.ListInit( - Expression.New(typeof (List)), - typeof (List).GetMethodPortable("Add", typeof (string)), - logNameParameter))); - return memberInit; - } - - internal class EntLibLogger - { - private readonly string _loggerName; - private readonly Action _writeLog; - private readonly Func _shouldLog; - - internal EntLibLogger(string loggerName, Action writeLog, Func shouldLog) - { - _loggerName = loggerName; - _writeLog = writeLog; - _shouldLog = shouldLog; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - var severity = MapSeverity(logLevel); - if (messageFunc == null) - { - return _shouldLog(_loggerName, severity); - } - - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - if (exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - _writeLog(_loggerName, messageFunc(), severity); - return true; - } - - public bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - var severity = MapSeverity(logLevel); - var message = messageFunc() + Environment.NewLine + exception; - _writeLog(_loggerName, message, severity); - return true; - } - - private static int MapSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Info: - return TraceEventTypeValues.Information; - default: - return TraceEventTypeValues.Verbose; - } - } - } - } - - internal class SerilogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public SerilogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Serilog.Log not found"); - } - _getLoggerByNameDelegate = GetForContextMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new SerilogLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - return message => GetPushProperty()("NDC", message); - } - - protected override OpenMdc GetOpenMdcMethod() - { - return (key, value) => GetPushProperty()(key, value); - } - - private static Func GetPushProperty() - { - Type ndcContextType = Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"); - MethodInfo pushPropertyMethod = ndcContextType.GetMethodPortable( - "PushProperty", - typeof(string), - typeof(object), - typeof(bool)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression pushPropertyMethodCall = Expression - .Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam); - var pushProperty = Expression - .Lambda>( - pushPropertyMethodCall, - nameParam, - valueParam, - destructureObjectParam) - .Compile(); - - return (key, value) => pushProperty(key, value, false); - } - - private static Type GetLogManagerType() - { - return Type.GetType("Serilog.Log, Serilog"); - } - - private static Func GetForContextMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("ForContext", typeof(string), typeof(object), typeof(bool)); - ParameterExpression propertyNameParam = Expression.Parameter(typeof(string), "propertyName"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectsParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression methodCall = Expression.Call(null, method, new Expression[] - { - propertyNameParam, - valueParam, - destructureObjectsParam - }); - var func = Expression.Lambda>( - methodCall, - propertyNameParam, - valueParam, - destructureObjectsParam) - .Compile(); - return name => func("Name", name, false); - } - - internal class SerilogLogger - { - private readonly object _logger; - private static readonly object DebugLevel; - private static readonly object ErrorLevel; - private static readonly object FatalLevel; - private static readonly object InformationLevel; - private static readonly object VerboseLevel; - private static readonly object WarningLevel; - private static readonly Func IsEnabled; - private static readonly Action Write; - private static readonly Action WriteException; - - static SerilogLogger() - { - var logEventLevelType = Type.GetType("Serilog.Events.LogEventLevel, Serilog"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type Serilog.Events.LogEventLevel was not found."); - } - DebugLevel = Enum.Parse(logEventLevelType, "Debug", false); - ErrorLevel = Enum.Parse(logEventLevelType, "Error", false); - FatalLevel = Enum.Parse(logEventLevelType, "Fatal", false); - InformationLevel = Enum.Parse(logEventLevelType, "Information", false); - VerboseLevel = Enum.Parse(logEventLevelType, "Verbose", false); - WarningLevel = Enum.Parse(logEventLevelType, "Warning", false); - - // Func isEnabled = (logger, level) => { return ((SeriLog.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("Serilog.ILogger, Serilog"); - if (loggerType == null) - { - throw new InvalidOperationException("Type Serilog.ILogger was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabled", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - IsEnabled = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Write = - // (logger, level, message, params) => { ((SeriLog.ILoggerILogger)logger).Write(level, message, params); } - MethodInfo writeMethodInfo = loggerType.GetMethodPortable("Write", logEventLevelType, typeof(string), typeof(object[])); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - ParameterExpression propertyValuesParam = Expression.Parameter(typeof(object[])); - MethodCallExpression writeMethodExp = Expression.Call( - instanceCast, - writeMethodInfo, - levelCast, - messageParam, - propertyValuesParam); - var expression = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - messageParam, - propertyValuesParam); - Write = expression.Compile(); - - // Action WriteException = - // (logger, level, exception, message) => { ((ILogger)logger).Write(level, exception, message, new object[]); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Write", - logEventLevelType, - typeof(Exception), - typeof(string), - typeof(object[])); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - levelCast, - exceptionParam, - messageParam, - propertyValuesParam); - WriteException = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - exceptionParam, - messageParam, - propertyValuesParam).Compile(); - } - - internal SerilogLogger(object logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsEnabled(_logger, logLevel); - } - if (exception != null) - { - return LogException(logLevel, messageFunc, exception, formatParameters); - } - - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - Write(_logger, DebugLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - Write(_logger, InformationLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - Write(_logger, WarningLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - Write(_logger, ErrorLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - Write(_logger, FatalLevel, messageFunc(), formatParameters); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - Write(_logger, VerboseLevel, messageFunc(), formatParameters); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception, object[] formatParams) - { - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - WriteException(_logger, DebugLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - WriteException(_logger, InformationLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - WriteException(_logger, WarningLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - WriteException(_logger, ErrorLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - WriteException(_logger, FatalLevel, exception, messageFunc(), formatParams); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - WriteException(_logger, VerboseLevel, exception, messageFunc(), formatParams); - return true; - } - break; - } - return false; - } - } - } - - internal class LoupeLogProvider : LogProviderBase - { - /// - /// The form of the Loupe Log.Write method we're using - /// - internal delegate void WriteDelegate( - int severity, - string logSystem, - int skipFrames, - Exception exception, - bool attributeToException, - int writeMode, - string detailsXml, - string category, - string caption, - string description, - params object[] args - ); - - private static bool s_providerIsAvailableOverride = true; - private readonly WriteDelegate _logWriteDelegate; - - public LoupeLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Gibraltar.Agent.Log (Loupe) not found"); - } - - _logWriteDelegate = GetLogWriteDelegate(); - } - - /// - /// Gets or sets a value indicating whether [provider is available override]. Used in tests. - /// - /// - /// true if [provider is available override]; otherwise, false. - /// - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new LoupeLogger(name, _logWriteDelegate).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - private static Type GetLogManagerType() - { - return Type.GetType("Gibraltar.Agent.Log, Gibraltar.Agent"); - } - - private static WriteDelegate GetLogWriteDelegate() - { - Type logManagerType = GetLogManagerType(); - Type logMessageSeverityType = Type.GetType("Gibraltar.Agent.LogMessageSeverity, Gibraltar.Agent"); - Type logWriteModeType = Type.GetType("Gibraltar.Agent.LogWriteMode, Gibraltar.Agent"); - - MethodInfo method = logManagerType.GetMethodPortable( - "Write", - logMessageSeverityType, typeof(string), typeof(int), typeof(Exception), typeof(bool), - logWriteModeType, typeof(string), typeof(string), typeof(string), typeof(string), typeof(object[])); - - var callDelegate = (WriteDelegate)method.CreateDelegate(typeof(WriteDelegate)); - return callDelegate; - } - - internal class LoupeLogger - { - private const string LogSystem = "LibLog"; - - private readonly string _category; - private readonly WriteDelegate _logWriteDelegate; - private readonly int _skipLevel; - - internal LoupeLogger(string category, WriteDelegate logWriteDelegate) - { - _category = category; - _logWriteDelegate = logWriteDelegate; -#if DEBUG - _skipLevel = 2; -#else - _skipLevel = 1; -#endif - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - //nothing to log.. - return true; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - _logWriteDelegate(ToLogMessageSeverity(logLevel), LogSystem, _skipLevel, exception, true, 0, null, - _category, null, messageFunc.Invoke()); - - return true; - } - - private int ToLogMessageSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - return TraceEventTypeValues.Verbose; - case LogLevel.Debug: - return TraceEventTypeValues.Verbose; - case LogLevel.Info: - return TraceEventTypeValues.Information; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - default: - throw new ArgumentOutOfRangeException("logLevel"); - } - } - } - } - - internal static class TraceEventTypeValues - { - internal static readonly Type Type; - internal static readonly int Verbose; - internal static readonly int Information; - internal static readonly int Warning; - internal static readonly int Error; - internal static readonly int Critical; - - static TraceEventTypeValues() - { - var assembly = typeof(Uri).GetAssemblyPortable(); // This is to get to the System.dll assembly in a PCL compatible way. - if (assembly == null) - { - return; - } - Type = assembly.GetType("System.Diagnostics.TraceEventType"); - if (Type == null) return; - Verbose = (int)Enum.Parse(Type, "Verbose", false); - Information = (int)Enum.Parse(Type, "Information", false); - Warning = (int)Enum.Parse(Type, "Warning", false); - Error = (int)Enum.Parse(Type, "Error", false); - Critical = (int)Enum.Parse(Type, "Critical", false); - } - } - - internal static class LogMessageFormatter - { - private static readonly Regex Pattern = new Regex(@"\{@?\w{1,}\}"); - - /// - /// Some logging frameworks support structured logging, such as serilog. This will allow you to add names to structured data in a format string: - /// For example: Log("Log message to {user}", user). This only works with serilog, but as the user of LibLog, you don't know if serilog is actually - /// used. So, this class simulates that. it will replace any text in {curly braces} with an index number. - /// - /// "Log {message} to {user}" would turn into => "Log {0} to {1}". Then the format parameters are handled using regular .net string.Format. - /// - /// The message builder. - /// The format parameters. - /// - public static Func SimulateStructuredLogging(Func messageBuilder, object[] formatParameters) - { - if (formatParameters == null || formatParameters.Length == 0) - { - return messageBuilder; - } - - return () => - { - string targetMessage = messageBuilder(); - int argumentIndex = 0; - foreach (Match match in Pattern.Matches(targetMessage)) - { - int notUsed; - if (!int.TryParse(match.Value.Substring(1, match.Value.Length -2), out notUsed)) - { - targetMessage = ReplaceFirst(targetMessage, match.Value, - "{" + argumentIndex++ + "}"); - } - } - try - { - return string.Format(CultureInfo.InvariantCulture, targetMessage, formatParameters); - } - catch (FormatException ex) - { - throw new FormatException("The input string '" + targetMessage + "' could not be formatted using string.Format", ex); - } - }; - } - - private static string ReplaceFirst(string text, string search, string replace) - { - int pos = text.IndexOf(search, StringComparison.Ordinal); - if (pos < 0) - { - return text; - } - return text.Substring(0, pos) + replace + text.Substring(pos + search.Length); - } - } - - internal static class TypeExtensions - { - internal static MethodInfo GetMethodPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, new Type[]{}); -#else - return type.GetMethod(name); -#endif - } - - internal static MethodInfo GetMethodPortable(this Type type, string name, params Type[] types) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, types); -#else - return type.GetMethod(name, types); -#endif - } - - internal static PropertyInfo GetPropertyPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeProperty(name); -#else - return type.GetProperty(name); -#endif - } - - internal static IEnumerable GetFieldsPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeFields(); -#else - return type.GetFields(); -#endif - } - - internal static Type GetBaseTypePortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().BaseType; -#else - return type.BaseType; -#endif - } - -#if LIBLOG_PORTABLE - internal static MethodInfo GetGetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.GetMethod; - } - - internal static MethodInfo GetSetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.SetMethod; - } -#endif - -#if !LIBLOG_PORTABLE - internal static object CreateDelegate(this MethodInfo methodInfo, Type delegateType) - { - return Delegate.CreateDelegate(delegateType, methodInfo); - } -#endif - - internal static Assembly GetAssemblyPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().Assembly; -#else - return type.Assembly; -#endif - } - } - - internal class DisposableAction : IDisposable - { - private readonly Action _onDispose; - - public DisposableAction(Action onDispose = null) - { - _onDispose = onDispose; - } - - public void Dispose() - { - if(_onDispose != null) - { - _onDispose(); - } - } - } -} diff --git a/Src/Solid-TradeService/1.CQS_Maybe/Maybe.cs b/Src/Solid-TradeService/1.CQS_Maybe/Maybe.cs deleted file mode 100644 index bc37dff..0000000 --- a/Src/Solid-TradeService/1.CQS_Maybe/Maybe.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace TradeApp -{ - public class Maybe : IEnumerable - { - - private readonly IEnumerable _values; - - public Maybe() - { - _values = new T[0]; - } - - public Maybe(T value) - { - if (value == null) throw new ArgumentNullException(nameof(value)); - _values = new[] {value}; - } - - public IEnumerator GetEnumerator() - { - return _values.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} diff --git a/Src/Solid-TradeService/1.CQS_Maybe/Models/OrderDirection.cs b/Src/Solid-TradeService/1.CQS_Maybe/Models/OrderDirection.cs deleted file mode 100644 index c0df608..0000000 --- a/Src/Solid-TradeService/1.CQS_Maybe/Models/OrderDirection.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace TradeApp.Models -{ - public enum OrderDirection - { - Buy, - Sell - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/1.CQS_Maybe/Program.cs b/Src/Solid-TradeService/1.CQS_Maybe/Program.cs deleted file mode 100644 index 01b4d6a..0000000 --- a/Src/Solid-TradeService/1.CQS_Maybe/Program.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Linq; -using TradeApp.App_Packages.LibLog._4._2; -using TradeApp.Models; - -namespace TradeApp -{ - class Program - { - static void Main(string[] args) - { - string username = Environment.UserName; - - Logging.LogProvider.SetCurrentLogProvider(new ColoredConsoleLogProvider()); - - DealService service = new DealService(username); - - var id = Guid.NewGuid().ToString(); - var deal = new Deal - { - Id = id, - Price = 500.00, - Quantity = 10, - Symbol = "MSFT", - Time = DateTime.Now - }; - - service.Save(id, deal); - - Console.WriteLine(service.GetFileName(id)); - - Console.WriteLine(); - Console.WriteLine(); - - - var defaultDeal = new Deal - { - Id = "UnSet", - Price = 0, - Quantity = 0, - Symbol = "UnSet", - Time = DateTime.MinValue - }; - - - - var vincentDeal = service.Load(id).DefaultIfEmpty(defaultDeal).Single(); - Console.WriteLine(vincentDeal); - - Console.ReadLine(); - } - } -} diff --git a/Src/Solid-TradeService/1.CQS_Maybe/Properties/AssemblyInfo.cs b/Src/Solid-TradeService/1.CQS_Maybe/Properties/AssemblyInfo.cs deleted file mode 100644 index b681b7c..0000000 --- a/Src/Solid-TradeService/1.CQS_Maybe/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -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("TradeApp")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TradeApp")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[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("bba07b19-254a-4ef0-bcc5-f8954c963537")] - -// 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")] diff --git a/Src/Solid-TradeService/1.CQS_Maybe/Readme.md b/Src/Solid-TradeService/1.CQS_Maybe/Readme.md deleted file mode 100644 index 0cca6d3..0000000 --- a/Src/Solid-TradeService/1.CQS_Maybe/Readme.md +++ /dev/null @@ -1,11 +0,0 @@ -# Step 1 : Apply Command Query Segregation and Handle invariant - -- Check that all queries return something ! and have no side effect -- Check that command do not return data -- Then refactor if needed -- Handle pre-condition - - Add Guard clause in constructor that throw ArgumentNullException - - Add Guard clause for directory to fail fast - - Add Guard clause in methods for file to fail fast -- Handle post-condition - - Use Maybe monad to garanted output (not null) \ No newline at end of file diff --git a/Src/Solid-TradeService/1.CQS_Maybe/TradeApp.csproj b/Src/Solid-TradeService/1.CQS_Maybe/TradeApp.csproj deleted file mode 100644 index b72fe5a..0000000 --- a/Src/Solid-TradeService/1.CQS_Maybe/TradeApp.csproj +++ /dev/null @@ -1,76 +0,0 @@ - - - - - Debug - AnyCPU - {8C216700-5A1E-4F66-BC79-3A24EF7E1EC4} - Exe - Properties - TradeApp - TradeApp - v4.6 - 512 - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - True - - - - ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - True - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/1.CQS_Maybe/packages.config b/Src/Solid-TradeService/1.CQS_Maybe/packages.config deleted file mode 100644 index 557b51e..0000000 --- a/Src/Solid-TradeService/1.CQS_Maybe/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/2.SRP/App.config b/Src/Solid-TradeService/2.SRP/App.config deleted file mode 100644 index 8324aa6..0000000 --- a/Src/Solid-TradeService/2.SRP/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/2.SRP/DealCaching.cs b/Src/Solid-TradeService/2.SRP/DealCaching.cs deleted file mode 100644 index ea43e84..0000000 --- a/Src/Solid-TradeService/2.SRP/DealCaching.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Immutable; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealCaching - { - private ImmutableDictionary _cache; - - public DealCaching() - { - _cache = ImmutableDictionary.Empty; - } - public void AddOrUpdate(string id, Deal deal) - { - ImmutableInterlocked.AddOrUpdate(ref _cache, id, deal, (i, d) => deal); - } - - public Deal GetOrAdd(string id, Func dealFactory ) - { - return ImmutableInterlocked.GetOrAdd(ref _cache, id, dealFactory); - } - } -} diff --git a/Src/Solid-TradeService/2.SRP/DealSerializer.cs b/Src/Solid-TradeService/2.SRP/DealSerializer.cs deleted file mode 100644 index d271e58..0000000 --- a/Src/Solid-TradeService/2.SRP/DealSerializer.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Newtonsoft.Json; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealSerializer - { - public string SerializeDeal(Deal deal) - { - return JsonConvert.SerializeObject(deal); - } - - public Deal DeserializeDeal(string serializedDeal) - { - return JsonConvert.DeserializeObject(serializedDeal); - } - } -} diff --git a/Src/Solid-TradeService/2.SRP/DealService.cs b/Src/Solid-TradeService/2.SRP/DealService.cs deleted file mode 100644 index 195fcde..0000000 --- a/Src/Solid-TradeService/2.SRP/DealService.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.IO; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealService - { - private readonly DealServiceLogger _dealServiceLogger = new DealServiceLogger(); - private readonly DealCaching _dealCaching = new DealCaching(); - private readonly DealStorage _dealStorage = new DealStorage(); - private readonly DealSerializer _dealSerializer = new DealSerializer(); - - public DealService(string username) - { - if(username == null) - { throw new ArgumentNullException(nameof(username)); } - - if (!Directory.Exists(username)) - { Directory.CreateDirectory(username); } - - Username = username; - } - - public string Username { get; } - - public void Save(string id, Deal deal) - { - _dealServiceLogger.Saving(deal); - var file = _dealStorage.GetFileName(id,Username); - var serializedDeal = _dealSerializer.SerializeDeal(deal); - _dealStorage.WriteDeal(file.FullName,serializedDeal); - _dealCaching.AddOrUpdate(id, deal); - _dealServiceLogger.Saved(deal); - } - - public Maybe Load(string id) - { - _dealServiceLogger.Loading(id); - var file = _dealStorage.GetFileName(id,Username); - - if (!file.Exists) - { - _dealServiceLogger.DidNotFind(id); - return new Maybe(); - } - - try - { - var deal = _dealCaching.GetOrAdd(id, _ => - _dealSerializer.DeserializeDeal(_dealStorage.ReadDeal(file.FullName))); - - _dealServiceLogger.Loaded(deal); - return new Maybe(deal); - } - catch (Exception) - { - return new Maybe(); - } - } - - - } -} diff --git a/Src/Solid-TradeService/2.SRP/DealServiceDiagram.cd b/Src/Solid-TradeService/2.SRP/DealServiceDiagram.cd deleted file mode 100644 index 4007499..0000000 --- a/Src/Solid-TradeService/2.SRP/DealServiceDiagram.cd +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - AAAIgIAEAAAAAAAAAQAAAAAAAAAAIAAAAAAAAgAAAAA= - DealService.cs - - - - - - - - - - - - AAAAAAAAAIAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAA= - DealCaching.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAABA= - DealSerializer.cs - - - - - - AAAAAAAAAIEAAAAAAAAIAICAIAAAAAAAAAAAAAAAAAA= - DealServiceLogger.cs - - - - - - AAAAAAAAAEAAAAAAAAAABAAAQAAAAAAAAAAAAAAAAAA= - DealStorage.cs - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/2.SRP/DealServiceLogger.cs b/Src/Solid-TradeService/2.SRP/DealServiceLogger.cs deleted file mode 100644 index 1be074d..0000000 --- a/Src/Solid-TradeService/2.SRP/DealServiceLogger.cs +++ /dev/null @@ -1,35 +0,0 @@ -using TradeApp.Logging; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealServiceLogger - { - private static readonly ILog _logger = LogProvider.For(); - - public void Saving(Deal deal) - { - _logger.Info($"Saving deal {deal.Id}."); - } - - public void Saved(Deal deal) - { - _logger.Info($"Saved deal {deal.Id}."); - } - - public void Loading(string id) - { - _logger.Info($"Loading deal {id}."); - } - - public void DidNotFind(string id) - { - _logger.Info($"No deal {id} found."); - } - - public void Loaded(Deal deal) - { - _logger.Info($"Returning deal {deal.Id}."); - } - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/2.SRP/DealStorage.cs b/Src/Solid-TradeService/2.SRP/DealStorage.cs deleted file mode 100644 index fce907a..0000000 --- a/Src/Solid-TradeService/2.SRP/DealStorage.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.IO; - -namespace TradeApp -{ - public class DealStorage - { - public void WriteDeal(string path, string serializedDeal) - { - File.WriteAllText(path, serializedDeal); - } - - public string ReadDeal(string path) - { - return File.ReadAllText(path); - } - - public FileInfo GetFileName(string id, string username) - { - return new FileInfo(Path.Combine(username, id + ".json")); - } - } -} diff --git a/Src/Solid-TradeService/2.SRP/Log/ColoredConsoleLogProvider.cs b/Src/Solid-TradeService/2.SRP/Log/ColoredConsoleLogProvider.cs deleted file mode 100644 index 6853892..0000000 --- a/Src/Solid-TradeService/2.SRP/Log/ColoredConsoleLogProvider.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using TradeApp.Logging; - -namespace TradeApp.App_Packages.LibLog._4._2 -{ - public class ColoredConsoleLogProvider : ILogProvider - { - private static readonly Dictionary Colors = new Dictionary - { - {LogLevel.Fatal, ConsoleColor.Red}, - {LogLevel.Error, ConsoleColor.Yellow}, - {LogLevel.Warn, ConsoleColor.Magenta}, - {LogLevel.Info, ConsoleColor.White}, - {LogLevel.Debug, ConsoleColor.Gray}, - {LogLevel.Trace, ConsoleColor.DarkGray}, - }; - - public Logger GetLogger(string name) - { - return (logLevel, messageFunc, exception, formatParameters) => - { - if (messageFunc == null) - { - return true; // All log levels are enabled - } - - ConsoleColor consoleColor; - if (Colors.TryGetValue(logLevel, out consoleColor)) - { - var originalForground = Console.ForegroundColor; - try - { - Console.ForegroundColor = consoleColor; - WriteMessage(logLevel, name, messageFunc, formatParameters, exception); - } - finally - { - Console.ForegroundColor = originalForground; - } - } - else - { - WriteMessage(logLevel, name, messageFunc, formatParameters, exception); - } - - return true; - }; - } - - private static void WriteMessage( - LogLevel logLevel, - string name, - Func messageFunc, - object[] formatParameters, - Exception exception) - { - var message = string.Format(CultureInfo.InvariantCulture, messageFunc(), formatParameters); - if (exception != null) - { - message = message + "|" + exception; - } - Console.WriteLine("{0} | {1} | {2} | {3}", DateTime.UtcNow, logLevel, name, message); - } - - public IDisposable OpenNestedContext(string message) - { - return NullDisposable.Instance; - } - - public IDisposable OpenMappedContext(string key, string value) - { - return NullDisposable.Instance; - } - - private class NullDisposable : IDisposable - { - internal static readonly IDisposable Instance = new NullDisposable(); - - public void Dispose() - { } - } - } -} diff --git a/Src/Solid-TradeService/2.SRP/Log/LibLog.cs b/Src/Solid-TradeService/2.SRP/Log/LibLog.cs deleted file mode 100644 index f761084..0000000 --- a/Src/Solid-TradeService/2.SRP/Log/LibLog.cs +++ /dev/null @@ -1,1998 +0,0 @@ -//=============================================================================== -// LibLog -// -// https://github.com/damianh/LibLog -//=============================================================================== -// Copyright © 2011-2015 Damian Hickey. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//=============================================================================== - -// ReSharper disable PossibleNullReferenceException - -// Define LIBLOG_PORTABLE conditional compilation symbol for PCL compatibility -// -// Define LIBLOG_PUBLIC to enable ability to GET a logger (LogProvider.For<>() etc) from outside this library. NOTE: -// this can have unintended consequences of consumers of your library using your library to resolve a logger. If the -// reason is because you want to open this functionality to other projects within your solution, -// consider [InternalVisibleTo] instead. -// -// Define LIBLOG_PROVIDERS_ONLY if your library provides its own logging API and you just want to use the -// LibLog providers internally to provide built in support for popular logging frameworks. - -#pragma warning disable 1591 - -// If you copied this file manually, you need to change all "YourRootNameSpace" so not to clash with other libraries -// that use LibLog -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog -#else -namespace TradeApp.Logging -#endif -{ - using System.Collections.Generic; -#if LIBLOG_PROVIDERS_ONLY - using TradeApp.LibLog.LogProviders; -#else - using TradeApp.Logging.LogProviders; -#endif - using System; -#if !LIBLOG_PROVIDERS_ONLY - using System.Diagnostics; -#if !LIBLOG_PORTABLE - using System.Runtime.CompilerServices; -#endif -#endif - -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - delegate bool Logger(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters); - -#if !LIBLOG_PROVIDERS_ONLY - /// - /// Simple interface that represent a logger. - /// -#if LIBLOG_PUBLIC - public -#else - internal -#endif - interface ILog - { - /// - /// Log a message the specified log level. - /// - /// The log level. - /// The message function. - /// An optional exception. - /// Optional format parameters for the message generated by the messagefunc. - /// true if the message was logged. Otherwise false. - /// - /// Note to implementers: the message func should not be called if the loglevel is not enabled - /// so as not to incur performance penalties. - /// - /// To check IsEnabled call Log with only LogLevel and check the return value, no event will be written. - /// - bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters ); - } -#endif - - /// - /// The log level. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - enum LogLevel - { - Trace, - Debug, - Info, - Warn, - Error, - Fatal - } - -#if !LIBLOG_PROVIDERS_ONLY -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static partial class LogExtensions - { - public static bool IsDebugEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Debug, null); - } - - public static bool IsErrorEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Error, null); - } - - public static bool IsFatalEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Fatal, null); - } - - public static bool IsInfoEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Info, null); - } - - public static bool IsTraceEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Trace, null); - } - - public static bool IsWarnEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Warn, null); - } - - public static void Debug(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Debug, messageFunc); - } - - public static void Debug(this ILog logger, string message) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc()); - } - } - - public static void DebugFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsDebugEnabled()) - { - logger.LogFormat(LogLevel.Debug, message, args); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception, formatParams); - } - } - - public static void Error(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Error, messageFunc); - } - - public static void Error(this ILog logger, string message) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc()); - } - } - - public static void ErrorFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsErrorEnabled()) - { - logger.LogFormat(LogLevel.Error, message, args); - } - } - - public static void ErrorException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc(), exception, formatParams); - } - } - - public static void Fatal(this ILog logger, Func messageFunc) - { - logger.Log(LogLevel.Fatal, messageFunc); - } - - public static void Fatal(this ILog logger, string message) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc()); - } - } - - public static void FatalFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsFatalEnabled()) - { - logger.LogFormat(LogLevel.Fatal, message, args); - } - } - - public static void FatalException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc(), exception, formatParams); - } - } - - public static void Info(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Info, messageFunc); - } - - public static void Info(this ILog logger, string message) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc()); - } - } - - public static void InfoFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsInfoEnabled()) - { - logger.LogFormat(LogLevel.Info, message, args); - } - } - - public static void InfoException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc(), exception, formatParams); - } - } - - public static void Trace(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Trace, messageFunc); - } - - public static void Trace(this ILog logger, string message) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc()); - } - } - - public static void TraceFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsTraceEnabled()) - { - logger.LogFormat(LogLevel.Trace, message, args); - } - } - - public static void TraceException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc(), exception, formatParams); - } - } - - public static void Warn(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Warn, messageFunc); - } - - public static void Warn(this ILog logger, string message) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc()); - } - } - - public static void WarnFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsWarnEnabled()) - { - logger.LogFormat(LogLevel.Warn, message, args); - } - } - - public static void WarnException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc(), exception, formatParams); - } - } - - // ReSharper disable once UnusedParameter.Local - private static void GuardAgainstNullLogger(ILog logger) - { - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - } - - private static void LogFormat(this ILog logger, LogLevel logLevel, string message, params object[] args) - { - logger.Log(logLevel, message.AsFunc(), null, args); - } - - // Avoid the closure allocation, see https://gist.github.com/AArnott/d285feef75c18f6ecd2b - private static Func AsFunc(this T value) where T : class - { - return value.Return; - } - - private static T Return(this T value) - { - return value; - } - } -#endif - - /// - /// Represents a way to get a - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - interface ILogProvider - { - /// - /// Gets the specified named logger. - /// - /// Name of the logger. - /// The logger reference. - Logger GetLogger(string name); - - /// - /// Opens a nested diagnostics context. Not supported in EntLib logging. - /// - /// The message to add to the diagnostics context. - /// A disposable that when disposed removes the message from the context. - IDisposable OpenNestedContext(string message); - - /// - /// Opens a mapped diagnostics context. Not supported in EntLib logging. - /// - /// A key. - /// A value. - /// A disposable that when disposed removes the map from the context. - IDisposable OpenMappedContext(string key, string value); - } - - /// - /// Provides a mechanism to create instances of objects. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - static class LogProvider - { -#if !LIBLOG_PROVIDERS_ONLY - /// - /// The disable logging environment variable. If the environment variable is set to 'true', then logging - /// will be disabled. - /// - public const string DisableLoggingEnvironmentVariable = "TradeApp_LIBLOG_DISABLE"; - private const string NullLogProvider = "Current Log Provider is not set. Call SetCurrentLogProvider " + - "with a non-null value first."; - private static dynamic s_currentLogProvider; - private static Action s_onCurrentLogProviderSet; - - static LogProvider() - { - IsDisabled = false; - } - - /// - /// Sets the current log provider. - /// - /// The log provider. - public static void SetCurrentLogProvider(ILogProvider logProvider) - { - s_currentLogProvider = logProvider; - - RaiseOnCurrentLogProviderSet(); - } - - /// - /// Gets or sets a value indicating whether this is logging is disabled. - /// - /// - /// true if logging is disabled; otherwise, false. - /// - public static bool IsDisabled { get; set; } - - /// - /// Sets an action that is invoked when a consumer of your library has called SetCurrentLogProvider. It is - /// important that hook into this if you are using child libraries (especially ilmerged ones) that are using - /// LibLog (or other logging abstraction) so you adapt and delegate to them. - /// - /// - internal static Action OnCurrentLogProviderSet - { - set - { - s_onCurrentLogProviderSet = value; - RaiseOnCurrentLogProviderSet(); - } - } - - internal static ILogProvider CurrentLogProvider - { - get - { - return s_currentLogProvider; - } - } - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog For() - { - return GetLogger(typeof(T)); - } - -#if !LIBLOG_PORTABLE - /// - /// Gets a logger for the current class. - /// - /// An instance of - [MethodImpl(MethodImplOptions.NoInlining)] -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetCurrentClassLogger() - { - var stackFrame = new StackFrame(1, false); - return GetLogger(stackFrame.GetMethod().DeclaringType); - } -#endif - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(Type type) - { - return GetLogger(type.FullName); - } - - /// - /// Gets a logger with the specified name. - /// - /// The name. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(string name) - { - ILogProvider logProvider = CurrentLogProvider ?? ResolveLogProvider(); - return logProvider == null - ? NoOpLogger.Instance - : (ILog)new LoggerExecutionWrapper(logProvider.GetLogger(name), () => IsDisabled); - } - - /// - /// Opens a nested diagnostics context. - /// - /// A message. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenNestedContext(string message) - { - if(CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenNestedContext(message); - } - - /// - /// Opens a mapped diagnostics context. - /// - /// A key. - /// A value. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenMappedContext(string key, string value) - { - if (CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenMappedContext(key, value); - } -#endif - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate bool IsLoggerAvailable(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate ILogProvider CreateLogProvider(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - static readonly List> LogProviderResolvers = - new List> - { - new Tuple(SerilogLogProvider.IsLoggerAvailable, () => new SerilogLogProvider()), - new Tuple(NLogLogProvider.IsLoggerAvailable, () => new NLogLogProvider()), - new Tuple(Log4NetLogProvider.IsLoggerAvailable, () => new Log4NetLogProvider()), - new Tuple(EntLibLogProvider.IsLoggerAvailable, () => new EntLibLogProvider()), - new Tuple(LoupeLogProvider.IsLoggerAvailable, () => new LoupeLogProvider()), - }; - -#if !LIBLOG_PROVIDERS_ONLY - private static void RaiseOnCurrentLogProviderSet() - { - if (s_onCurrentLogProviderSet != null) - { - s_onCurrentLogProviderSet(s_currentLogProvider); - } - } -#endif - - internal static ILogProvider ResolveLogProvider() - { - try - { - foreach (var providerResolver in LogProviderResolvers) - { - if (providerResolver.Item1()) - { - return providerResolver.Item2(); - } - } - } - catch (Exception ex) - { -#if LIBLOG_PORTABLE - Debug.WriteLine( -#else - Console.WriteLine( -#endif - "Exception occurred resolving a log provider. Logging for this assembly {0} is disabled. {1}", - typeof(LogProvider).GetAssemblyPortable().FullName, - ex); - } - return null; - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class NoOpLogger : ILog - { - internal static readonly NoOpLogger Instance = new NoOpLogger(); - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - return false; - } - } -#endif - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class LoggerExecutionWrapper : ILog - { - private readonly Logger _logger; - private readonly Func _getIsDisabled; - internal const string FailedToGenerateLogMessage = "Failed to generate log message"; - - internal LoggerExecutionWrapper(Logger logger, Func getIsDisabled = null) - { - _logger = logger; - _getIsDisabled = getIsDisabled ?? (() => false); - } - - internal Logger WrappedLogger - { - get { return _logger; } - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters) - { - if (_getIsDisabled()) - { - return false; - } -#if !LIBLOG_PORTABLE - var envVar = Environment.GetEnvironmentVariable(LogProvider.DisableLoggingEnvironmentVariable); - - if (envVar != null && envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) - { - return false; - } -#endif - - if (messageFunc == null) - { - return _logger(logLevel, null); - } - - Func wrappedMessageFunc = () => - { - try - { - return messageFunc(); - } - catch (Exception ex) - { - Log(LogLevel.Error, () => FailedToGenerateLogMessage, ex); - } - return null; - }; - return _logger(logLevel, wrappedMessageFunc, exception, formatParameters); - } - } -#endif -} - -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog.LogProviders -#else -namespace TradeApp.Logging.LogProviders -#endif -{ - using System; - using System.Collections.Generic; -#if !LIBLOG_PORTABLE - using System.Diagnostics; -#endif - using System.Globalization; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; -#if !LIBLOG_PORTABLE - using System.Text; -#endif - using System.Text.RegularExpressions; - - internal abstract class LogProviderBase : ILogProvider - { - protected delegate IDisposable OpenNdc(string message); - protected delegate IDisposable OpenMdc(string key, string value); - - private readonly Lazy _lazyOpenNdcMethod; - private readonly Lazy _lazyOpenMdcMethod; - private static readonly IDisposable NoopDisposableInstance = new DisposableAction(); - - protected LogProviderBase() - { - _lazyOpenNdcMethod - = new Lazy(GetOpenNdcMethod); - _lazyOpenMdcMethod - = new Lazy(GetOpenMdcMethod); - } - - public abstract Logger GetLogger(string name); - - public IDisposable OpenNestedContext(string message) - { - return _lazyOpenNdcMethod.Value(message); - } - - public IDisposable OpenMappedContext(string key, string value) - { - return _lazyOpenMdcMethod.Value(key, value); - } - - protected virtual OpenNdc GetOpenNdcMethod() - { - return _ => NoopDisposableInstance; - } - - protected virtual OpenMdc GetOpenMdcMethod() - { - return (_, __) => NoopDisposableInstance; - } - } - - internal class NLogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public NLogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("NLog.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new NLogLogger(_getLoggerByNameDelegate(name)).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("NLog.NestedDiagnosticsContext, NLog"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("NLog.MappedDiagnosticsContext, NLog"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("NLog.LogManager, NLog"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class NLogLogger - { - private readonly dynamic _logger; - - internal NLogLogger(dynamic logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - if(exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.Debug(messageFunc()); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.Info(messageFunc()); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.Warn(messageFunc()); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.Error(messageFunc()); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.Fatal(messageFunc()); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.Trace(messageFunc()); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.DebugException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.InfoException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.WarnException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.ErrorException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.FatalException(messageFunc(), exception); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.TraceException(messageFunc(), exception); - return true; - } - break; - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Debug: - return _logger.IsDebugEnabled; - case LogLevel.Info: - return _logger.IsInfoEnabled; - case LogLevel.Warn: - return _logger.IsWarnEnabled; - case LogLevel.Error: - return _logger.IsErrorEnabled; - case LogLevel.Fatal: - return _logger.IsFatalEnabled; - default: - return _logger.IsTraceEnabled; - } - } - } - } - - internal class Log4NetLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public Log4NetLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("log4net.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new Log4NetLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("log4net.NDC, log4net"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("log4net.MDC, log4net"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("log4net.LogManager, log4net"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class Log4NetLogger - { - private readonly dynamic _logger; - private static Type s_callerStackBoundaryType; - private static readonly object CallerStackBoundaryTypeSync = new object(); - - private readonly object _levelDebug; - private readonly object _levelInfo; - private readonly object _levelWarn; - private readonly object _levelError; - private readonly object _levelFatal; - private readonly Func _isEnabledForDelegate; - private readonly Action _logDelegate; - - internal Log4NetLogger(dynamic logger) - { - _logger = logger.Logger; - - var logEventLevelType = Type.GetType("log4net.Core.Level, log4net"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type log4net.Core.Level was not found."); - } - - var levelFields = logEventLevelType.GetFieldsPortable().ToList(); - _levelDebug = levelFields.First(x => x.Name == "Debug").GetValue(null); - _levelInfo = levelFields.First(x => x.Name == "Info").GetValue(null); - _levelWarn = levelFields.First(x => x.Name == "Warn").GetValue(null); - _levelError = levelFields.First(x => x.Name == "Error").GetValue(null); - _levelFatal = levelFields.First(x => x.Name == "Fatal").GetValue(null); - - // Func isEnabledFor = (logger, level) => { return ((log4net.Core.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("log4net.Core.ILogger, log4net"); - if (loggerType == null) - { - throw new InvalidOperationException("Type log4net.Core.ILogger, was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabledFor", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression callerStackBoundaryDeclaringTypeParam = Expression.Parameter(typeof(Type)); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - _isEnabledForDelegate = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Log = - // (logger, callerStackBoundaryDeclaringType, level, message, exception) => { ((ILogger)logger).Write(callerStackBoundaryDeclaringType, level, message, exception); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Log", - typeof(Type), - logEventLevelType, - typeof(string), - typeof(Exception)); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - var writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - callerStackBoundaryDeclaringTypeParam, - levelCast, - messageParam, - exceptionParam); - _logDelegate = Expression.Lambda>( - writeMethodExp, - instanceParam, - callerStackBoundaryDeclaringTypeParam, - levelParam, - messageParam, - exceptionParam).Compile(); - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - - if (!IsLogLevelEnable(logLevel)) - { - return false; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - // determine correct caller - this might change due to jit optimizations with method inlining - if (s_callerStackBoundaryType == null) - { - lock (CallerStackBoundaryTypeSync) - { -#if !LIBLOG_PORTABLE - StackTrace stack = new StackTrace(); - Type thisType = GetType(); - s_callerStackBoundaryType = Type.GetType("LoggerExecutionWrapper"); - for (var i = 1; i < stack.FrameCount; i++) - { - if (!IsInTypeHierarchy(thisType, stack.GetFrame(i).GetMethod().DeclaringType)) - { - s_callerStackBoundaryType = stack.GetFrame(i - 1).GetMethod().DeclaringType; - break; - } - } -#else - s_callerStackBoundaryType = typeof (LoggerExecutionWrapper); -#endif - } - } - - var translatedLevel = TranslateLevel(logLevel); - _logDelegate(_logger, s_callerStackBoundaryType, translatedLevel, messageFunc(), exception); - return true; - } - - private bool IsInTypeHierarchy(Type currentType, Type checkType) - { - while (currentType != null && currentType != typeof(object)) - { - if (currentType == checkType) - { - return true; - } - currentType = currentType.GetBaseTypePortable(); - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - var level = TranslateLevel(logLevel); - return _isEnabledForDelegate(_logger, level); - } - - private object TranslateLevel(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - case LogLevel.Debug: - return _levelDebug; - case LogLevel.Info: - return _levelInfo; - case LogLevel.Warn: - return _levelWarn; - case LogLevel.Error: - return _levelError; - case LogLevel.Fatal: - return _levelFatal; - default: - throw new ArgumentOutOfRangeException("logLevel", logLevel, null); - } - } - } - } - - internal class EntLibLogProvider : LogProviderBase - { - private const string TypeTemplate = "Microsoft.Practices.EnterpriseLibrary.Logging.{0}, Microsoft.Practices.EnterpriseLibrary.Logging"; - private static bool s_providerIsAvailableOverride = true; - private static readonly Type LogEntryType; - private static readonly Type LoggerType; - private static readonly Type TraceEventTypeType; - private static readonly Action WriteLogEntry; - private static readonly Func ShouldLogEntry; - - static EntLibLogProvider() - { - LogEntryType = Type.GetType(string.Format(TypeTemplate, "LogEntry")); - LoggerType = Type.GetType(string.Format(TypeTemplate, "Logger")); - TraceEventTypeType = TraceEventTypeValues.Type; - if (LogEntryType == null - || TraceEventTypeType == null - || LoggerType == null) - { - return; - } - WriteLogEntry = GetWriteLogEntry(); - ShouldLogEntry = GetShouldLogEntry(); - } - - public EntLibLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Microsoft.Practices.EnterpriseLibrary.Logging.Logger not found"); - } - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new EntLibLogger(name, WriteLogEntry, ShouldLogEntry).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride - && TraceEventTypeType != null - && LogEntryType != null; - } - - private static Action GetWriteLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var messageParameter = Expression.Parameter(typeof(string), "message"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - messageParameter, - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("Write", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - messageParameter, - severityParameter).Compile(); - } - - private static Func GetShouldLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - Expression.Constant("***dummy***"), - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("ShouldLog", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - severityParameter).Compile(); - } - - private static MemberInitExpression GetWriteLogExpression(Expression message, - Expression severityParameter, ParameterExpression logNameParameter) - { - var entryType = LogEntryType; - MemberInitExpression memberInit = Expression.MemberInit(Expression.New(entryType), - Expression.Bind(entryType.GetPropertyPortable("Message"), message), - Expression.Bind(entryType.GetPropertyPortable("Severity"), severityParameter), - Expression.Bind( - entryType.GetPropertyPortable("TimeStamp"), - Expression.Property(null, typeof (DateTime).GetPropertyPortable("UtcNow"))), - Expression.Bind( - entryType.GetPropertyPortable("Categories"), - Expression.ListInit( - Expression.New(typeof (List)), - typeof (List).GetMethodPortable("Add", typeof (string)), - logNameParameter))); - return memberInit; - } - - internal class EntLibLogger - { - private readonly string _loggerName; - private readonly Action _writeLog; - private readonly Func _shouldLog; - - internal EntLibLogger(string loggerName, Action writeLog, Func shouldLog) - { - _loggerName = loggerName; - _writeLog = writeLog; - _shouldLog = shouldLog; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - var severity = MapSeverity(logLevel); - if (messageFunc == null) - { - return _shouldLog(_loggerName, severity); - } - - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - if (exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - _writeLog(_loggerName, messageFunc(), severity); - return true; - } - - public bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - var severity = MapSeverity(logLevel); - var message = messageFunc() + Environment.NewLine + exception; - _writeLog(_loggerName, message, severity); - return true; - } - - private static int MapSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Info: - return TraceEventTypeValues.Information; - default: - return TraceEventTypeValues.Verbose; - } - } - } - } - - internal class SerilogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public SerilogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Serilog.Log not found"); - } - _getLoggerByNameDelegate = GetForContextMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new SerilogLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - return message => GetPushProperty()("NDC", message); - } - - protected override OpenMdc GetOpenMdcMethod() - { - return (key, value) => GetPushProperty()(key, value); - } - - private static Func GetPushProperty() - { - Type ndcContextType = Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"); - MethodInfo pushPropertyMethod = ndcContextType.GetMethodPortable( - "PushProperty", - typeof(string), - typeof(object), - typeof(bool)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression pushPropertyMethodCall = Expression - .Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam); - var pushProperty = Expression - .Lambda>( - pushPropertyMethodCall, - nameParam, - valueParam, - destructureObjectParam) - .Compile(); - - return (key, value) => pushProperty(key, value, false); - } - - private static Type GetLogManagerType() - { - return Type.GetType("Serilog.Log, Serilog"); - } - - private static Func GetForContextMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("ForContext", typeof(string), typeof(object), typeof(bool)); - ParameterExpression propertyNameParam = Expression.Parameter(typeof(string), "propertyName"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectsParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression methodCall = Expression.Call(null, method, new Expression[] - { - propertyNameParam, - valueParam, - destructureObjectsParam - }); - var func = Expression.Lambda>( - methodCall, - propertyNameParam, - valueParam, - destructureObjectsParam) - .Compile(); - return name => func("Name", name, false); - } - - internal class SerilogLogger - { - private readonly object _logger; - private static readonly object DebugLevel; - private static readonly object ErrorLevel; - private static readonly object FatalLevel; - private static readonly object InformationLevel; - private static readonly object VerboseLevel; - private static readonly object WarningLevel; - private static readonly Func IsEnabled; - private static readonly Action Write; - private static readonly Action WriteException; - - static SerilogLogger() - { - var logEventLevelType = Type.GetType("Serilog.Events.LogEventLevel, Serilog"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type Serilog.Events.LogEventLevel was not found."); - } - DebugLevel = Enum.Parse(logEventLevelType, "Debug", false); - ErrorLevel = Enum.Parse(logEventLevelType, "Error", false); - FatalLevel = Enum.Parse(logEventLevelType, "Fatal", false); - InformationLevel = Enum.Parse(logEventLevelType, "Information", false); - VerboseLevel = Enum.Parse(logEventLevelType, "Verbose", false); - WarningLevel = Enum.Parse(logEventLevelType, "Warning", false); - - // Func isEnabled = (logger, level) => { return ((SeriLog.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("Serilog.ILogger, Serilog"); - if (loggerType == null) - { - throw new InvalidOperationException("Type Serilog.ILogger was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabled", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - IsEnabled = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Write = - // (logger, level, message, params) => { ((SeriLog.ILoggerILogger)logger).Write(level, message, params); } - MethodInfo writeMethodInfo = loggerType.GetMethodPortable("Write", logEventLevelType, typeof(string), typeof(object[])); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - ParameterExpression propertyValuesParam = Expression.Parameter(typeof(object[])); - MethodCallExpression writeMethodExp = Expression.Call( - instanceCast, - writeMethodInfo, - levelCast, - messageParam, - propertyValuesParam); - var expression = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - messageParam, - propertyValuesParam); - Write = expression.Compile(); - - // Action WriteException = - // (logger, level, exception, message) => { ((ILogger)logger).Write(level, exception, message, new object[]); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Write", - logEventLevelType, - typeof(Exception), - typeof(string), - typeof(object[])); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - levelCast, - exceptionParam, - messageParam, - propertyValuesParam); - WriteException = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - exceptionParam, - messageParam, - propertyValuesParam).Compile(); - } - - internal SerilogLogger(object logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsEnabled(_logger, logLevel); - } - if (exception != null) - { - return LogException(logLevel, messageFunc, exception, formatParameters); - } - - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - Write(_logger, DebugLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - Write(_logger, InformationLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - Write(_logger, WarningLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - Write(_logger, ErrorLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - Write(_logger, FatalLevel, messageFunc(), formatParameters); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - Write(_logger, VerboseLevel, messageFunc(), formatParameters); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception, object[] formatParams) - { - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - WriteException(_logger, DebugLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - WriteException(_logger, InformationLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - WriteException(_logger, WarningLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - WriteException(_logger, ErrorLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - WriteException(_logger, FatalLevel, exception, messageFunc(), formatParams); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - WriteException(_logger, VerboseLevel, exception, messageFunc(), formatParams); - return true; - } - break; - } - return false; - } - } - } - - internal class LoupeLogProvider : LogProviderBase - { - /// - /// The form of the Loupe Log.Write method we're using - /// - internal delegate void WriteDelegate( - int severity, - string logSystem, - int skipFrames, - Exception exception, - bool attributeToException, - int writeMode, - string detailsXml, - string category, - string caption, - string description, - params object[] args - ); - - private static bool s_providerIsAvailableOverride = true; - private readonly WriteDelegate _logWriteDelegate; - - public LoupeLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Gibraltar.Agent.Log (Loupe) not found"); - } - - _logWriteDelegate = GetLogWriteDelegate(); - } - - /// - /// Gets or sets a value indicating whether [provider is available override]. Used in tests. - /// - /// - /// true if [provider is available override]; otherwise, false. - /// - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new LoupeLogger(name, _logWriteDelegate).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - private static Type GetLogManagerType() - { - return Type.GetType("Gibraltar.Agent.Log, Gibraltar.Agent"); - } - - private static WriteDelegate GetLogWriteDelegate() - { - Type logManagerType = GetLogManagerType(); - Type logMessageSeverityType = Type.GetType("Gibraltar.Agent.LogMessageSeverity, Gibraltar.Agent"); - Type logWriteModeType = Type.GetType("Gibraltar.Agent.LogWriteMode, Gibraltar.Agent"); - - MethodInfo method = logManagerType.GetMethodPortable( - "Write", - logMessageSeverityType, typeof(string), typeof(int), typeof(Exception), typeof(bool), - logWriteModeType, typeof(string), typeof(string), typeof(string), typeof(string), typeof(object[])); - - var callDelegate = (WriteDelegate)method.CreateDelegate(typeof(WriteDelegate)); - return callDelegate; - } - - internal class LoupeLogger - { - private const string LogSystem = "LibLog"; - - private readonly string _category; - private readonly WriteDelegate _logWriteDelegate; - private readonly int _skipLevel; - - internal LoupeLogger(string category, WriteDelegate logWriteDelegate) - { - _category = category; - _logWriteDelegate = logWriteDelegate; -#if DEBUG - _skipLevel = 2; -#else - _skipLevel = 1; -#endif - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - //nothing to log.. - return true; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - _logWriteDelegate(ToLogMessageSeverity(logLevel), LogSystem, _skipLevel, exception, true, 0, null, - _category, null, messageFunc.Invoke()); - - return true; - } - - private int ToLogMessageSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - return TraceEventTypeValues.Verbose; - case LogLevel.Debug: - return TraceEventTypeValues.Verbose; - case LogLevel.Info: - return TraceEventTypeValues.Information; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - default: - throw new ArgumentOutOfRangeException("logLevel"); - } - } - } - } - - internal static class TraceEventTypeValues - { - internal static readonly Type Type; - internal static readonly int Verbose; - internal static readonly int Information; - internal static readonly int Warning; - internal static readonly int Error; - internal static readonly int Critical; - - static TraceEventTypeValues() - { - var assembly = typeof(Uri).GetAssemblyPortable(); // This is to get to the System.dll assembly in a PCL compatible way. - if (assembly == null) - { - return; - } - Type = assembly.GetType("System.Diagnostics.TraceEventType"); - if (Type == null) return; - Verbose = (int)Enum.Parse(Type, "Verbose", false); - Information = (int)Enum.Parse(Type, "Information", false); - Warning = (int)Enum.Parse(Type, "Warning", false); - Error = (int)Enum.Parse(Type, "Error", false); - Critical = (int)Enum.Parse(Type, "Critical", false); - } - } - - internal static class LogMessageFormatter - { - private static readonly Regex Pattern = new Regex(@"\{@?\w{1,}\}"); - - /// - /// Some logging frameworks support structured logging, such as serilog. This will allow you to add names to structured data in a format string: - /// For example: Log("Log message to {user}", user). This only works with serilog, but as the user of LibLog, you don't know if serilog is actually - /// used. So, this class simulates that. it will replace any text in {curly braces} with an index number. - /// - /// "Log {message} to {user}" would turn into => "Log {0} to {1}". Then the format parameters are handled using regular .net string.Format. - /// - /// The message builder. - /// The format parameters. - /// - public static Func SimulateStructuredLogging(Func messageBuilder, object[] formatParameters) - { - if (formatParameters == null || formatParameters.Length == 0) - { - return messageBuilder; - } - - return () => - { - string targetMessage = messageBuilder(); - int argumentIndex = 0; - foreach (Match match in Pattern.Matches(targetMessage)) - { - int notUsed; - if (!int.TryParse(match.Value.Substring(1, match.Value.Length -2), out notUsed)) - { - targetMessage = ReplaceFirst(targetMessage, match.Value, - "{" + argumentIndex++ + "}"); - } - } - try - { - return string.Format(CultureInfo.InvariantCulture, targetMessage, formatParameters); - } - catch (FormatException ex) - { - throw new FormatException("The input string '" + targetMessage + "' could not be formatted using string.Format", ex); - } - }; - } - - private static string ReplaceFirst(string text, string search, string replace) - { - int pos = text.IndexOf(search, StringComparison.Ordinal); - if (pos < 0) - { - return text; - } - return text.Substring(0, pos) + replace + text.Substring(pos + search.Length); - } - } - - internal static class TypeExtensions - { - internal static MethodInfo GetMethodPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, new Type[]{}); -#else - return type.GetMethod(name); -#endif - } - - internal static MethodInfo GetMethodPortable(this Type type, string name, params Type[] types) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, types); -#else - return type.GetMethod(name, types); -#endif - } - - internal static PropertyInfo GetPropertyPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeProperty(name); -#else - return type.GetProperty(name); -#endif - } - - internal static IEnumerable GetFieldsPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeFields(); -#else - return type.GetFields(); -#endif - } - - internal static Type GetBaseTypePortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().BaseType; -#else - return type.BaseType; -#endif - } - -#if LIBLOG_PORTABLE - internal static MethodInfo GetGetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.GetMethod; - } - - internal static MethodInfo GetSetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.SetMethod; - } -#endif - -#if !LIBLOG_PORTABLE - internal static object CreateDelegate(this MethodInfo methodInfo, Type delegateType) - { - return Delegate.CreateDelegate(delegateType, methodInfo); - } -#endif - - internal static Assembly GetAssemblyPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().Assembly; -#else - return type.Assembly; -#endif - } - } - - internal class DisposableAction : IDisposable - { - private readonly Action _onDispose; - - public DisposableAction(Action onDispose = null) - { - _onDispose = onDispose; - } - - public void Dispose() - { - if(_onDispose != null) - { - _onDispose(); - } - } - } -} diff --git a/Src/Solid-TradeService/2.SRP/Maybe.cs b/Src/Solid-TradeService/2.SRP/Maybe.cs deleted file mode 100644 index bc37dff..0000000 --- a/Src/Solid-TradeService/2.SRP/Maybe.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace TradeApp -{ - public class Maybe : IEnumerable - { - - private readonly IEnumerable _values; - - public Maybe() - { - _values = new T[0]; - } - - public Maybe(T value) - { - if (value == null) throw new ArgumentNullException(nameof(value)); - _values = new[] {value}; - } - - public IEnumerator GetEnumerator() - { - return _values.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} diff --git a/Src/Solid-TradeService/2.SRP/Models/Deal.cs b/Src/Solid-TradeService/2.SRP/Models/Deal.cs deleted file mode 100644 index da47454..0000000 --- a/Src/Solid-TradeService/2.SRP/Models/Deal.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -namespace TradeApp.Models -{ - public class Deal - { - private Deal(string id, double price, int quantity, string symbol, DateTime time) - { - Id = id; - Price = price; - Time = time; - Quantity = quantity; - Symbol = symbol; - } - - public static Deal Empty => new Deal("Empty", 0, 0, "Unset", DateTime.MinValue); - - public string Id { get; } - public double Price { get; } - public DateTime Time { get; } - public int Quantity { get; } - - public string Symbol { get; } - - public OrderDirection Direction - { - get { - return Quantity >= 0 ? OrderDirection.Buy : OrderDirection.Sell; - } - } - - public Deal With(string id = null, double? price = null, int? quantity = null, string symbol = null, DateTime? time = null) - { - return new Deal( - id ?? Id, - price ?? Price, - quantity ?? Quantity, - symbol ?? Symbol, - time ?? Time - ); - - } - - public override string ToString() - { - return $"OrderId: {Id} {Direction} order for {Quantity} unit{(Quantity == 1 ? "" : "s")} of {Symbol}"; - } - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/2.SRP/Models/OrderDirection.cs b/Src/Solid-TradeService/2.SRP/Models/OrderDirection.cs deleted file mode 100644 index c0df608..0000000 --- a/Src/Solid-TradeService/2.SRP/Models/OrderDirection.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace TradeApp.Models -{ - public enum OrderDirection - { - Buy, - Sell - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/2.SRP/Program.cs b/Src/Solid-TradeService/2.SRP/Program.cs deleted file mode 100644 index 8cc7c8d..0000000 --- a/Src/Solid-TradeService/2.SRP/Program.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Linq; -using TradeApp.App_Packages.LibLog._4._2; -using TradeApp.Models; - -namespace TradeApp -{ - class Program - { - static void Main(string[] args) - { - string username = Environment.UserName; - - Logging.LogProvider.SetCurrentLogProvider(new ColoredConsoleLogProvider()); - - DealService service = new DealService(username); - - var id = Guid.NewGuid().ToString(); - var deal = Deal.Empty.With( - id, - 500.00, - 10, - "MSFT", - DateTime.Now - ); - - service.Save(id, deal); - - - Console.WriteLine(); - Console.WriteLine(); - - var vincentDeal = service.Load(id).DefaultIfEmpty(Deal.Empty).Single(); - Console.WriteLine(vincentDeal); - - Console.ReadLine(); - } - } -} diff --git a/Src/Solid-TradeService/2.SRP/Properties/AssemblyInfo.cs b/Src/Solid-TradeService/2.SRP/Properties/AssemblyInfo.cs deleted file mode 100644 index b681b7c..0000000 --- a/Src/Solid-TradeService/2.SRP/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -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("TradeApp")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TradeApp")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[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("bba07b19-254a-4ef0-bcc5-f8954c963537")] - -// 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")] diff --git a/Src/Solid-TradeService/2.SRP/Readme.md b/Src/Solid-TradeService/2.SRP/Readme.md deleted file mode 100644 index ebe1ade..0000000 --- a/Src/Solid-TradeService/2.SRP/Readme.md +++ /dev/null @@ -1,9 +0,0 @@ -# Step 2 : Single Responsability Principle - -- Use specific type (fileinfo) -- Extract DealServiceLogger. (If log lib change, we now don't need to edit DealService) -- Extract Cache. (If cache use other data structure than ImmutableDictionary, we now don't need to edit DealService) -- Extract Serializer. (If we want to serializer in Xml or Protobuf we can without editing DealService)) -- Extract Storage. (If we want to store in SQL Database we can without editing DealService)) - -- Make deal immutable \ No newline at end of file diff --git a/Src/Solid-TradeService/2.SRP/TradeApp.csproj b/Src/Solid-TradeService/2.SRP/TradeApp.csproj deleted file mode 100644 index 6b27092..0000000 --- a/Src/Solid-TradeService/2.SRP/TradeApp.csproj +++ /dev/null @@ -1,81 +0,0 @@ - - - - - Debug - AnyCPU - {A2380718-A48F-4333-94F0-FAF25C9EE17E} - Exe - Properties - TradeApp - TradeApp - v4.6 - 512 - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - True - - - - ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/2.SRP/packages.config b/Src/Solid-TradeService/2.SRP/packages.config deleted file mode 100644 index 557b51e..0000000 --- a/Src/Solid-TradeService/2.SRP/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/3.OCP/App.config b/Src/Solid-TradeService/3.OCP/App.config deleted file mode 100644 index 8324aa6..0000000 --- a/Src/Solid-TradeService/3.OCP/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/3.OCP/DealCaching.cs b/Src/Solid-TradeService/3.OCP/DealCaching.cs deleted file mode 100644 index 53cd68d..0000000 --- a/Src/Solid-TradeService/3.OCP/DealCaching.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Immutable; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealCaching - { - private ImmutableDictionary _cache; - - public DealCaching() - { - _cache = ImmutableDictionary.Empty; - } - public virtual void AddOrUpdate(string id, Deal deal) - { - ImmutableInterlocked.AddOrUpdate(ref _cache, id, deal, (i, d) => deal); - } - - public virtual Deal GetOrAdd(string id, Func dealFactory ) - { - return ImmutableInterlocked.GetOrAdd(ref _cache, id, dealFactory); - } - } -} diff --git a/Src/Solid-TradeService/3.OCP/DealSerializer.cs b/Src/Solid-TradeService/3.OCP/DealSerializer.cs deleted file mode 100644 index c603b91..0000000 --- a/Src/Solid-TradeService/3.OCP/DealSerializer.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Newtonsoft.Json; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealSerializer - { - public virtual string SerializeDeal(Deal deal) - { - return JsonConvert.SerializeObject(deal); - } - - public virtual Deal DeserializeDeal(string serializedDeal) - { - return JsonConvert.DeserializeObject(serializedDeal); - } - } -} diff --git a/Src/Solid-TradeService/3.OCP/DealService.cs b/Src/Solid-TradeService/3.OCP/DealService.cs deleted file mode 100644 index 59fea59..0000000 --- a/Src/Solid-TradeService/3.OCP/DealService.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.IO; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealService - { - private readonly DealServiceLogger _dealServiceLogger; - private readonly DealCaching _dealCaching; - private readonly DealStorage _dealStorage; - private readonly DealSerializer _dealSerializer; - - public DealService(string username) - { - if(username == null) - { throw new ArgumentNullException(nameof(username)); } - - if (!Directory.Exists(username)) - { Directory.CreateDirectory(username); } - - Username = username; - _dealCaching = new DealCaching(); - _dealStorage = new DealStorage(); - _dealSerializer = new DealSerializer(); - _dealServiceLogger = new DealServiceLogger(); - } - - public virtual DealCaching DealCaching => _dealCaching; - - public virtual DealStorage DealStorage => _dealStorage; - - public virtual DealServiceLogger DealServiceLogger => _dealServiceLogger; - - public virtual DealSerializer DealSerializer => _dealSerializer; - - public string Username { get; } - - - public void Save(string id, Deal deal) - { - _dealServiceLogger.Saving(deal); - var file = _dealStorage.GetFileName(id,Username); - var serializedDeal = _dealSerializer.SerializeDeal(deal); - _dealStorage.WriteDeal(file.FullName,serializedDeal); - _dealCaching.AddOrUpdate(id, deal); - _dealServiceLogger.Saved(deal); - } - - public Maybe Load(string id) - { - _dealServiceLogger.Loading(id); - var file = _dealStorage.GetFileName(id,Username); - - if (!file.Exists) - { - _dealServiceLogger.DidNotFind(id); - return new Maybe(); - } - - try - { - var deal = _dealCaching.GetOrAdd(id, _ => - _dealSerializer.DeserializeDeal(_dealStorage.ReadDeal(file.FullName))); - - _dealServiceLogger.Loaded(deal); - return new Maybe(deal); - } - catch (Exception) - { - return new Maybe(); - } - } - - - } -} diff --git a/Src/Solid-TradeService/3.OCP/DealServiceDiagram.cd b/Src/Solid-TradeService/3.OCP/DealServiceDiagram.cd deleted file mode 100644 index 4007499..0000000 --- a/Src/Solid-TradeService/3.OCP/DealServiceDiagram.cd +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - AAAIgIAEAAAAAAAAAQAAAAAAAAAAIAAAAAAAAgAAAAA= - DealService.cs - - - - - - - - - - - - AAAAAAAAAIAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAA= - DealCaching.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAABA= - DealSerializer.cs - - - - - - AAAAAAAAAIEAAAAAAAAIAICAIAAAAAAAAAAAAAAAAAA= - DealServiceLogger.cs - - - - - - AAAAAAAAAEAAAAAAAAAABAAAQAAAAAAAAAAAAAAAAAA= - DealStorage.cs - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/3.OCP/DealServiceLogger.cs b/Src/Solid-TradeService/3.OCP/DealServiceLogger.cs deleted file mode 100644 index ab0996e..0000000 --- a/Src/Solid-TradeService/3.OCP/DealServiceLogger.cs +++ /dev/null @@ -1,35 +0,0 @@ -using TradeApp.Logging; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealServiceLogger - { - private static readonly ILog _logger = LogProvider.For(); - - public virtual void Saving(Deal deal) - { - _logger.Info($"Saving deal {deal.Id}."); - } - - public virtual void Saved(Deal deal) - { - _logger.Info($"Saved deal {deal.Id}."); - } - - public virtual void Loading(string id) - { - _logger.Info($"Loading deal {id}."); - } - - public virtual void DidNotFind(string id) - { - _logger.Info($"No deal {id} found."); - } - - public virtual void Loaded(Deal deal) - { - _logger.Info($"Returning deal {deal.Id}."); - } - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/3.OCP/DealStorage.cs b/Src/Solid-TradeService/3.OCP/DealStorage.cs deleted file mode 100644 index 78ee218..0000000 --- a/Src/Solid-TradeService/3.OCP/DealStorage.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.IO; - -namespace TradeApp -{ - public class DealStorage - { - public virtual void WriteDeal(string path, string serializedDeal) - { - File.WriteAllText(path, serializedDeal); - } - - public virtual string ReadDeal(string path) - { - return File.ReadAllText(path); - } - - public virtual FileInfo GetFileName(string id, string username) - { - return new FileInfo(Path.Combine(username, id + ".json")); - } - } -} diff --git a/Src/Solid-TradeService/3.OCP/Log/ColoredConsoleLogProvider.cs b/Src/Solid-TradeService/3.OCP/Log/ColoredConsoleLogProvider.cs deleted file mode 100644 index 6853892..0000000 --- a/Src/Solid-TradeService/3.OCP/Log/ColoredConsoleLogProvider.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using TradeApp.Logging; - -namespace TradeApp.App_Packages.LibLog._4._2 -{ - public class ColoredConsoleLogProvider : ILogProvider - { - private static readonly Dictionary Colors = new Dictionary - { - {LogLevel.Fatal, ConsoleColor.Red}, - {LogLevel.Error, ConsoleColor.Yellow}, - {LogLevel.Warn, ConsoleColor.Magenta}, - {LogLevel.Info, ConsoleColor.White}, - {LogLevel.Debug, ConsoleColor.Gray}, - {LogLevel.Trace, ConsoleColor.DarkGray}, - }; - - public Logger GetLogger(string name) - { - return (logLevel, messageFunc, exception, formatParameters) => - { - if (messageFunc == null) - { - return true; // All log levels are enabled - } - - ConsoleColor consoleColor; - if (Colors.TryGetValue(logLevel, out consoleColor)) - { - var originalForground = Console.ForegroundColor; - try - { - Console.ForegroundColor = consoleColor; - WriteMessage(logLevel, name, messageFunc, formatParameters, exception); - } - finally - { - Console.ForegroundColor = originalForground; - } - } - else - { - WriteMessage(logLevel, name, messageFunc, formatParameters, exception); - } - - return true; - }; - } - - private static void WriteMessage( - LogLevel logLevel, - string name, - Func messageFunc, - object[] formatParameters, - Exception exception) - { - var message = string.Format(CultureInfo.InvariantCulture, messageFunc(), formatParameters); - if (exception != null) - { - message = message + "|" + exception; - } - Console.WriteLine("{0} | {1} | {2} | {3}", DateTime.UtcNow, logLevel, name, message); - } - - public IDisposable OpenNestedContext(string message) - { - return NullDisposable.Instance; - } - - public IDisposable OpenMappedContext(string key, string value) - { - return NullDisposable.Instance; - } - - private class NullDisposable : IDisposable - { - internal static readonly IDisposable Instance = new NullDisposable(); - - public void Dispose() - { } - } - } -} diff --git a/Src/Solid-TradeService/3.OCP/Log/LibLog.cs b/Src/Solid-TradeService/3.OCP/Log/LibLog.cs deleted file mode 100644 index f761084..0000000 --- a/Src/Solid-TradeService/3.OCP/Log/LibLog.cs +++ /dev/null @@ -1,1998 +0,0 @@ -//=============================================================================== -// LibLog -// -// https://github.com/damianh/LibLog -//=============================================================================== -// Copyright © 2011-2015 Damian Hickey. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//=============================================================================== - -// ReSharper disable PossibleNullReferenceException - -// Define LIBLOG_PORTABLE conditional compilation symbol for PCL compatibility -// -// Define LIBLOG_PUBLIC to enable ability to GET a logger (LogProvider.For<>() etc) from outside this library. NOTE: -// this can have unintended consequences of consumers of your library using your library to resolve a logger. If the -// reason is because you want to open this functionality to other projects within your solution, -// consider [InternalVisibleTo] instead. -// -// Define LIBLOG_PROVIDERS_ONLY if your library provides its own logging API and you just want to use the -// LibLog providers internally to provide built in support for popular logging frameworks. - -#pragma warning disable 1591 - -// If you copied this file manually, you need to change all "YourRootNameSpace" so not to clash with other libraries -// that use LibLog -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog -#else -namespace TradeApp.Logging -#endif -{ - using System.Collections.Generic; -#if LIBLOG_PROVIDERS_ONLY - using TradeApp.LibLog.LogProviders; -#else - using TradeApp.Logging.LogProviders; -#endif - using System; -#if !LIBLOG_PROVIDERS_ONLY - using System.Diagnostics; -#if !LIBLOG_PORTABLE - using System.Runtime.CompilerServices; -#endif -#endif - -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - delegate bool Logger(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters); - -#if !LIBLOG_PROVIDERS_ONLY - /// - /// Simple interface that represent a logger. - /// -#if LIBLOG_PUBLIC - public -#else - internal -#endif - interface ILog - { - /// - /// Log a message the specified log level. - /// - /// The log level. - /// The message function. - /// An optional exception. - /// Optional format parameters for the message generated by the messagefunc. - /// true if the message was logged. Otherwise false. - /// - /// Note to implementers: the message func should not be called if the loglevel is not enabled - /// so as not to incur performance penalties. - /// - /// To check IsEnabled call Log with only LogLevel and check the return value, no event will be written. - /// - bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters ); - } -#endif - - /// - /// The log level. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - enum LogLevel - { - Trace, - Debug, - Info, - Warn, - Error, - Fatal - } - -#if !LIBLOG_PROVIDERS_ONLY -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static partial class LogExtensions - { - public static bool IsDebugEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Debug, null); - } - - public static bool IsErrorEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Error, null); - } - - public static bool IsFatalEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Fatal, null); - } - - public static bool IsInfoEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Info, null); - } - - public static bool IsTraceEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Trace, null); - } - - public static bool IsWarnEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Warn, null); - } - - public static void Debug(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Debug, messageFunc); - } - - public static void Debug(this ILog logger, string message) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc()); - } - } - - public static void DebugFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsDebugEnabled()) - { - logger.LogFormat(LogLevel.Debug, message, args); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception, formatParams); - } - } - - public static void Error(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Error, messageFunc); - } - - public static void Error(this ILog logger, string message) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc()); - } - } - - public static void ErrorFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsErrorEnabled()) - { - logger.LogFormat(LogLevel.Error, message, args); - } - } - - public static void ErrorException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc(), exception, formatParams); - } - } - - public static void Fatal(this ILog logger, Func messageFunc) - { - logger.Log(LogLevel.Fatal, messageFunc); - } - - public static void Fatal(this ILog logger, string message) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc()); - } - } - - public static void FatalFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsFatalEnabled()) - { - logger.LogFormat(LogLevel.Fatal, message, args); - } - } - - public static void FatalException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc(), exception, formatParams); - } - } - - public static void Info(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Info, messageFunc); - } - - public static void Info(this ILog logger, string message) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc()); - } - } - - public static void InfoFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsInfoEnabled()) - { - logger.LogFormat(LogLevel.Info, message, args); - } - } - - public static void InfoException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc(), exception, formatParams); - } - } - - public static void Trace(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Trace, messageFunc); - } - - public static void Trace(this ILog logger, string message) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc()); - } - } - - public static void TraceFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsTraceEnabled()) - { - logger.LogFormat(LogLevel.Trace, message, args); - } - } - - public static void TraceException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc(), exception, formatParams); - } - } - - public static void Warn(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Warn, messageFunc); - } - - public static void Warn(this ILog logger, string message) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc()); - } - } - - public static void WarnFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsWarnEnabled()) - { - logger.LogFormat(LogLevel.Warn, message, args); - } - } - - public static void WarnException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc(), exception, formatParams); - } - } - - // ReSharper disable once UnusedParameter.Local - private static void GuardAgainstNullLogger(ILog logger) - { - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - } - - private static void LogFormat(this ILog logger, LogLevel logLevel, string message, params object[] args) - { - logger.Log(logLevel, message.AsFunc(), null, args); - } - - // Avoid the closure allocation, see https://gist.github.com/AArnott/d285feef75c18f6ecd2b - private static Func AsFunc(this T value) where T : class - { - return value.Return; - } - - private static T Return(this T value) - { - return value; - } - } -#endif - - /// - /// Represents a way to get a - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - interface ILogProvider - { - /// - /// Gets the specified named logger. - /// - /// Name of the logger. - /// The logger reference. - Logger GetLogger(string name); - - /// - /// Opens a nested diagnostics context. Not supported in EntLib logging. - /// - /// The message to add to the diagnostics context. - /// A disposable that when disposed removes the message from the context. - IDisposable OpenNestedContext(string message); - - /// - /// Opens a mapped diagnostics context. Not supported in EntLib logging. - /// - /// A key. - /// A value. - /// A disposable that when disposed removes the map from the context. - IDisposable OpenMappedContext(string key, string value); - } - - /// - /// Provides a mechanism to create instances of objects. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - static class LogProvider - { -#if !LIBLOG_PROVIDERS_ONLY - /// - /// The disable logging environment variable. If the environment variable is set to 'true', then logging - /// will be disabled. - /// - public const string DisableLoggingEnvironmentVariable = "TradeApp_LIBLOG_DISABLE"; - private const string NullLogProvider = "Current Log Provider is not set. Call SetCurrentLogProvider " + - "with a non-null value first."; - private static dynamic s_currentLogProvider; - private static Action s_onCurrentLogProviderSet; - - static LogProvider() - { - IsDisabled = false; - } - - /// - /// Sets the current log provider. - /// - /// The log provider. - public static void SetCurrentLogProvider(ILogProvider logProvider) - { - s_currentLogProvider = logProvider; - - RaiseOnCurrentLogProviderSet(); - } - - /// - /// Gets or sets a value indicating whether this is logging is disabled. - /// - /// - /// true if logging is disabled; otherwise, false. - /// - public static bool IsDisabled { get; set; } - - /// - /// Sets an action that is invoked when a consumer of your library has called SetCurrentLogProvider. It is - /// important that hook into this if you are using child libraries (especially ilmerged ones) that are using - /// LibLog (or other logging abstraction) so you adapt and delegate to them. - /// - /// - internal static Action OnCurrentLogProviderSet - { - set - { - s_onCurrentLogProviderSet = value; - RaiseOnCurrentLogProviderSet(); - } - } - - internal static ILogProvider CurrentLogProvider - { - get - { - return s_currentLogProvider; - } - } - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog For() - { - return GetLogger(typeof(T)); - } - -#if !LIBLOG_PORTABLE - /// - /// Gets a logger for the current class. - /// - /// An instance of - [MethodImpl(MethodImplOptions.NoInlining)] -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetCurrentClassLogger() - { - var stackFrame = new StackFrame(1, false); - return GetLogger(stackFrame.GetMethod().DeclaringType); - } -#endif - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(Type type) - { - return GetLogger(type.FullName); - } - - /// - /// Gets a logger with the specified name. - /// - /// The name. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(string name) - { - ILogProvider logProvider = CurrentLogProvider ?? ResolveLogProvider(); - return logProvider == null - ? NoOpLogger.Instance - : (ILog)new LoggerExecutionWrapper(logProvider.GetLogger(name), () => IsDisabled); - } - - /// - /// Opens a nested diagnostics context. - /// - /// A message. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenNestedContext(string message) - { - if(CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenNestedContext(message); - } - - /// - /// Opens a mapped diagnostics context. - /// - /// A key. - /// A value. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenMappedContext(string key, string value) - { - if (CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenMappedContext(key, value); - } -#endif - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate bool IsLoggerAvailable(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate ILogProvider CreateLogProvider(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - static readonly List> LogProviderResolvers = - new List> - { - new Tuple(SerilogLogProvider.IsLoggerAvailable, () => new SerilogLogProvider()), - new Tuple(NLogLogProvider.IsLoggerAvailable, () => new NLogLogProvider()), - new Tuple(Log4NetLogProvider.IsLoggerAvailable, () => new Log4NetLogProvider()), - new Tuple(EntLibLogProvider.IsLoggerAvailable, () => new EntLibLogProvider()), - new Tuple(LoupeLogProvider.IsLoggerAvailable, () => new LoupeLogProvider()), - }; - -#if !LIBLOG_PROVIDERS_ONLY - private static void RaiseOnCurrentLogProviderSet() - { - if (s_onCurrentLogProviderSet != null) - { - s_onCurrentLogProviderSet(s_currentLogProvider); - } - } -#endif - - internal static ILogProvider ResolveLogProvider() - { - try - { - foreach (var providerResolver in LogProviderResolvers) - { - if (providerResolver.Item1()) - { - return providerResolver.Item2(); - } - } - } - catch (Exception ex) - { -#if LIBLOG_PORTABLE - Debug.WriteLine( -#else - Console.WriteLine( -#endif - "Exception occurred resolving a log provider. Logging for this assembly {0} is disabled. {1}", - typeof(LogProvider).GetAssemblyPortable().FullName, - ex); - } - return null; - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class NoOpLogger : ILog - { - internal static readonly NoOpLogger Instance = new NoOpLogger(); - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - return false; - } - } -#endif - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class LoggerExecutionWrapper : ILog - { - private readonly Logger _logger; - private readonly Func _getIsDisabled; - internal const string FailedToGenerateLogMessage = "Failed to generate log message"; - - internal LoggerExecutionWrapper(Logger logger, Func getIsDisabled = null) - { - _logger = logger; - _getIsDisabled = getIsDisabled ?? (() => false); - } - - internal Logger WrappedLogger - { - get { return _logger; } - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters) - { - if (_getIsDisabled()) - { - return false; - } -#if !LIBLOG_PORTABLE - var envVar = Environment.GetEnvironmentVariable(LogProvider.DisableLoggingEnvironmentVariable); - - if (envVar != null && envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) - { - return false; - } -#endif - - if (messageFunc == null) - { - return _logger(logLevel, null); - } - - Func wrappedMessageFunc = () => - { - try - { - return messageFunc(); - } - catch (Exception ex) - { - Log(LogLevel.Error, () => FailedToGenerateLogMessage, ex); - } - return null; - }; - return _logger(logLevel, wrappedMessageFunc, exception, formatParameters); - } - } -#endif -} - -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog.LogProviders -#else -namespace TradeApp.Logging.LogProviders -#endif -{ - using System; - using System.Collections.Generic; -#if !LIBLOG_PORTABLE - using System.Diagnostics; -#endif - using System.Globalization; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; -#if !LIBLOG_PORTABLE - using System.Text; -#endif - using System.Text.RegularExpressions; - - internal abstract class LogProviderBase : ILogProvider - { - protected delegate IDisposable OpenNdc(string message); - protected delegate IDisposable OpenMdc(string key, string value); - - private readonly Lazy _lazyOpenNdcMethod; - private readonly Lazy _lazyOpenMdcMethod; - private static readonly IDisposable NoopDisposableInstance = new DisposableAction(); - - protected LogProviderBase() - { - _lazyOpenNdcMethod - = new Lazy(GetOpenNdcMethod); - _lazyOpenMdcMethod - = new Lazy(GetOpenMdcMethod); - } - - public abstract Logger GetLogger(string name); - - public IDisposable OpenNestedContext(string message) - { - return _lazyOpenNdcMethod.Value(message); - } - - public IDisposable OpenMappedContext(string key, string value) - { - return _lazyOpenMdcMethod.Value(key, value); - } - - protected virtual OpenNdc GetOpenNdcMethod() - { - return _ => NoopDisposableInstance; - } - - protected virtual OpenMdc GetOpenMdcMethod() - { - return (_, __) => NoopDisposableInstance; - } - } - - internal class NLogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public NLogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("NLog.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new NLogLogger(_getLoggerByNameDelegate(name)).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("NLog.NestedDiagnosticsContext, NLog"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("NLog.MappedDiagnosticsContext, NLog"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("NLog.LogManager, NLog"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class NLogLogger - { - private readonly dynamic _logger; - - internal NLogLogger(dynamic logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - if(exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.Debug(messageFunc()); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.Info(messageFunc()); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.Warn(messageFunc()); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.Error(messageFunc()); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.Fatal(messageFunc()); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.Trace(messageFunc()); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.DebugException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.InfoException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.WarnException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.ErrorException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.FatalException(messageFunc(), exception); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.TraceException(messageFunc(), exception); - return true; - } - break; - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Debug: - return _logger.IsDebugEnabled; - case LogLevel.Info: - return _logger.IsInfoEnabled; - case LogLevel.Warn: - return _logger.IsWarnEnabled; - case LogLevel.Error: - return _logger.IsErrorEnabled; - case LogLevel.Fatal: - return _logger.IsFatalEnabled; - default: - return _logger.IsTraceEnabled; - } - } - } - } - - internal class Log4NetLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public Log4NetLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("log4net.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new Log4NetLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("log4net.NDC, log4net"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("log4net.MDC, log4net"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("log4net.LogManager, log4net"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class Log4NetLogger - { - private readonly dynamic _logger; - private static Type s_callerStackBoundaryType; - private static readonly object CallerStackBoundaryTypeSync = new object(); - - private readonly object _levelDebug; - private readonly object _levelInfo; - private readonly object _levelWarn; - private readonly object _levelError; - private readonly object _levelFatal; - private readonly Func _isEnabledForDelegate; - private readonly Action _logDelegate; - - internal Log4NetLogger(dynamic logger) - { - _logger = logger.Logger; - - var logEventLevelType = Type.GetType("log4net.Core.Level, log4net"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type log4net.Core.Level was not found."); - } - - var levelFields = logEventLevelType.GetFieldsPortable().ToList(); - _levelDebug = levelFields.First(x => x.Name == "Debug").GetValue(null); - _levelInfo = levelFields.First(x => x.Name == "Info").GetValue(null); - _levelWarn = levelFields.First(x => x.Name == "Warn").GetValue(null); - _levelError = levelFields.First(x => x.Name == "Error").GetValue(null); - _levelFatal = levelFields.First(x => x.Name == "Fatal").GetValue(null); - - // Func isEnabledFor = (logger, level) => { return ((log4net.Core.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("log4net.Core.ILogger, log4net"); - if (loggerType == null) - { - throw new InvalidOperationException("Type log4net.Core.ILogger, was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabledFor", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression callerStackBoundaryDeclaringTypeParam = Expression.Parameter(typeof(Type)); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - _isEnabledForDelegate = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Log = - // (logger, callerStackBoundaryDeclaringType, level, message, exception) => { ((ILogger)logger).Write(callerStackBoundaryDeclaringType, level, message, exception); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Log", - typeof(Type), - logEventLevelType, - typeof(string), - typeof(Exception)); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - var writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - callerStackBoundaryDeclaringTypeParam, - levelCast, - messageParam, - exceptionParam); - _logDelegate = Expression.Lambda>( - writeMethodExp, - instanceParam, - callerStackBoundaryDeclaringTypeParam, - levelParam, - messageParam, - exceptionParam).Compile(); - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - - if (!IsLogLevelEnable(logLevel)) - { - return false; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - // determine correct caller - this might change due to jit optimizations with method inlining - if (s_callerStackBoundaryType == null) - { - lock (CallerStackBoundaryTypeSync) - { -#if !LIBLOG_PORTABLE - StackTrace stack = new StackTrace(); - Type thisType = GetType(); - s_callerStackBoundaryType = Type.GetType("LoggerExecutionWrapper"); - for (var i = 1; i < stack.FrameCount; i++) - { - if (!IsInTypeHierarchy(thisType, stack.GetFrame(i).GetMethod().DeclaringType)) - { - s_callerStackBoundaryType = stack.GetFrame(i - 1).GetMethod().DeclaringType; - break; - } - } -#else - s_callerStackBoundaryType = typeof (LoggerExecutionWrapper); -#endif - } - } - - var translatedLevel = TranslateLevel(logLevel); - _logDelegate(_logger, s_callerStackBoundaryType, translatedLevel, messageFunc(), exception); - return true; - } - - private bool IsInTypeHierarchy(Type currentType, Type checkType) - { - while (currentType != null && currentType != typeof(object)) - { - if (currentType == checkType) - { - return true; - } - currentType = currentType.GetBaseTypePortable(); - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - var level = TranslateLevel(logLevel); - return _isEnabledForDelegate(_logger, level); - } - - private object TranslateLevel(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - case LogLevel.Debug: - return _levelDebug; - case LogLevel.Info: - return _levelInfo; - case LogLevel.Warn: - return _levelWarn; - case LogLevel.Error: - return _levelError; - case LogLevel.Fatal: - return _levelFatal; - default: - throw new ArgumentOutOfRangeException("logLevel", logLevel, null); - } - } - } - } - - internal class EntLibLogProvider : LogProviderBase - { - private const string TypeTemplate = "Microsoft.Practices.EnterpriseLibrary.Logging.{0}, Microsoft.Practices.EnterpriseLibrary.Logging"; - private static bool s_providerIsAvailableOverride = true; - private static readonly Type LogEntryType; - private static readonly Type LoggerType; - private static readonly Type TraceEventTypeType; - private static readonly Action WriteLogEntry; - private static readonly Func ShouldLogEntry; - - static EntLibLogProvider() - { - LogEntryType = Type.GetType(string.Format(TypeTemplate, "LogEntry")); - LoggerType = Type.GetType(string.Format(TypeTemplate, "Logger")); - TraceEventTypeType = TraceEventTypeValues.Type; - if (LogEntryType == null - || TraceEventTypeType == null - || LoggerType == null) - { - return; - } - WriteLogEntry = GetWriteLogEntry(); - ShouldLogEntry = GetShouldLogEntry(); - } - - public EntLibLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Microsoft.Practices.EnterpriseLibrary.Logging.Logger not found"); - } - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new EntLibLogger(name, WriteLogEntry, ShouldLogEntry).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride - && TraceEventTypeType != null - && LogEntryType != null; - } - - private static Action GetWriteLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var messageParameter = Expression.Parameter(typeof(string), "message"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - messageParameter, - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("Write", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - messageParameter, - severityParameter).Compile(); - } - - private static Func GetShouldLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - Expression.Constant("***dummy***"), - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("ShouldLog", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - severityParameter).Compile(); - } - - private static MemberInitExpression GetWriteLogExpression(Expression message, - Expression severityParameter, ParameterExpression logNameParameter) - { - var entryType = LogEntryType; - MemberInitExpression memberInit = Expression.MemberInit(Expression.New(entryType), - Expression.Bind(entryType.GetPropertyPortable("Message"), message), - Expression.Bind(entryType.GetPropertyPortable("Severity"), severityParameter), - Expression.Bind( - entryType.GetPropertyPortable("TimeStamp"), - Expression.Property(null, typeof (DateTime).GetPropertyPortable("UtcNow"))), - Expression.Bind( - entryType.GetPropertyPortable("Categories"), - Expression.ListInit( - Expression.New(typeof (List)), - typeof (List).GetMethodPortable("Add", typeof (string)), - logNameParameter))); - return memberInit; - } - - internal class EntLibLogger - { - private readonly string _loggerName; - private readonly Action _writeLog; - private readonly Func _shouldLog; - - internal EntLibLogger(string loggerName, Action writeLog, Func shouldLog) - { - _loggerName = loggerName; - _writeLog = writeLog; - _shouldLog = shouldLog; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - var severity = MapSeverity(logLevel); - if (messageFunc == null) - { - return _shouldLog(_loggerName, severity); - } - - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - if (exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - _writeLog(_loggerName, messageFunc(), severity); - return true; - } - - public bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - var severity = MapSeverity(logLevel); - var message = messageFunc() + Environment.NewLine + exception; - _writeLog(_loggerName, message, severity); - return true; - } - - private static int MapSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Info: - return TraceEventTypeValues.Information; - default: - return TraceEventTypeValues.Verbose; - } - } - } - } - - internal class SerilogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public SerilogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Serilog.Log not found"); - } - _getLoggerByNameDelegate = GetForContextMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new SerilogLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - return message => GetPushProperty()("NDC", message); - } - - protected override OpenMdc GetOpenMdcMethod() - { - return (key, value) => GetPushProperty()(key, value); - } - - private static Func GetPushProperty() - { - Type ndcContextType = Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"); - MethodInfo pushPropertyMethod = ndcContextType.GetMethodPortable( - "PushProperty", - typeof(string), - typeof(object), - typeof(bool)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression pushPropertyMethodCall = Expression - .Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam); - var pushProperty = Expression - .Lambda>( - pushPropertyMethodCall, - nameParam, - valueParam, - destructureObjectParam) - .Compile(); - - return (key, value) => pushProperty(key, value, false); - } - - private static Type GetLogManagerType() - { - return Type.GetType("Serilog.Log, Serilog"); - } - - private static Func GetForContextMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("ForContext", typeof(string), typeof(object), typeof(bool)); - ParameterExpression propertyNameParam = Expression.Parameter(typeof(string), "propertyName"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectsParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression methodCall = Expression.Call(null, method, new Expression[] - { - propertyNameParam, - valueParam, - destructureObjectsParam - }); - var func = Expression.Lambda>( - methodCall, - propertyNameParam, - valueParam, - destructureObjectsParam) - .Compile(); - return name => func("Name", name, false); - } - - internal class SerilogLogger - { - private readonly object _logger; - private static readonly object DebugLevel; - private static readonly object ErrorLevel; - private static readonly object FatalLevel; - private static readonly object InformationLevel; - private static readonly object VerboseLevel; - private static readonly object WarningLevel; - private static readonly Func IsEnabled; - private static readonly Action Write; - private static readonly Action WriteException; - - static SerilogLogger() - { - var logEventLevelType = Type.GetType("Serilog.Events.LogEventLevel, Serilog"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type Serilog.Events.LogEventLevel was not found."); - } - DebugLevel = Enum.Parse(logEventLevelType, "Debug", false); - ErrorLevel = Enum.Parse(logEventLevelType, "Error", false); - FatalLevel = Enum.Parse(logEventLevelType, "Fatal", false); - InformationLevel = Enum.Parse(logEventLevelType, "Information", false); - VerboseLevel = Enum.Parse(logEventLevelType, "Verbose", false); - WarningLevel = Enum.Parse(logEventLevelType, "Warning", false); - - // Func isEnabled = (logger, level) => { return ((SeriLog.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("Serilog.ILogger, Serilog"); - if (loggerType == null) - { - throw new InvalidOperationException("Type Serilog.ILogger was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabled", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - IsEnabled = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Write = - // (logger, level, message, params) => { ((SeriLog.ILoggerILogger)logger).Write(level, message, params); } - MethodInfo writeMethodInfo = loggerType.GetMethodPortable("Write", logEventLevelType, typeof(string), typeof(object[])); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - ParameterExpression propertyValuesParam = Expression.Parameter(typeof(object[])); - MethodCallExpression writeMethodExp = Expression.Call( - instanceCast, - writeMethodInfo, - levelCast, - messageParam, - propertyValuesParam); - var expression = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - messageParam, - propertyValuesParam); - Write = expression.Compile(); - - // Action WriteException = - // (logger, level, exception, message) => { ((ILogger)logger).Write(level, exception, message, new object[]); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Write", - logEventLevelType, - typeof(Exception), - typeof(string), - typeof(object[])); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - levelCast, - exceptionParam, - messageParam, - propertyValuesParam); - WriteException = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - exceptionParam, - messageParam, - propertyValuesParam).Compile(); - } - - internal SerilogLogger(object logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsEnabled(_logger, logLevel); - } - if (exception != null) - { - return LogException(logLevel, messageFunc, exception, formatParameters); - } - - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - Write(_logger, DebugLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - Write(_logger, InformationLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - Write(_logger, WarningLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - Write(_logger, ErrorLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - Write(_logger, FatalLevel, messageFunc(), formatParameters); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - Write(_logger, VerboseLevel, messageFunc(), formatParameters); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception, object[] formatParams) - { - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - WriteException(_logger, DebugLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - WriteException(_logger, InformationLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - WriteException(_logger, WarningLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - WriteException(_logger, ErrorLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - WriteException(_logger, FatalLevel, exception, messageFunc(), formatParams); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - WriteException(_logger, VerboseLevel, exception, messageFunc(), formatParams); - return true; - } - break; - } - return false; - } - } - } - - internal class LoupeLogProvider : LogProviderBase - { - /// - /// The form of the Loupe Log.Write method we're using - /// - internal delegate void WriteDelegate( - int severity, - string logSystem, - int skipFrames, - Exception exception, - bool attributeToException, - int writeMode, - string detailsXml, - string category, - string caption, - string description, - params object[] args - ); - - private static bool s_providerIsAvailableOverride = true; - private readonly WriteDelegate _logWriteDelegate; - - public LoupeLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Gibraltar.Agent.Log (Loupe) not found"); - } - - _logWriteDelegate = GetLogWriteDelegate(); - } - - /// - /// Gets or sets a value indicating whether [provider is available override]. Used in tests. - /// - /// - /// true if [provider is available override]; otherwise, false. - /// - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new LoupeLogger(name, _logWriteDelegate).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - private static Type GetLogManagerType() - { - return Type.GetType("Gibraltar.Agent.Log, Gibraltar.Agent"); - } - - private static WriteDelegate GetLogWriteDelegate() - { - Type logManagerType = GetLogManagerType(); - Type logMessageSeverityType = Type.GetType("Gibraltar.Agent.LogMessageSeverity, Gibraltar.Agent"); - Type logWriteModeType = Type.GetType("Gibraltar.Agent.LogWriteMode, Gibraltar.Agent"); - - MethodInfo method = logManagerType.GetMethodPortable( - "Write", - logMessageSeverityType, typeof(string), typeof(int), typeof(Exception), typeof(bool), - logWriteModeType, typeof(string), typeof(string), typeof(string), typeof(string), typeof(object[])); - - var callDelegate = (WriteDelegate)method.CreateDelegate(typeof(WriteDelegate)); - return callDelegate; - } - - internal class LoupeLogger - { - private const string LogSystem = "LibLog"; - - private readonly string _category; - private readonly WriteDelegate _logWriteDelegate; - private readonly int _skipLevel; - - internal LoupeLogger(string category, WriteDelegate logWriteDelegate) - { - _category = category; - _logWriteDelegate = logWriteDelegate; -#if DEBUG - _skipLevel = 2; -#else - _skipLevel = 1; -#endif - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - //nothing to log.. - return true; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - _logWriteDelegate(ToLogMessageSeverity(logLevel), LogSystem, _skipLevel, exception, true, 0, null, - _category, null, messageFunc.Invoke()); - - return true; - } - - private int ToLogMessageSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - return TraceEventTypeValues.Verbose; - case LogLevel.Debug: - return TraceEventTypeValues.Verbose; - case LogLevel.Info: - return TraceEventTypeValues.Information; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - default: - throw new ArgumentOutOfRangeException("logLevel"); - } - } - } - } - - internal static class TraceEventTypeValues - { - internal static readonly Type Type; - internal static readonly int Verbose; - internal static readonly int Information; - internal static readonly int Warning; - internal static readonly int Error; - internal static readonly int Critical; - - static TraceEventTypeValues() - { - var assembly = typeof(Uri).GetAssemblyPortable(); // This is to get to the System.dll assembly in a PCL compatible way. - if (assembly == null) - { - return; - } - Type = assembly.GetType("System.Diagnostics.TraceEventType"); - if (Type == null) return; - Verbose = (int)Enum.Parse(Type, "Verbose", false); - Information = (int)Enum.Parse(Type, "Information", false); - Warning = (int)Enum.Parse(Type, "Warning", false); - Error = (int)Enum.Parse(Type, "Error", false); - Critical = (int)Enum.Parse(Type, "Critical", false); - } - } - - internal static class LogMessageFormatter - { - private static readonly Regex Pattern = new Regex(@"\{@?\w{1,}\}"); - - /// - /// Some logging frameworks support structured logging, such as serilog. This will allow you to add names to structured data in a format string: - /// For example: Log("Log message to {user}", user). This only works with serilog, but as the user of LibLog, you don't know if serilog is actually - /// used. So, this class simulates that. it will replace any text in {curly braces} with an index number. - /// - /// "Log {message} to {user}" would turn into => "Log {0} to {1}". Then the format parameters are handled using regular .net string.Format. - /// - /// The message builder. - /// The format parameters. - /// - public static Func SimulateStructuredLogging(Func messageBuilder, object[] formatParameters) - { - if (formatParameters == null || formatParameters.Length == 0) - { - return messageBuilder; - } - - return () => - { - string targetMessage = messageBuilder(); - int argumentIndex = 0; - foreach (Match match in Pattern.Matches(targetMessage)) - { - int notUsed; - if (!int.TryParse(match.Value.Substring(1, match.Value.Length -2), out notUsed)) - { - targetMessage = ReplaceFirst(targetMessage, match.Value, - "{" + argumentIndex++ + "}"); - } - } - try - { - return string.Format(CultureInfo.InvariantCulture, targetMessage, formatParameters); - } - catch (FormatException ex) - { - throw new FormatException("The input string '" + targetMessage + "' could not be formatted using string.Format", ex); - } - }; - } - - private static string ReplaceFirst(string text, string search, string replace) - { - int pos = text.IndexOf(search, StringComparison.Ordinal); - if (pos < 0) - { - return text; - } - return text.Substring(0, pos) + replace + text.Substring(pos + search.Length); - } - } - - internal static class TypeExtensions - { - internal static MethodInfo GetMethodPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, new Type[]{}); -#else - return type.GetMethod(name); -#endif - } - - internal static MethodInfo GetMethodPortable(this Type type, string name, params Type[] types) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, types); -#else - return type.GetMethod(name, types); -#endif - } - - internal static PropertyInfo GetPropertyPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeProperty(name); -#else - return type.GetProperty(name); -#endif - } - - internal static IEnumerable GetFieldsPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeFields(); -#else - return type.GetFields(); -#endif - } - - internal static Type GetBaseTypePortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().BaseType; -#else - return type.BaseType; -#endif - } - -#if LIBLOG_PORTABLE - internal static MethodInfo GetGetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.GetMethod; - } - - internal static MethodInfo GetSetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.SetMethod; - } -#endif - -#if !LIBLOG_PORTABLE - internal static object CreateDelegate(this MethodInfo methodInfo, Type delegateType) - { - return Delegate.CreateDelegate(delegateType, methodInfo); - } -#endif - - internal static Assembly GetAssemblyPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().Assembly; -#else - return type.Assembly; -#endif - } - } - - internal class DisposableAction : IDisposable - { - private readonly Action _onDispose; - - public DisposableAction(Action onDispose = null) - { - _onDispose = onDispose; - } - - public void Dispose() - { - if(_onDispose != null) - { - _onDispose(); - } - } - } -} diff --git a/Src/Solid-TradeService/3.OCP/Maybe.cs b/Src/Solid-TradeService/3.OCP/Maybe.cs deleted file mode 100644 index bc37dff..0000000 --- a/Src/Solid-TradeService/3.OCP/Maybe.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace TradeApp -{ - public class Maybe : IEnumerable - { - - private readonly IEnumerable _values; - - public Maybe() - { - _values = new T[0]; - } - - public Maybe(T value) - { - if (value == null) throw new ArgumentNullException(nameof(value)); - _values = new[] {value}; - } - - public IEnumerator GetEnumerator() - { - return _values.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} diff --git a/Src/Solid-TradeService/3.OCP/Models/Deal.cs b/Src/Solid-TradeService/3.OCP/Models/Deal.cs deleted file mode 100644 index da47454..0000000 --- a/Src/Solid-TradeService/3.OCP/Models/Deal.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -namespace TradeApp.Models -{ - public class Deal - { - private Deal(string id, double price, int quantity, string symbol, DateTime time) - { - Id = id; - Price = price; - Time = time; - Quantity = quantity; - Symbol = symbol; - } - - public static Deal Empty => new Deal("Empty", 0, 0, "Unset", DateTime.MinValue); - - public string Id { get; } - public double Price { get; } - public DateTime Time { get; } - public int Quantity { get; } - - public string Symbol { get; } - - public OrderDirection Direction - { - get { - return Quantity >= 0 ? OrderDirection.Buy : OrderDirection.Sell; - } - } - - public Deal With(string id = null, double? price = null, int? quantity = null, string symbol = null, DateTime? time = null) - { - return new Deal( - id ?? Id, - price ?? Price, - quantity ?? Quantity, - symbol ?? Symbol, - time ?? Time - ); - - } - - public override string ToString() - { - return $"OrderId: {Id} {Direction} order for {Quantity} unit{(Quantity == 1 ? "" : "s")} of {Symbol}"; - } - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/3.OCP/Models/OrderDirection.cs b/Src/Solid-TradeService/3.OCP/Models/OrderDirection.cs deleted file mode 100644 index c0df608..0000000 --- a/Src/Solid-TradeService/3.OCP/Models/OrderDirection.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace TradeApp.Models -{ - public enum OrderDirection - { - Buy, - Sell - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/3.OCP/Program.cs b/Src/Solid-TradeService/3.OCP/Program.cs deleted file mode 100644 index 8cc7c8d..0000000 --- a/Src/Solid-TradeService/3.OCP/Program.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Linq; -using TradeApp.App_Packages.LibLog._4._2; -using TradeApp.Models; - -namespace TradeApp -{ - class Program - { - static void Main(string[] args) - { - string username = Environment.UserName; - - Logging.LogProvider.SetCurrentLogProvider(new ColoredConsoleLogProvider()); - - DealService service = new DealService(username); - - var id = Guid.NewGuid().ToString(); - var deal = Deal.Empty.With( - id, - 500.00, - 10, - "MSFT", - DateTime.Now - ); - - service.Save(id, deal); - - - Console.WriteLine(); - Console.WriteLine(); - - var vincentDeal = service.Load(id).DefaultIfEmpty(Deal.Empty).Single(); - Console.WriteLine(vincentDeal); - - Console.ReadLine(); - } - } -} diff --git a/Src/Solid-TradeService/3.OCP/Properties/AssemblyInfo.cs b/Src/Solid-TradeService/3.OCP/Properties/AssemblyInfo.cs deleted file mode 100644 index b681b7c..0000000 --- a/Src/Solid-TradeService/3.OCP/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -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("TradeApp")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TradeApp")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[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("bba07b19-254a-4ef0-bcc5-f8954c963537")] - -// 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")] diff --git a/Src/Solid-TradeService/3.OCP/Readme.md b/Src/Solid-TradeService/3.OCP/Readme.md deleted file mode 100644 index 29bd876..0000000 --- a/Src/Solid-TradeService/3.OCP/Readme.md +++ /dev/null @@ -1,6 +0,0 @@ -# Step 3 : Open/Closed Principle - -## Use simple Inheritance with virtual members in this sample - -- Make public methods virtual -- Add some Factory Methods using virtual properties \ No newline at end of file diff --git a/Src/Solid-TradeService/3.OCP/TradeApp.csproj b/Src/Solid-TradeService/3.OCP/TradeApp.csproj deleted file mode 100644 index fd27d63..0000000 --- a/Src/Solid-TradeService/3.OCP/TradeApp.csproj +++ /dev/null @@ -1,81 +0,0 @@ - - - - - Debug - AnyCPU - {986AEC51-2775-4B65-AF59-2DA17455376C} - Exe - Properties - TradeApp - TradeApp - v4.6 - 512 - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - True - - - - ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/3.OCP/packages.config b/Src/Solid-TradeService/3.OCP/packages.config deleted file mode 100644 index 557b51e..0000000 --- a/Src/Solid-TradeService/3.OCP/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/4.LSP/App.config b/Src/Solid-TradeService/4.LSP/App.config deleted file mode 100644 index 8324aa6..0000000 --- a/Src/Solid-TradeService/4.LSP/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/4.LSP/DealCaching.cs b/Src/Solid-TradeService/4.LSP/DealCaching.cs deleted file mode 100644 index 53cd68d..0000000 --- a/Src/Solid-TradeService/4.LSP/DealCaching.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Immutable; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealCaching - { - private ImmutableDictionary _cache; - - public DealCaching() - { - _cache = ImmutableDictionary.Empty; - } - public virtual void AddOrUpdate(string id, Deal deal) - { - ImmutableInterlocked.AddOrUpdate(ref _cache, id, deal, (i, d) => deal); - } - - public virtual Deal GetOrAdd(string id, Func dealFactory ) - { - return ImmutableInterlocked.GetOrAdd(ref _cache, id, dealFactory); - } - } -} diff --git a/Src/Solid-TradeService/4.LSP/DealSerializer.cs b/Src/Solid-TradeService/4.LSP/DealSerializer.cs deleted file mode 100644 index c603b91..0000000 --- a/Src/Solid-TradeService/4.LSP/DealSerializer.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Newtonsoft.Json; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealSerializer - { - public virtual string SerializeDeal(Deal deal) - { - return JsonConvert.SerializeObject(deal); - } - - public virtual Deal DeserializeDeal(string serializedDeal) - { - return JsonConvert.DeserializeObject(serializedDeal); - } - } -} diff --git a/Src/Solid-TradeService/4.LSP/DealService.cs b/Src/Solid-TradeService/4.LSP/DealService.cs deleted file mode 100644 index 59fea59..0000000 --- a/Src/Solid-TradeService/4.LSP/DealService.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.IO; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealService - { - private readonly DealServiceLogger _dealServiceLogger; - private readonly DealCaching _dealCaching; - private readonly DealStorage _dealStorage; - private readonly DealSerializer _dealSerializer; - - public DealService(string username) - { - if(username == null) - { throw new ArgumentNullException(nameof(username)); } - - if (!Directory.Exists(username)) - { Directory.CreateDirectory(username); } - - Username = username; - _dealCaching = new DealCaching(); - _dealStorage = new DealStorage(); - _dealSerializer = new DealSerializer(); - _dealServiceLogger = new DealServiceLogger(); - } - - public virtual DealCaching DealCaching => _dealCaching; - - public virtual DealStorage DealStorage => _dealStorage; - - public virtual DealServiceLogger DealServiceLogger => _dealServiceLogger; - - public virtual DealSerializer DealSerializer => _dealSerializer; - - public string Username { get; } - - - public void Save(string id, Deal deal) - { - _dealServiceLogger.Saving(deal); - var file = _dealStorage.GetFileName(id,Username); - var serializedDeal = _dealSerializer.SerializeDeal(deal); - _dealStorage.WriteDeal(file.FullName,serializedDeal); - _dealCaching.AddOrUpdate(id, deal); - _dealServiceLogger.Saved(deal); - } - - public Maybe Load(string id) - { - _dealServiceLogger.Loading(id); - var file = _dealStorage.GetFileName(id,Username); - - if (!file.Exists) - { - _dealServiceLogger.DidNotFind(id); - return new Maybe(); - } - - try - { - var deal = _dealCaching.GetOrAdd(id, _ => - _dealSerializer.DeserializeDeal(_dealStorage.ReadDeal(file.FullName))); - - _dealServiceLogger.Loaded(deal); - return new Maybe(deal); - } - catch (Exception) - { - return new Maybe(); - } - } - - - } -} diff --git a/Src/Solid-TradeService/4.LSP/DealServiceDiagram.cd b/Src/Solid-TradeService/4.LSP/DealServiceDiagram.cd deleted file mode 100644 index 4007499..0000000 --- a/Src/Solid-TradeService/4.LSP/DealServiceDiagram.cd +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - AAAIgIAEAAAAAAAAAQAAAAAAAAAAIAAAAAAAAgAAAAA= - DealService.cs - - - - - - - - - - - - AAAAAAAAAIAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAA= - DealCaching.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAABA= - DealSerializer.cs - - - - - - AAAAAAAAAIEAAAAAAAAIAICAIAAAAAAAAAAAAAAAAAA= - DealServiceLogger.cs - - - - - - AAAAAAAAAEAAAAAAAAAABAAAQAAAAAAAAAAAAAAAAAA= - DealStorage.cs - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/4.LSP/DealServiceLogger.cs b/Src/Solid-TradeService/4.LSP/DealServiceLogger.cs deleted file mode 100644 index ab0996e..0000000 --- a/Src/Solid-TradeService/4.LSP/DealServiceLogger.cs +++ /dev/null @@ -1,35 +0,0 @@ -using TradeApp.Logging; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealServiceLogger - { - private static readonly ILog _logger = LogProvider.For(); - - public virtual void Saving(Deal deal) - { - _logger.Info($"Saving deal {deal.Id}."); - } - - public virtual void Saved(Deal deal) - { - _logger.Info($"Saved deal {deal.Id}."); - } - - public virtual void Loading(string id) - { - _logger.Info($"Loading deal {id}."); - } - - public virtual void DidNotFind(string id) - { - _logger.Info($"No deal {id} found."); - } - - public virtual void Loaded(Deal deal) - { - _logger.Info($"Returning deal {deal.Id}."); - } - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/4.LSP/DealStorage.cs b/Src/Solid-TradeService/4.LSP/DealStorage.cs deleted file mode 100644 index 78ee218..0000000 --- a/Src/Solid-TradeService/4.LSP/DealStorage.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.IO; - -namespace TradeApp -{ - public class DealStorage - { - public virtual void WriteDeal(string path, string serializedDeal) - { - File.WriteAllText(path, serializedDeal); - } - - public virtual string ReadDeal(string path) - { - return File.ReadAllText(path); - } - - public virtual FileInfo GetFileName(string id, string username) - { - return new FileInfo(Path.Combine(username, id + ".json")); - } - } -} diff --git a/Src/Solid-TradeService/4.LSP/Log/ColoredConsoleLogProvider.cs b/Src/Solid-TradeService/4.LSP/Log/ColoredConsoleLogProvider.cs deleted file mode 100644 index 6853892..0000000 --- a/Src/Solid-TradeService/4.LSP/Log/ColoredConsoleLogProvider.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using TradeApp.Logging; - -namespace TradeApp.App_Packages.LibLog._4._2 -{ - public class ColoredConsoleLogProvider : ILogProvider - { - private static readonly Dictionary Colors = new Dictionary - { - {LogLevel.Fatal, ConsoleColor.Red}, - {LogLevel.Error, ConsoleColor.Yellow}, - {LogLevel.Warn, ConsoleColor.Magenta}, - {LogLevel.Info, ConsoleColor.White}, - {LogLevel.Debug, ConsoleColor.Gray}, - {LogLevel.Trace, ConsoleColor.DarkGray}, - }; - - public Logger GetLogger(string name) - { - return (logLevel, messageFunc, exception, formatParameters) => - { - if (messageFunc == null) - { - return true; // All log levels are enabled - } - - ConsoleColor consoleColor; - if (Colors.TryGetValue(logLevel, out consoleColor)) - { - var originalForground = Console.ForegroundColor; - try - { - Console.ForegroundColor = consoleColor; - WriteMessage(logLevel, name, messageFunc, formatParameters, exception); - } - finally - { - Console.ForegroundColor = originalForground; - } - } - else - { - WriteMessage(logLevel, name, messageFunc, formatParameters, exception); - } - - return true; - }; - } - - private static void WriteMessage( - LogLevel logLevel, - string name, - Func messageFunc, - object[] formatParameters, - Exception exception) - { - var message = string.Format(CultureInfo.InvariantCulture, messageFunc(), formatParameters); - if (exception != null) - { - message = message + "|" + exception; - } - Console.WriteLine("{0} | {1} | {2} | {3}", DateTime.UtcNow, logLevel, name, message); - } - - public IDisposable OpenNestedContext(string message) - { - return NullDisposable.Instance; - } - - public IDisposable OpenMappedContext(string key, string value) - { - return NullDisposable.Instance; - } - - private class NullDisposable : IDisposable - { - internal static readonly IDisposable Instance = new NullDisposable(); - - public void Dispose() - { } - } - } -} diff --git a/Src/Solid-TradeService/4.LSP/Log/LibLog.cs b/Src/Solid-TradeService/4.LSP/Log/LibLog.cs deleted file mode 100644 index f761084..0000000 --- a/Src/Solid-TradeService/4.LSP/Log/LibLog.cs +++ /dev/null @@ -1,1998 +0,0 @@ -//=============================================================================== -// LibLog -// -// https://github.com/damianh/LibLog -//=============================================================================== -// Copyright © 2011-2015 Damian Hickey. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//=============================================================================== - -// ReSharper disable PossibleNullReferenceException - -// Define LIBLOG_PORTABLE conditional compilation symbol for PCL compatibility -// -// Define LIBLOG_PUBLIC to enable ability to GET a logger (LogProvider.For<>() etc) from outside this library. NOTE: -// this can have unintended consequences of consumers of your library using your library to resolve a logger. If the -// reason is because you want to open this functionality to other projects within your solution, -// consider [InternalVisibleTo] instead. -// -// Define LIBLOG_PROVIDERS_ONLY if your library provides its own logging API and you just want to use the -// LibLog providers internally to provide built in support for popular logging frameworks. - -#pragma warning disable 1591 - -// If you copied this file manually, you need to change all "YourRootNameSpace" so not to clash with other libraries -// that use LibLog -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog -#else -namespace TradeApp.Logging -#endif -{ - using System.Collections.Generic; -#if LIBLOG_PROVIDERS_ONLY - using TradeApp.LibLog.LogProviders; -#else - using TradeApp.Logging.LogProviders; -#endif - using System; -#if !LIBLOG_PROVIDERS_ONLY - using System.Diagnostics; -#if !LIBLOG_PORTABLE - using System.Runtime.CompilerServices; -#endif -#endif - -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - delegate bool Logger(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters); - -#if !LIBLOG_PROVIDERS_ONLY - /// - /// Simple interface that represent a logger. - /// -#if LIBLOG_PUBLIC - public -#else - internal -#endif - interface ILog - { - /// - /// Log a message the specified log level. - /// - /// The log level. - /// The message function. - /// An optional exception. - /// Optional format parameters for the message generated by the messagefunc. - /// true if the message was logged. Otherwise false. - /// - /// Note to implementers: the message func should not be called if the loglevel is not enabled - /// so as not to incur performance penalties. - /// - /// To check IsEnabled call Log with only LogLevel and check the return value, no event will be written. - /// - bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters ); - } -#endif - - /// - /// The log level. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - enum LogLevel - { - Trace, - Debug, - Info, - Warn, - Error, - Fatal - } - -#if !LIBLOG_PROVIDERS_ONLY -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static partial class LogExtensions - { - public static bool IsDebugEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Debug, null); - } - - public static bool IsErrorEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Error, null); - } - - public static bool IsFatalEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Fatal, null); - } - - public static bool IsInfoEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Info, null); - } - - public static bool IsTraceEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Trace, null); - } - - public static bool IsWarnEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Warn, null); - } - - public static void Debug(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Debug, messageFunc); - } - - public static void Debug(this ILog logger, string message) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc()); - } - } - - public static void DebugFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsDebugEnabled()) - { - logger.LogFormat(LogLevel.Debug, message, args); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception, formatParams); - } - } - - public static void Error(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Error, messageFunc); - } - - public static void Error(this ILog logger, string message) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc()); - } - } - - public static void ErrorFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsErrorEnabled()) - { - logger.LogFormat(LogLevel.Error, message, args); - } - } - - public static void ErrorException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc(), exception, formatParams); - } - } - - public static void Fatal(this ILog logger, Func messageFunc) - { - logger.Log(LogLevel.Fatal, messageFunc); - } - - public static void Fatal(this ILog logger, string message) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc()); - } - } - - public static void FatalFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsFatalEnabled()) - { - logger.LogFormat(LogLevel.Fatal, message, args); - } - } - - public static void FatalException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc(), exception, formatParams); - } - } - - public static void Info(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Info, messageFunc); - } - - public static void Info(this ILog logger, string message) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc()); - } - } - - public static void InfoFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsInfoEnabled()) - { - logger.LogFormat(LogLevel.Info, message, args); - } - } - - public static void InfoException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc(), exception, formatParams); - } - } - - public static void Trace(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Trace, messageFunc); - } - - public static void Trace(this ILog logger, string message) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc()); - } - } - - public static void TraceFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsTraceEnabled()) - { - logger.LogFormat(LogLevel.Trace, message, args); - } - } - - public static void TraceException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc(), exception, formatParams); - } - } - - public static void Warn(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Warn, messageFunc); - } - - public static void Warn(this ILog logger, string message) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc()); - } - } - - public static void WarnFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsWarnEnabled()) - { - logger.LogFormat(LogLevel.Warn, message, args); - } - } - - public static void WarnException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc(), exception, formatParams); - } - } - - // ReSharper disable once UnusedParameter.Local - private static void GuardAgainstNullLogger(ILog logger) - { - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - } - - private static void LogFormat(this ILog logger, LogLevel logLevel, string message, params object[] args) - { - logger.Log(logLevel, message.AsFunc(), null, args); - } - - // Avoid the closure allocation, see https://gist.github.com/AArnott/d285feef75c18f6ecd2b - private static Func AsFunc(this T value) where T : class - { - return value.Return; - } - - private static T Return(this T value) - { - return value; - } - } -#endif - - /// - /// Represents a way to get a - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - interface ILogProvider - { - /// - /// Gets the specified named logger. - /// - /// Name of the logger. - /// The logger reference. - Logger GetLogger(string name); - - /// - /// Opens a nested diagnostics context. Not supported in EntLib logging. - /// - /// The message to add to the diagnostics context. - /// A disposable that when disposed removes the message from the context. - IDisposable OpenNestedContext(string message); - - /// - /// Opens a mapped diagnostics context. Not supported in EntLib logging. - /// - /// A key. - /// A value. - /// A disposable that when disposed removes the map from the context. - IDisposable OpenMappedContext(string key, string value); - } - - /// - /// Provides a mechanism to create instances of objects. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - static class LogProvider - { -#if !LIBLOG_PROVIDERS_ONLY - /// - /// The disable logging environment variable. If the environment variable is set to 'true', then logging - /// will be disabled. - /// - public const string DisableLoggingEnvironmentVariable = "TradeApp_LIBLOG_DISABLE"; - private const string NullLogProvider = "Current Log Provider is not set. Call SetCurrentLogProvider " + - "with a non-null value first."; - private static dynamic s_currentLogProvider; - private static Action s_onCurrentLogProviderSet; - - static LogProvider() - { - IsDisabled = false; - } - - /// - /// Sets the current log provider. - /// - /// The log provider. - public static void SetCurrentLogProvider(ILogProvider logProvider) - { - s_currentLogProvider = logProvider; - - RaiseOnCurrentLogProviderSet(); - } - - /// - /// Gets or sets a value indicating whether this is logging is disabled. - /// - /// - /// true if logging is disabled; otherwise, false. - /// - public static bool IsDisabled { get; set; } - - /// - /// Sets an action that is invoked when a consumer of your library has called SetCurrentLogProvider. It is - /// important that hook into this if you are using child libraries (especially ilmerged ones) that are using - /// LibLog (or other logging abstraction) so you adapt and delegate to them. - /// - /// - internal static Action OnCurrentLogProviderSet - { - set - { - s_onCurrentLogProviderSet = value; - RaiseOnCurrentLogProviderSet(); - } - } - - internal static ILogProvider CurrentLogProvider - { - get - { - return s_currentLogProvider; - } - } - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog For() - { - return GetLogger(typeof(T)); - } - -#if !LIBLOG_PORTABLE - /// - /// Gets a logger for the current class. - /// - /// An instance of - [MethodImpl(MethodImplOptions.NoInlining)] -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetCurrentClassLogger() - { - var stackFrame = new StackFrame(1, false); - return GetLogger(stackFrame.GetMethod().DeclaringType); - } -#endif - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(Type type) - { - return GetLogger(type.FullName); - } - - /// - /// Gets a logger with the specified name. - /// - /// The name. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(string name) - { - ILogProvider logProvider = CurrentLogProvider ?? ResolveLogProvider(); - return logProvider == null - ? NoOpLogger.Instance - : (ILog)new LoggerExecutionWrapper(logProvider.GetLogger(name), () => IsDisabled); - } - - /// - /// Opens a nested diagnostics context. - /// - /// A message. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenNestedContext(string message) - { - if(CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenNestedContext(message); - } - - /// - /// Opens a mapped diagnostics context. - /// - /// A key. - /// A value. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenMappedContext(string key, string value) - { - if (CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenMappedContext(key, value); - } -#endif - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate bool IsLoggerAvailable(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate ILogProvider CreateLogProvider(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - static readonly List> LogProviderResolvers = - new List> - { - new Tuple(SerilogLogProvider.IsLoggerAvailable, () => new SerilogLogProvider()), - new Tuple(NLogLogProvider.IsLoggerAvailable, () => new NLogLogProvider()), - new Tuple(Log4NetLogProvider.IsLoggerAvailable, () => new Log4NetLogProvider()), - new Tuple(EntLibLogProvider.IsLoggerAvailable, () => new EntLibLogProvider()), - new Tuple(LoupeLogProvider.IsLoggerAvailable, () => new LoupeLogProvider()), - }; - -#if !LIBLOG_PROVIDERS_ONLY - private static void RaiseOnCurrentLogProviderSet() - { - if (s_onCurrentLogProviderSet != null) - { - s_onCurrentLogProviderSet(s_currentLogProvider); - } - } -#endif - - internal static ILogProvider ResolveLogProvider() - { - try - { - foreach (var providerResolver in LogProviderResolvers) - { - if (providerResolver.Item1()) - { - return providerResolver.Item2(); - } - } - } - catch (Exception ex) - { -#if LIBLOG_PORTABLE - Debug.WriteLine( -#else - Console.WriteLine( -#endif - "Exception occurred resolving a log provider. Logging for this assembly {0} is disabled. {1}", - typeof(LogProvider).GetAssemblyPortable().FullName, - ex); - } - return null; - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class NoOpLogger : ILog - { - internal static readonly NoOpLogger Instance = new NoOpLogger(); - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - return false; - } - } -#endif - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class LoggerExecutionWrapper : ILog - { - private readonly Logger _logger; - private readonly Func _getIsDisabled; - internal const string FailedToGenerateLogMessage = "Failed to generate log message"; - - internal LoggerExecutionWrapper(Logger logger, Func getIsDisabled = null) - { - _logger = logger; - _getIsDisabled = getIsDisabled ?? (() => false); - } - - internal Logger WrappedLogger - { - get { return _logger; } - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters) - { - if (_getIsDisabled()) - { - return false; - } -#if !LIBLOG_PORTABLE - var envVar = Environment.GetEnvironmentVariable(LogProvider.DisableLoggingEnvironmentVariable); - - if (envVar != null && envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) - { - return false; - } -#endif - - if (messageFunc == null) - { - return _logger(logLevel, null); - } - - Func wrappedMessageFunc = () => - { - try - { - return messageFunc(); - } - catch (Exception ex) - { - Log(LogLevel.Error, () => FailedToGenerateLogMessage, ex); - } - return null; - }; - return _logger(logLevel, wrappedMessageFunc, exception, formatParameters); - } - } -#endif -} - -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog.LogProviders -#else -namespace TradeApp.Logging.LogProviders -#endif -{ - using System; - using System.Collections.Generic; -#if !LIBLOG_PORTABLE - using System.Diagnostics; -#endif - using System.Globalization; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; -#if !LIBLOG_PORTABLE - using System.Text; -#endif - using System.Text.RegularExpressions; - - internal abstract class LogProviderBase : ILogProvider - { - protected delegate IDisposable OpenNdc(string message); - protected delegate IDisposable OpenMdc(string key, string value); - - private readonly Lazy _lazyOpenNdcMethod; - private readonly Lazy _lazyOpenMdcMethod; - private static readonly IDisposable NoopDisposableInstance = new DisposableAction(); - - protected LogProviderBase() - { - _lazyOpenNdcMethod - = new Lazy(GetOpenNdcMethod); - _lazyOpenMdcMethod - = new Lazy(GetOpenMdcMethod); - } - - public abstract Logger GetLogger(string name); - - public IDisposable OpenNestedContext(string message) - { - return _lazyOpenNdcMethod.Value(message); - } - - public IDisposable OpenMappedContext(string key, string value) - { - return _lazyOpenMdcMethod.Value(key, value); - } - - protected virtual OpenNdc GetOpenNdcMethod() - { - return _ => NoopDisposableInstance; - } - - protected virtual OpenMdc GetOpenMdcMethod() - { - return (_, __) => NoopDisposableInstance; - } - } - - internal class NLogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public NLogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("NLog.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new NLogLogger(_getLoggerByNameDelegate(name)).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("NLog.NestedDiagnosticsContext, NLog"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("NLog.MappedDiagnosticsContext, NLog"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("NLog.LogManager, NLog"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class NLogLogger - { - private readonly dynamic _logger; - - internal NLogLogger(dynamic logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - if(exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.Debug(messageFunc()); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.Info(messageFunc()); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.Warn(messageFunc()); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.Error(messageFunc()); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.Fatal(messageFunc()); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.Trace(messageFunc()); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.DebugException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.InfoException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.WarnException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.ErrorException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.FatalException(messageFunc(), exception); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.TraceException(messageFunc(), exception); - return true; - } - break; - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Debug: - return _logger.IsDebugEnabled; - case LogLevel.Info: - return _logger.IsInfoEnabled; - case LogLevel.Warn: - return _logger.IsWarnEnabled; - case LogLevel.Error: - return _logger.IsErrorEnabled; - case LogLevel.Fatal: - return _logger.IsFatalEnabled; - default: - return _logger.IsTraceEnabled; - } - } - } - } - - internal class Log4NetLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public Log4NetLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("log4net.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new Log4NetLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("log4net.NDC, log4net"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("log4net.MDC, log4net"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("log4net.LogManager, log4net"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class Log4NetLogger - { - private readonly dynamic _logger; - private static Type s_callerStackBoundaryType; - private static readonly object CallerStackBoundaryTypeSync = new object(); - - private readonly object _levelDebug; - private readonly object _levelInfo; - private readonly object _levelWarn; - private readonly object _levelError; - private readonly object _levelFatal; - private readonly Func _isEnabledForDelegate; - private readonly Action _logDelegate; - - internal Log4NetLogger(dynamic logger) - { - _logger = logger.Logger; - - var logEventLevelType = Type.GetType("log4net.Core.Level, log4net"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type log4net.Core.Level was not found."); - } - - var levelFields = logEventLevelType.GetFieldsPortable().ToList(); - _levelDebug = levelFields.First(x => x.Name == "Debug").GetValue(null); - _levelInfo = levelFields.First(x => x.Name == "Info").GetValue(null); - _levelWarn = levelFields.First(x => x.Name == "Warn").GetValue(null); - _levelError = levelFields.First(x => x.Name == "Error").GetValue(null); - _levelFatal = levelFields.First(x => x.Name == "Fatal").GetValue(null); - - // Func isEnabledFor = (logger, level) => { return ((log4net.Core.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("log4net.Core.ILogger, log4net"); - if (loggerType == null) - { - throw new InvalidOperationException("Type log4net.Core.ILogger, was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabledFor", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression callerStackBoundaryDeclaringTypeParam = Expression.Parameter(typeof(Type)); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - _isEnabledForDelegate = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Log = - // (logger, callerStackBoundaryDeclaringType, level, message, exception) => { ((ILogger)logger).Write(callerStackBoundaryDeclaringType, level, message, exception); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Log", - typeof(Type), - logEventLevelType, - typeof(string), - typeof(Exception)); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - var writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - callerStackBoundaryDeclaringTypeParam, - levelCast, - messageParam, - exceptionParam); - _logDelegate = Expression.Lambda>( - writeMethodExp, - instanceParam, - callerStackBoundaryDeclaringTypeParam, - levelParam, - messageParam, - exceptionParam).Compile(); - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - - if (!IsLogLevelEnable(logLevel)) - { - return false; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - // determine correct caller - this might change due to jit optimizations with method inlining - if (s_callerStackBoundaryType == null) - { - lock (CallerStackBoundaryTypeSync) - { -#if !LIBLOG_PORTABLE - StackTrace stack = new StackTrace(); - Type thisType = GetType(); - s_callerStackBoundaryType = Type.GetType("LoggerExecutionWrapper"); - for (var i = 1; i < stack.FrameCount; i++) - { - if (!IsInTypeHierarchy(thisType, stack.GetFrame(i).GetMethod().DeclaringType)) - { - s_callerStackBoundaryType = stack.GetFrame(i - 1).GetMethod().DeclaringType; - break; - } - } -#else - s_callerStackBoundaryType = typeof (LoggerExecutionWrapper); -#endif - } - } - - var translatedLevel = TranslateLevel(logLevel); - _logDelegate(_logger, s_callerStackBoundaryType, translatedLevel, messageFunc(), exception); - return true; - } - - private bool IsInTypeHierarchy(Type currentType, Type checkType) - { - while (currentType != null && currentType != typeof(object)) - { - if (currentType == checkType) - { - return true; - } - currentType = currentType.GetBaseTypePortable(); - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - var level = TranslateLevel(logLevel); - return _isEnabledForDelegate(_logger, level); - } - - private object TranslateLevel(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - case LogLevel.Debug: - return _levelDebug; - case LogLevel.Info: - return _levelInfo; - case LogLevel.Warn: - return _levelWarn; - case LogLevel.Error: - return _levelError; - case LogLevel.Fatal: - return _levelFatal; - default: - throw new ArgumentOutOfRangeException("logLevel", logLevel, null); - } - } - } - } - - internal class EntLibLogProvider : LogProviderBase - { - private const string TypeTemplate = "Microsoft.Practices.EnterpriseLibrary.Logging.{0}, Microsoft.Practices.EnterpriseLibrary.Logging"; - private static bool s_providerIsAvailableOverride = true; - private static readonly Type LogEntryType; - private static readonly Type LoggerType; - private static readonly Type TraceEventTypeType; - private static readonly Action WriteLogEntry; - private static readonly Func ShouldLogEntry; - - static EntLibLogProvider() - { - LogEntryType = Type.GetType(string.Format(TypeTemplate, "LogEntry")); - LoggerType = Type.GetType(string.Format(TypeTemplate, "Logger")); - TraceEventTypeType = TraceEventTypeValues.Type; - if (LogEntryType == null - || TraceEventTypeType == null - || LoggerType == null) - { - return; - } - WriteLogEntry = GetWriteLogEntry(); - ShouldLogEntry = GetShouldLogEntry(); - } - - public EntLibLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Microsoft.Practices.EnterpriseLibrary.Logging.Logger not found"); - } - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new EntLibLogger(name, WriteLogEntry, ShouldLogEntry).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride - && TraceEventTypeType != null - && LogEntryType != null; - } - - private static Action GetWriteLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var messageParameter = Expression.Parameter(typeof(string), "message"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - messageParameter, - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("Write", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - messageParameter, - severityParameter).Compile(); - } - - private static Func GetShouldLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - Expression.Constant("***dummy***"), - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("ShouldLog", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - severityParameter).Compile(); - } - - private static MemberInitExpression GetWriteLogExpression(Expression message, - Expression severityParameter, ParameterExpression logNameParameter) - { - var entryType = LogEntryType; - MemberInitExpression memberInit = Expression.MemberInit(Expression.New(entryType), - Expression.Bind(entryType.GetPropertyPortable("Message"), message), - Expression.Bind(entryType.GetPropertyPortable("Severity"), severityParameter), - Expression.Bind( - entryType.GetPropertyPortable("TimeStamp"), - Expression.Property(null, typeof (DateTime).GetPropertyPortable("UtcNow"))), - Expression.Bind( - entryType.GetPropertyPortable("Categories"), - Expression.ListInit( - Expression.New(typeof (List)), - typeof (List).GetMethodPortable("Add", typeof (string)), - logNameParameter))); - return memberInit; - } - - internal class EntLibLogger - { - private readonly string _loggerName; - private readonly Action _writeLog; - private readonly Func _shouldLog; - - internal EntLibLogger(string loggerName, Action writeLog, Func shouldLog) - { - _loggerName = loggerName; - _writeLog = writeLog; - _shouldLog = shouldLog; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - var severity = MapSeverity(logLevel); - if (messageFunc == null) - { - return _shouldLog(_loggerName, severity); - } - - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - if (exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - _writeLog(_loggerName, messageFunc(), severity); - return true; - } - - public bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - var severity = MapSeverity(logLevel); - var message = messageFunc() + Environment.NewLine + exception; - _writeLog(_loggerName, message, severity); - return true; - } - - private static int MapSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Info: - return TraceEventTypeValues.Information; - default: - return TraceEventTypeValues.Verbose; - } - } - } - } - - internal class SerilogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public SerilogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Serilog.Log not found"); - } - _getLoggerByNameDelegate = GetForContextMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new SerilogLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - return message => GetPushProperty()("NDC", message); - } - - protected override OpenMdc GetOpenMdcMethod() - { - return (key, value) => GetPushProperty()(key, value); - } - - private static Func GetPushProperty() - { - Type ndcContextType = Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"); - MethodInfo pushPropertyMethod = ndcContextType.GetMethodPortable( - "PushProperty", - typeof(string), - typeof(object), - typeof(bool)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression pushPropertyMethodCall = Expression - .Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam); - var pushProperty = Expression - .Lambda>( - pushPropertyMethodCall, - nameParam, - valueParam, - destructureObjectParam) - .Compile(); - - return (key, value) => pushProperty(key, value, false); - } - - private static Type GetLogManagerType() - { - return Type.GetType("Serilog.Log, Serilog"); - } - - private static Func GetForContextMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("ForContext", typeof(string), typeof(object), typeof(bool)); - ParameterExpression propertyNameParam = Expression.Parameter(typeof(string), "propertyName"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectsParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression methodCall = Expression.Call(null, method, new Expression[] - { - propertyNameParam, - valueParam, - destructureObjectsParam - }); - var func = Expression.Lambda>( - methodCall, - propertyNameParam, - valueParam, - destructureObjectsParam) - .Compile(); - return name => func("Name", name, false); - } - - internal class SerilogLogger - { - private readonly object _logger; - private static readonly object DebugLevel; - private static readonly object ErrorLevel; - private static readonly object FatalLevel; - private static readonly object InformationLevel; - private static readonly object VerboseLevel; - private static readonly object WarningLevel; - private static readonly Func IsEnabled; - private static readonly Action Write; - private static readonly Action WriteException; - - static SerilogLogger() - { - var logEventLevelType = Type.GetType("Serilog.Events.LogEventLevel, Serilog"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type Serilog.Events.LogEventLevel was not found."); - } - DebugLevel = Enum.Parse(logEventLevelType, "Debug", false); - ErrorLevel = Enum.Parse(logEventLevelType, "Error", false); - FatalLevel = Enum.Parse(logEventLevelType, "Fatal", false); - InformationLevel = Enum.Parse(logEventLevelType, "Information", false); - VerboseLevel = Enum.Parse(logEventLevelType, "Verbose", false); - WarningLevel = Enum.Parse(logEventLevelType, "Warning", false); - - // Func isEnabled = (logger, level) => { return ((SeriLog.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("Serilog.ILogger, Serilog"); - if (loggerType == null) - { - throw new InvalidOperationException("Type Serilog.ILogger was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabled", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - IsEnabled = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Write = - // (logger, level, message, params) => { ((SeriLog.ILoggerILogger)logger).Write(level, message, params); } - MethodInfo writeMethodInfo = loggerType.GetMethodPortable("Write", logEventLevelType, typeof(string), typeof(object[])); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - ParameterExpression propertyValuesParam = Expression.Parameter(typeof(object[])); - MethodCallExpression writeMethodExp = Expression.Call( - instanceCast, - writeMethodInfo, - levelCast, - messageParam, - propertyValuesParam); - var expression = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - messageParam, - propertyValuesParam); - Write = expression.Compile(); - - // Action WriteException = - // (logger, level, exception, message) => { ((ILogger)logger).Write(level, exception, message, new object[]); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Write", - logEventLevelType, - typeof(Exception), - typeof(string), - typeof(object[])); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - levelCast, - exceptionParam, - messageParam, - propertyValuesParam); - WriteException = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - exceptionParam, - messageParam, - propertyValuesParam).Compile(); - } - - internal SerilogLogger(object logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsEnabled(_logger, logLevel); - } - if (exception != null) - { - return LogException(logLevel, messageFunc, exception, formatParameters); - } - - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - Write(_logger, DebugLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - Write(_logger, InformationLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - Write(_logger, WarningLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - Write(_logger, ErrorLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - Write(_logger, FatalLevel, messageFunc(), formatParameters); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - Write(_logger, VerboseLevel, messageFunc(), formatParameters); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception, object[] formatParams) - { - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - WriteException(_logger, DebugLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - WriteException(_logger, InformationLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - WriteException(_logger, WarningLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - WriteException(_logger, ErrorLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - WriteException(_logger, FatalLevel, exception, messageFunc(), formatParams); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - WriteException(_logger, VerboseLevel, exception, messageFunc(), formatParams); - return true; - } - break; - } - return false; - } - } - } - - internal class LoupeLogProvider : LogProviderBase - { - /// - /// The form of the Loupe Log.Write method we're using - /// - internal delegate void WriteDelegate( - int severity, - string logSystem, - int skipFrames, - Exception exception, - bool attributeToException, - int writeMode, - string detailsXml, - string category, - string caption, - string description, - params object[] args - ); - - private static bool s_providerIsAvailableOverride = true; - private readonly WriteDelegate _logWriteDelegate; - - public LoupeLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Gibraltar.Agent.Log (Loupe) not found"); - } - - _logWriteDelegate = GetLogWriteDelegate(); - } - - /// - /// Gets or sets a value indicating whether [provider is available override]. Used in tests. - /// - /// - /// true if [provider is available override]; otherwise, false. - /// - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new LoupeLogger(name, _logWriteDelegate).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - private static Type GetLogManagerType() - { - return Type.GetType("Gibraltar.Agent.Log, Gibraltar.Agent"); - } - - private static WriteDelegate GetLogWriteDelegate() - { - Type logManagerType = GetLogManagerType(); - Type logMessageSeverityType = Type.GetType("Gibraltar.Agent.LogMessageSeverity, Gibraltar.Agent"); - Type logWriteModeType = Type.GetType("Gibraltar.Agent.LogWriteMode, Gibraltar.Agent"); - - MethodInfo method = logManagerType.GetMethodPortable( - "Write", - logMessageSeverityType, typeof(string), typeof(int), typeof(Exception), typeof(bool), - logWriteModeType, typeof(string), typeof(string), typeof(string), typeof(string), typeof(object[])); - - var callDelegate = (WriteDelegate)method.CreateDelegate(typeof(WriteDelegate)); - return callDelegate; - } - - internal class LoupeLogger - { - private const string LogSystem = "LibLog"; - - private readonly string _category; - private readonly WriteDelegate _logWriteDelegate; - private readonly int _skipLevel; - - internal LoupeLogger(string category, WriteDelegate logWriteDelegate) - { - _category = category; - _logWriteDelegate = logWriteDelegate; -#if DEBUG - _skipLevel = 2; -#else - _skipLevel = 1; -#endif - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - //nothing to log.. - return true; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - _logWriteDelegate(ToLogMessageSeverity(logLevel), LogSystem, _skipLevel, exception, true, 0, null, - _category, null, messageFunc.Invoke()); - - return true; - } - - private int ToLogMessageSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - return TraceEventTypeValues.Verbose; - case LogLevel.Debug: - return TraceEventTypeValues.Verbose; - case LogLevel.Info: - return TraceEventTypeValues.Information; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - default: - throw new ArgumentOutOfRangeException("logLevel"); - } - } - } - } - - internal static class TraceEventTypeValues - { - internal static readonly Type Type; - internal static readonly int Verbose; - internal static readonly int Information; - internal static readonly int Warning; - internal static readonly int Error; - internal static readonly int Critical; - - static TraceEventTypeValues() - { - var assembly = typeof(Uri).GetAssemblyPortable(); // This is to get to the System.dll assembly in a PCL compatible way. - if (assembly == null) - { - return; - } - Type = assembly.GetType("System.Diagnostics.TraceEventType"); - if (Type == null) return; - Verbose = (int)Enum.Parse(Type, "Verbose", false); - Information = (int)Enum.Parse(Type, "Information", false); - Warning = (int)Enum.Parse(Type, "Warning", false); - Error = (int)Enum.Parse(Type, "Error", false); - Critical = (int)Enum.Parse(Type, "Critical", false); - } - } - - internal static class LogMessageFormatter - { - private static readonly Regex Pattern = new Regex(@"\{@?\w{1,}\}"); - - /// - /// Some logging frameworks support structured logging, such as serilog. This will allow you to add names to structured data in a format string: - /// For example: Log("Log message to {user}", user). This only works with serilog, but as the user of LibLog, you don't know if serilog is actually - /// used. So, this class simulates that. it will replace any text in {curly braces} with an index number. - /// - /// "Log {message} to {user}" would turn into => "Log {0} to {1}". Then the format parameters are handled using regular .net string.Format. - /// - /// The message builder. - /// The format parameters. - /// - public static Func SimulateStructuredLogging(Func messageBuilder, object[] formatParameters) - { - if (formatParameters == null || formatParameters.Length == 0) - { - return messageBuilder; - } - - return () => - { - string targetMessage = messageBuilder(); - int argumentIndex = 0; - foreach (Match match in Pattern.Matches(targetMessage)) - { - int notUsed; - if (!int.TryParse(match.Value.Substring(1, match.Value.Length -2), out notUsed)) - { - targetMessage = ReplaceFirst(targetMessage, match.Value, - "{" + argumentIndex++ + "}"); - } - } - try - { - return string.Format(CultureInfo.InvariantCulture, targetMessage, formatParameters); - } - catch (FormatException ex) - { - throw new FormatException("The input string '" + targetMessage + "' could not be formatted using string.Format", ex); - } - }; - } - - private static string ReplaceFirst(string text, string search, string replace) - { - int pos = text.IndexOf(search, StringComparison.Ordinal); - if (pos < 0) - { - return text; - } - return text.Substring(0, pos) + replace + text.Substring(pos + search.Length); - } - } - - internal static class TypeExtensions - { - internal static MethodInfo GetMethodPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, new Type[]{}); -#else - return type.GetMethod(name); -#endif - } - - internal static MethodInfo GetMethodPortable(this Type type, string name, params Type[] types) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, types); -#else - return type.GetMethod(name, types); -#endif - } - - internal static PropertyInfo GetPropertyPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeProperty(name); -#else - return type.GetProperty(name); -#endif - } - - internal static IEnumerable GetFieldsPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeFields(); -#else - return type.GetFields(); -#endif - } - - internal static Type GetBaseTypePortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().BaseType; -#else - return type.BaseType; -#endif - } - -#if LIBLOG_PORTABLE - internal static MethodInfo GetGetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.GetMethod; - } - - internal static MethodInfo GetSetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.SetMethod; - } -#endif - -#if !LIBLOG_PORTABLE - internal static object CreateDelegate(this MethodInfo methodInfo, Type delegateType) - { - return Delegate.CreateDelegate(delegateType, methodInfo); - } -#endif - - internal static Assembly GetAssemblyPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().Assembly; -#else - return type.Assembly; -#endif - } - } - - internal class DisposableAction : IDisposable - { - private readonly Action _onDispose; - - public DisposableAction(Action onDispose = null) - { - _onDispose = onDispose; - } - - public void Dispose() - { - if(_onDispose != null) - { - _onDispose(); - } - } - } -} diff --git a/Src/Solid-TradeService/4.LSP/Maybe.cs b/Src/Solid-TradeService/4.LSP/Maybe.cs deleted file mode 100644 index bc37dff..0000000 --- a/Src/Solid-TradeService/4.LSP/Maybe.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace TradeApp -{ - public class Maybe : IEnumerable - { - - private readonly IEnumerable _values; - - public Maybe() - { - _values = new T[0]; - } - - public Maybe(T value) - { - if (value == null) throw new ArgumentNullException(nameof(value)); - _values = new[] {value}; - } - - public IEnumerator GetEnumerator() - { - return _values.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} diff --git a/Src/Solid-TradeService/4.LSP/Models/Deal.cs b/Src/Solid-TradeService/4.LSP/Models/Deal.cs deleted file mode 100644 index da47454..0000000 --- a/Src/Solid-TradeService/4.LSP/Models/Deal.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -namespace TradeApp.Models -{ - public class Deal - { - private Deal(string id, double price, int quantity, string symbol, DateTime time) - { - Id = id; - Price = price; - Time = time; - Quantity = quantity; - Symbol = symbol; - } - - public static Deal Empty => new Deal("Empty", 0, 0, "Unset", DateTime.MinValue); - - public string Id { get; } - public double Price { get; } - public DateTime Time { get; } - public int Quantity { get; } - - public string Symbol { get; } - - public OrderDirection Direction - { - get { - return Quantity >= 0 ? OrderDirection.Buy : OrderDirection.Sell; - } - } - - public Deal With(string id = null, double? price = null, int? quantity = null, string symbol = null, DateTime? time = null) - { - return new Deal( - id ?? Id, - price ?? Price, - quantity ?? Quantity, - symbol ?? Symbol, - time ?? Time - ); - - } - - public override string ToString() - { - return $"OrderId: {Id} {Direction} order for {Quantity} unit{(Quantity == 1 ? "" : "s")} of {Symbol}"; - } - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/4.LSP/Models/OrderDirection.cs b/Src/Solid-TradeService/4.LSP/Models/OrderDirection.cs deleted file mode 100644 index c0df608..0000000 --- a/Src/Solid-TradeService/4.LSP/Models/OrderDirection.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace TradeApp.Models -{ - public enum OrderDirection - { - Buy, - Sell - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/4.LSP/Program.cs b/Src/Solid-TradeService/4.LSP/Program.cs deleted file mode 100644 index 8cc7c8d..0000000 --- a/Src/Solid-TradeService/4.LSP/Program.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Linq; -using TradeApp.App_Packages.LibLog._4._2; -using TradeApp.Models; - -namespace TradeApp -{ - class Program - { - static void Main(string[] args) - { - string username = Environment.UserName; - - Logging.LogProvider.SetCurrentLogProvider(new ColoredConsoleLogProvider()); - - DealService service = new DealService(username); - - var id = Guid.NewGuid().ToString(); - var deal = Deal.Empty.With( - id, - 500.00, - 10, - "MSFT", - DateTime.Now - ); - - service.Save(id, deal); - - - Console.WriteLine(); - Console.WriteLine(); - - var vincentDeal = service.Load(id).DefaultIfEmpty(Deal.Empty).Single(); - Console.WriteLine(vincentDeal); - - Console.ReadLine(); - } - } -} diff --git a/Src/Solid-TradeService/4.LSP/Properties/AssemblyInfo.cs b/Src/Solid-TradeService/4.LSP/Properties/AssemblyInfo.cs deleted file mode 100644 index b681b7c..0000000 --- a/Src/Solid-TradeService/4.LSP/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -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("TradeApp")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TradeApp")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[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("bba07b19-254a-4ef0-bcc5-f8954c963537")] - -// 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")] diff --git a/Src/Solid-TradeService/4.LSP/Readme.md b/Src/Solid-TradeService/4.LSP/Readme.md deleted file mode 100644 index 4202193..0000000 --- a/Src/Solid-TradeService/4.LSP/Readme.md +++ /dev/null @@ -1,7 +0,0 @@ -# Step 4 : Liskov Substitution Principle - -#### Using dapper as micro ORM - -- Try Create a new SQLDealStorage by inheriting from DealStorage -- See that GetFileName method have no sens in this class and that it's a violation of the LSP -- See that path is not really the path anymore and that it's a violation of the LSP \ No newline at end of file diff --git a/Src/Solid-TradeService/4.LSP/SQLDealStorage.cs b/Src/Solid-TradeService/4.LSP/SQLDealStorage.cs deleted file mode 100644 index 27eaf05..0000000 --- a/Src/Solid-TradeService/4.LSP/SQLDealStorage.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Data.SqlClient; -using System.IO; -using System.Linq; -using Dapper; - -namespace TradeApp -{ - public class SQLDealStorage : DealStorage - { - private readonly string _connectionString; - - public SQLDealStorage(string connectionString) - { - _connectionString = connectionString; - } - - public override string ReadDeal(string path) - { - - using (SqlConnection connection = new SqlConnection(_connectionString)) - { - connection.Open(); - var result = connection.Query("select Value from Deals where Id = @Id", new { Id = path }); - return result.First(); - } - } - - public override void WriteDeal(string path, string serializedDeal) - { - using (SqlConnection connection = new SqlConnection(_connectionString)) - { - connection.Open(); - connection.Execute(@"delete from Deals where Id = @Id", new { Id = path }); - connection.Execute(@"insert Deals(Id, Value) values (@Id, @Value)", - new {Id = path, Value = serializedDeal}); - } - } - - public override FileInfo GetFileName(string id, string username) - { - throw new NotImplementedException("Don't call this method if using SQL"); - } - } -} diff --git a/Src/Solid-TradeService/4.LSP/TradeApp.csproj b/Src/Solid-TradeService/4.LSP/TradeApp.csproj deleted file mode 100644 index 0fc2ff1..0000000 --- a/Src/Solid-TradeService/4.LSP/TradeApp.csproj +++ /dev/null @@ -1,85 +0,0 @@ - - - - - Debug - AnyCPU - {3417DA3A-14F9-4720-9F4E-D59C2E3AB77B} - Exe - Properties - TradeApp - TradeApp - v4.6 - 512 - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Dapper.1.42\lib\net45\Dapper.dll - - - ..\..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - True - - - - ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/4.LSP/packages.config b/Src/Solid-TradeService/4.LSP/packages.config deleted file mode 100644 index 88af6e8..0000000 --- a/Src/Solid-TradeService/4.LSP/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/5.ISP/App.config b/Src/Solid-TradeService/5.ISP/App.config deleted file mode 100644 index 8324aa6..0000000 --- a/Src/Solid-TradeService/5.ISP/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/5.ISP/Caching/DealCaching.cs b/Src/Solid-TradeService/5.ISP/Caching/DealCaching.cs deleted file mode 100644 index a63a287..0000000 --- a/Src/Solid-TradeService/5.ISP/Caching/DealCaching.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Immutable; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealCaching : IDealCaching - { - private ImmutableDictionary> _cache; - - public DealCaching() - { - _cache = ImmutableDictionary>.Empty; - } - public virtual void Save(string id, Maybe deal) - { - ImmutableInterlocked.AddOrUpdate(ref _cache, id, deal, (i, d) => deal ); - } - - public virtual Maybe Load(string id, Func> dealFactory ) - { - return ImmutableInterlocked.GetOrAdd(ref _cache, id, dealFactory); - } - } -} diff --git a/Src/Solid-TradeService/5.ISP/Caching/IDealCaching.cs b/Src/Solid-TradeService/5.ISP/Caching/IDealCaching.cs deleted file mode 100644 index 3a6b801..0000000 --- a/Src/Solid-TradeService/5.ISP/Caching/IDealCaching.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using TradeApp.Models; - -namespace TradeApp -{ - public interface IDealCaching - { - void Save(string id, Maybe deal); - Maybe Load(string id, Func> dealFactory); - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/5.ISP/DealService.cs b/Src/Solid-TradeService/5.ISP/DealService.cs deleted file mode 100644 index 50e752b..0000000 --- a/Src/Solid-TradeService/5.ISP/DealService.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Diagnostics.Contracts; -using System.IO; -using System.Linq; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealService - { - public DealService(string username) - { - if (username == null) - { throw new ArgumentNullException(nameof(username)); } - - if (!Directory.Exists(username)) - { Directory.CreateDirectory(username); } - - Username = username; - Cache = new DealCaching(); - Storage = new FileDealStorage(username); - Serializer = new DealSerializer(); - Logger = new DealServiceLogger(); - } - - public virtual IDealCaching Cache { get; } - - public virtual IDealStorage Storage { get; } - - public virtual IDealServiceLogger Logger { get; } - - public virtual IDealSerializer Serializer { get; } - - public string Username { get; } - - public void Save(string id, Deal deal) - { - Logger.Saving(deal); - Storage.Save(id, Serializer.SerializeDeal(deal)); - Cache.Save(id, new Maybe(deal)); - Logger.Saved(deal); - } - - public Maybe Load(string id) - { - Logger.Loading(id); - - var deal = Cache.Load(id, _ => - { - var serializedDeal = Storage.Load(id); - return Serializer.DeserializeDeal(serializedDeal); - }); - - if (deal.Any()) - Logger.Loaded(deal.First()); - else - Logger.DidNotFind(id); - - return deal; - } - } -} diff --git a/Src/Solid-TradeService/5.ISP/DealServiceDiagram.cd b/Src/Solid-TradeService/5.ISP/DealServiceDiagram.cd deleted file mode 100644 index 4007499..0000000 --- a/Src/Solid-TradeService/5.ISP/DealServiceDiagram.cd +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - AAAIgIAEAAAAAAAAAQAAAAAAAAAAIAAAAAAAAgAAAAA= - DealService.cs - - - - - - - - - - - - AAAAAAAAAIAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAA= - DealCaching.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAABA= - DealSerializer.cs - - - - - - AAAAAAAAAIEAAAAAAAAIAICAIAAAAAAAAAAAAAAAAAA= - DealServiceLogger.cs - - - - - - AAAAAAAAAEAAAAAAAAAABAAAQAAAAAAAAAAAAAAAAAA= - DealStorage.cs - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/5.ISP/Log/ColoredConsoleLogProvider.cs b/Src/Solid-TradeService/5.ISP/Log/ColoredConsoleLogProvider.cs deleted file mode 100644 index 6853892..0000000 --- a/Src/Solid-TradeService/5.ISP/Log/ColoredConsoleLogProvider.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using TradeApp.Logging; - -namespace TradeApp.App_Packages.LibLog._4._2 -{ - public class ColoredConsoleLogProvider : ILogProvider - { - private static readonly Dictionary Colors = new Dictionary - { - {LogLevel.Fatal, ConsoleColor.Red}, - {LogLevel.Error, ConsoleColor.Yellow}, - {LogLevel.Warn, ConsoleColor.Magenta}, - {LogLevel.Info, ConsoleColor.White}, - {LogLevel.Debug, ConsoleColor.Gray}, - {LogLevel.Trace, ConsoleColor.DarkGray}, - }; - - public Logger GetLogger(string name) - { - return (logLevel, messageFunc, exception, formatParameters) => - { - if (messageFunc == null) - { - return true; // All log levels are enabled - } - - ConsoleColor consoleColor; - if (Colors.TryGetValue(logLevel, out consoleColor)) - { - var originalForground = Console.ForegroundColor; - try - { - Console.ForegroundColor = consoleColor; - WriteMessage(logLevel, name, messageFunc, formatParameters, exception); - } - finally - { - Console.ForegroundColor = originalForground; - } - } - else - { - WriteMessage(logLevel, name, messageFunc, formatParameters, exception); - } - - return true; - }; - } - - private static void WriteMessage( - LogLevel logLevel, - string name, - Func messageFunc, - object[] formatParameters, - Exception exception) - { - var message = string.Format(CultureInfo.InvariantCulture, messageFunc(), formatParameters); - if (exception != null) - { - message = message + "|" + exception; - } - Console.WriteLine("{0} | {1} | {2} | {3}", DateTime.UtcNow, logLevel, name, message); - } - - public IDisposable OpenNestedContext(string message) - { - return NullDisposable.Instance; - } - - public IDisposable OpenMappedContext(string key, string value) - { - return NullDisposable.Instance; - } - - private class NullDisposable : IDisposable - { - internal static readonly IDisposable Instance = new NullDisposable(); - - public void Dispose() - { } - } - } -} diff --git a/Src/Solid-TradeService/5.ISP/Log/LibLog.cs b/Src/Solid-TradeService/5.ISP/Log/LibLog.cs deleted file mode 100644 index f761084..0000000 --- a/Src/Solid-TradeService/5.ISP/Log/LibLog.cs +++ /dev/null @@ -1,1998 +0,0 @@ -//=============================================================================== -// LibLog -// -// https://github.com/damianh/LibLog -//=============================================================================== -// Copyright © 2011-2015 Damian Hickey. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//=============================================================================== - -// ReSharper disable PossibleNullReferenceException - -// Define LIBLOG_PORTABLE conditional compilation symbol for PCL compatibility -// -// Define LIBLOG_PUBLIC to enable ability to GET a logger (LogProvider.For<>() etc) from outside this library. NOTE: -// this can have unintended consequences of consumers of your library using your library to resolve a logger. If the -// reason is because you want to open this functionality to other projects within your solution, -// consider [InternalVisibleTo] instead. -// -// Define LIBLOG_PROVIDERS_ONLY if your library provides its own logging API and you just want to use the -// LibLog providers internally to provide built in support for popular logging frameworks. - -#pragma warning disable 1591 - -// If you copied this file manually, you need to change all "YourRootNameSpace" so not to clash with other libraries -// that use LibLog -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog -#else -namespace TradeApp.Logging -#endif -{ - using System.Collections.Generic; -#if LIBLOG_PROVIDERS_ONLY - using TradeApp.LibLog.LogProviders; -#else - using TradeApp.Logging.LogProviders; -#endif - using System; -#if !LIBLOG_PROVIDERS_ONLY - using System.Diagnostics; -#if !LIBLOG_PORTABLE - using System.Runtime.CompilerServices; -#endif -#endif - -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - delegate bool Logger(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters); - -#if !LIBLOG_PROVIDERS_ONLY - /// - /// Simple interface that represent a logger. - /// -#if LIBLOG_PUBLIC - public -#else - internal -#endif - interface ILog - { - /// - /// Log a message the specified log level. - /// - /// The log level. - /// The message function. - /// An optional exception. - /// Optional format parameters for the message generated by the messagefunc. - /// true if the message was logged. Otherwise false. - /// - /// Note to implementers: the message func should not be called if the loglevel is not enabled - /// so as not to incur performance penalties. - /// - /// To check IsEnabled call Log with only LogLevel and check the return value, no event will be written. - /// - bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters ); - } -#endif - - /// - /// The log level. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - enum LogLevel - { - Trace, - Debug, - Info, - Warn, - Error, - Fatal - } - -#if !LIBLOG_PROVIDERS_ONLY -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static partial class LogExtensions - { - public static bool IsDebugEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Debug, null); - } - - public static bool IsErrorEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Error, null); - } - - public static bool IsFatalEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Fatal, null); - } - - public static bool IsInfoEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Info, null); - } - - public static bool IsTraceEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Trace, null); - } - - public static bool IsWarnEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Warn, null); - } - - public static void Debug(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Debug, messageFunc); - } - - public static void Debug(this ILog logger, string message) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc()); - } - } - - public static void DebugFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsDebugEnabled()) - { - logger.LogFormat(LogLevel.Debug, message, args); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception, formatParams); - } - } - - public static void Error(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Error, messageFunc); - } - - public static void Error(this ILog logger, string message) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc()); - } - } - - public static void ErrorFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsErrorEnabled()) - { - logger.LogFormat(LogLevel.Error, message, args); - } - } - - public static void ErrorException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc(), exception, formatParams); - } - } - - public static void Fatal(this ILog logger, Func messageFunc) - { - logger.Log(LogLevel.Fatal, messageFunc); - } - - public static void Fatal(this ILog logger, string message) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc()); - } - } - - public static void FatalFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsFatalEnabled()) - { - logger.LogFormat(LogLevel.Fatal, message, args); - } - } - - public static void FatalException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc(), exception, formatParams); - } - } - - public static void Info(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Info, messageFunc); - } - - public static void Info(this ILog logger, string message) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc()); - } - } - - public static void InfoFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsInfoEnabled()) - { - logger.LogFormat(LogLevel.Info, message, args); - } - } - - public static void InfoException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc(), exception, formatParams); - } - } - - public static void Trace(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Trace, messageFunc); - } - - public static void Trace(this ILog logger, string message) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc()); - } - } - - public static void TraceFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsTraceEnabled()) - { - logger.LogFormat(LogLevel.Trace, message, args); - } - } - - public static void TraceException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc(), exception, formatParams); - } - } - - public static void Warn(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Warn, messageFunc); - } - - public static void Warn(this ILog logger, string message) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc()); - } - } - - public static void WarnFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsWarnEnabled()) - { - logger.LogFormat(LogLevel.Warn, message, args); - } - } - - public static void WarnException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc(), exception, formatParams); - } - } - - // ReSharper disable once UnusedParameter.Local - private static void GuardAgainstNullLogger(ILog logger) - { - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - } - - private static void LogFormat(this ILog logger, LogLevel logLevel, string message, params object[] args) - { - logger.Log(logLevel, message.AsFunc(), null, args); - } - - // Avoid the closure allocation, see https://gist.github.com/AArnott/d285feef75c18f6ecd2b - private static Func AsFunc(this T value) where T : class - { - return value.Return; - } - - private static T Return(this T value) - { - return value; - } - } -#endif - - /// - /// Represents a way to get a - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - interface ILogProvider - { - /// - /// Gets the specified named logger. - /// - /// Name of the logger. - /// The logger reference. - Logger GetLogger(string name); - - /// - /// Opens a nested diagnostics context. Not supported in EntLib logging. - /// - /// The message to add to the diagnostics context. - /// A disposable that when disposed removes the message from the context. - IDisposable OpenNestedContext(string message); - - /// - /// Opens a mapped diagnostics context. Not supported in EntLib logging. - /// - /// A key. - /// A value. - /// A disposable that when disposed removes the map from the context. - IDisposable OpenMappedContext(string key, string value); - } - - /// - /// Provides a mechanism to create instances of objects. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - static class LogProvider - { -#if !LIBLOG_PROVIDERS_ONLY - /// - /// The disable logging environment variable. If the environment variable is set to 'true', then logging - /// will be disabled. - /// - public const string DisableLoggingEnvironmentVariable = "TradeApp_LIBLOG_DISABLE"; - private const string NullLogProvider = "Current Log Provider is not set. Call SetCurrentLogProvider " + - "with a non-null value first."; - private static dynamic s_currentLogProvider; - private static Action s_onCurrentLogProviderSet; - - static LogProvider() - { - IsDisabled = false; - } - - /// - /// Sets the current log provider. - /// - /// The log provider. - public static void SetCurrentLogProvider(ILogProvider logProvider) - { - s_currentLogProvider = logProvider; - - RaiseOnCurrentLogProviderSet(); - } - - /// - /// Gets or sets a value indicating whether this is logging is disabled. - /// - /// - /// true if logging is disabled; otherwise, false. - /// - public static bool IsDisabled { get; set; } - - /// - /// Sets an action that is invoked when a consumer of your library has called SetCurrentLogProvider. It is - /// important that hook into this if you are using child libraries (especially ilmerged ones) that are using - /// LibLog (or other logging abstraction) so you adapt and delegate to them. - /// - /// - internal static Action OnCurrentLogProviderSet - { - set - { - s_onCurrentLogProviderSet = value; - RaiseOnCurrentLogProviderSet(); - } - } - - internal static ILogProvider CurrentLogProvider - { - get - { - return s_currentLogProvider; - } - } - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog For() - { - return GetLogger(typeof(T)); - } - -#if !LIBLOG_PORTABLE - /// - /// Gets a logger for the current class. - /// - /// An instance of - [MethodImpl(MethodImplOptions.NoInlining)] -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetCurrentClassLogger() - { - var stackFrame = new StackFrame(1, false); - return GetLogger(stackFrame.GetMethod().DeclaringType); - } -#endif - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(Type type) - { - return GetLogger(type.FullName); - } - - /// - /// Gets a logger with the specified name. - /// - /// The name. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(string name) - { - ILogProvider logProvider = CurrentLogProvider ?? ResolveLogProvider(); - return logProvider == null - ? NoOpLogger.Instance - : (ILog)new LoggerExecutionWrapper(logProvider.GetLogger(name), () => IsDisabled); - } - - /// - /// Opens a nested diagnostics context. - /// - /// A message. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenNestedContext(string message) - { - if(CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenNestedContext(message); - } - - /// - /// Opens a mapped diagnostics context. - /// - /// A key. - /// A value. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenMappedContext(string key, string value) - { - if (CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenMappedContext(key, value); - } -#endif - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate bool IsLoggerAvailable(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate ILogProvider CreateLogProvider(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - static readonly List> LogProviderResolvers = - new List> - { - new Tuple(SerilogLogProvider.IsLoggerAvailable, () => new SerilogLogProvider()), - new Tuple(NLogLogProvider.IsLoggerAvailable, () => new NLogLogProvider()), - new Tuple(Log4NetLogProvider.IsLoggerAvailable, () => new Log4NetLogProvider()), - new Tuple(EntLibLogProvider.IsLoggerAvailable, () => new EntLibLogProvider()), - new Tuple(LoupeLogProvider.IsLoggerAvailable, () => new LoupeLogProvider()), - }; - -#if !LIBLOG_PROVIDERS_ONLY - private static void RaiseOnCurrentLogProviderSet() - { - if (s_onCurrentLogProviderSet != null) - { - s_onCurrentLogProviderSet(s_currentLogProvider); - } - } -#endif - - internal static ILogProvider ResolveLogProvider() - { - try - { - foreach (var providerResolver in LogProviderResolvers) - { - if (providerResolver.Item1()) - { - return providerResolver.Item2(); - } - } - } - catch (Exception ex) - { -#if LIBLOG_PORTABLE - Debug.WriteLine( -#else - Console.WriteLine( -#endif - "Exception occurred resolving a log provider. Logging for this assembly {0} is disabled. {1}", - typeof(LogProvider).GetAssemblyPortable().FullName, - ex); - } - return null; - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class NoOpLogger : ILog - { - internal static readonly NoOpLogger Instance = new NoOpLogger(); - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - return false; - } - } -#endif - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class LoggerExecutionWrapper : ILog - { - private readonly Logger _logger; - private readonly Func _getIsDisabled; - internal const string FailedToGenerateLogMessage = "Failed to generate log message"; - - internal LoggerExecutionWrapper(Logger logger, Func getIsDisabled = null) - { - _logger = logger; - _getIsDisabled = getIsDisabled ?? (() => false); - } - - internal Logger WrappedLogger - { - get { return _logger; } - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters) - { - if (_getIsDisabled()) - { - return false; - } -#if !LIBLOG_PORTABLE - var envVar = Environment.GetEnvironmentVariable(LogProvider.DisableLoggingEnvironmentVariable); - - if (envVar != null && envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) - { - return false; - } -#endif - - if (messageFunc == null) - { - return _logger(logLevel, null); - } - - Func wrappedMessageFunc = () => - { - try - { - return messageFunc(); - } - catch (Exception ex) - { - Log(LogLevel.Error, () => FailedToGenerateLogMessage, ex); - } - return null; - }; - return _logger(logLevel, wrappedMessageFunc, exception, formatParameters); - } - } -#endif -} - -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog.LogProviders -#else -namespace TradeApp.Logging.LogProviders -#endif -{ - using System; - using System.Collections.Generic; -#if !LIBLOG_PORTABLE - using System.Diagnostics; -#endif - using System.Globalization; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; -#if !LIBLOG_PORTABLE - using System.Text; -#endif - using System.Text.RegularExpressions; - - internal abstract class LogProviderBase : ILogProvider - { - protected delegate IDisposable OpenNdc(string message); - protected delegate IDisposable OpenMdc(string key, string value); - - private readonly Lazy _lazyOpenNdcMethod; - private readonly Lazy _lazyOpenMdcMethod; - private static readonly IDisposable NoopDisposableInstance = new DisposableAction(); - - protected LogProviderBase() - { - _lazyOpenNdcMethod - = new Lazy(GetOpenNdcMethod); - _lazyOpenMdcMethod - = new Lazy(GetOpenMdcMethod); - } - - public abstract Logger GetLogger(string name); - - public IDisposable OpenNestedContext(string message) - { - return _lazyOpenNdcMethod.Value(message); - } - - public IDisposable OpenMappedContext(string key, string value) - { - return _lazyOpenMdcMethod.Value(key, value); - } - - protected virtual OpenNdc GetOpenNdcMethod() - { - return _ => NoopDisposableInstance; - } - - protected virtual OpenMdc GetOpenMdcMethod() - { - return (_, __) => NoopDisposableInstance; - } - } - - internal class NLogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public NLogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("NLog.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new NLogLogger(_getLoggerByNameDelegate(name)).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("NLog.NestedDiagnosticsContext, NLog"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("NLog.MappedDiagnosticsContext, NLog"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("NLog.LogManager, NLog"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class NLogLogger - { - private readonly dynamic _logger; - - internal NLogLogger(dynamic logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - if(exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.Debug(messageFunc()); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.Info(messageFunc()); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.Warn(messageFunc()); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.Error(messageFunc()); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.Fatal(messageFunc()); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.Trace(messageFunc()); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.DebugException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.InfoException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.WarnException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.ErrorException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.FatalException(messageFunc(), exception); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.TraceException(messageFunc(), exception); - return true; - } - break; - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Debug: - return _logger.IsDebugEnabled; - case LogLevel.Info: - return _logger.IsInfoEnabled; - case LogLevel.Warn: - return _logger.IsWarnEnabled; - case LogLevel.Error: - return _logger.IsErrorEnabled; - case LogLevel.Fatal: - return _logger.IsFatalEnabled; - default: - return _logger.IsTraceEnabled; - } - } - } - } - - internal class Log4NetLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public Log4NetLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("log4net.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new Log4NetLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("log4net.NDC, log4net"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("log4net.MDC, log4net"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("log4net.LogManager, log4net"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class Log4NetLogger - { - private readonly dynamic _logger; - private static Type s_callerStackBoundaryType; - private static readonly object CallerStackBoundaryTypeSync = new object(); - - private readonly object _levelDebug; - private readonly object _levelInfo; - private readonly object _levelWarn; - private readonly object _levelError; - private readonly object _levelFatal; - private readonly Func _isEnabledForDelegate; - private readonly Action _logDelegate; - - internal Log4NetLogger(dynamic logger) - { - _logger = logger.Logger; - - var logEventLevelType = Type.GetType("log4net.Core.Level, log4net"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type log4net.Core.Level was not found."); - } - - var levelFields = logEventLevelType.GetFieldsPortable().ToList(); - _levelDebug = levelFields.First(x => x.Name == "Debug").GetValue(null); - _levelInfo = levelFields.First(x => x.Name == "Info").GetValue(null); - _levelWarn = levelFields.First(x => x.Name == "Warn").GetValue(null); - _levelError = levelFields.First(x => x.Name == "Error").GetValue(null); - _levelFatal = levelFields.First(x => x.Name == "Fatal").GetValue(null); - - // Func isEnabledFor = (logger, level) => { return ((log4net.Core.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("log4net.Core.ILogger, log4net"); - if (loggerType == null) - { - throw new InvalidOperationException("Type log4net.Core.ILogger, was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabledFor", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression callerStackBoundaryDeclaringTypeParam = Expression.Parameter(typeof(Type)); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - _isEnabledForDelegate = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Log = - // (logger, callerStackBoundaryDeclaringType, level, message, exception) => { ((ILogger)logger).Write(callerStackBoundaryDeclaringType, level, message, exception); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Log", - typeof(Type), - logEventLevelType, - typeof(string), - typeof(Exception)); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - var writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - callerStackBoundaryDeclaringTypeParam, - levelCast, - messageParam, - exceptionParam); - _logDelegate = Expression.Lambda>( - writeMethodExp, - instanceParam, - callerStackBoundaryDeclaringTypeParam, - levelParam, - messageParam, - exceptionParam).Compile(); - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - - if (!IsLogLevelEnable(logLevel)) - { - return false; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - // determine correct caller - this might change due to jit optimizations with method inlining - if (s_callerStackBoundaryType == null) - { - lock (CallerStackBoundaryTypeSync) - { -#if !LIBLOG_PORTABLE - StackTrace stack = new StackTrace(); - Type thisType = GetType(); - s_callerStackBoundaryType = Type.GetType("LoggerExecutionWrapper"); - for (var i = 1; i < stack.FrameCount; i++) - { - if (!IsInTypeHierarchy(thisType, stack.GetFrame(i).GetMethod().DeclaringType)) - { - s_callerStackBoundaryType = stack.GetFrame(i - 1).GetMethod().DeclaringType; - break; - } - } -#else - s_callerStackBoundaryType = typeof (LoggerExecutionWrapper); -#endif - } - } - - var translatedLevel = TranslateLevel(logLevel); - _logDelegate(_logger, s_callerStackBoundaryType, translatedLevel, messageFunc(), exception); - return true; - } - - private bool IsInTypeHierarchy(Type currentType, Type checkType) - { - while (currentType != null && currentType != typeof(object)) - { - if (currentType == checkType) - { - return true; - } - currentType = currentType.GetBaseTypePortable(); - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - var level = TranslateLevel(logLevel); - return _isEnabledForDelegate(_logger, level); - } - - private object TranslateLevel(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - case LogLevel.Debug: - return _levelDebug; - case LogLevel.Info: - return _levelInfo; - case LogLevel.Warn: - return _levelWarn; - case LogLevel.Error: - return _levelError; - case LogLevel.Fatal: - return _levelFatal; - default: - throw new ArgumentOutOfRangeException("logLevel", logLevel, null); - } - } - } - } - - internal class EntLibLogProvider : LogProviderBase - { - private const string TypeTemplate = "Microsoft.Practices.EnterpriseLibrary.Logging.{0}, Microsoft.Practices.EnterpriseLibrary.Logging"; - private static bool s_providerIsAvailableOverride = true; - private static readonly Type LogEntryType; - private static readonly Type LoggerType; - private static readonly Type TraceEventTypeType; - private static readonly Action WriteLogEntry; - private static readonly Func ShouldLogEntry; - - static EntLibLogProvider() - { - LogEntryType = Type.GetType(string.Format(TypeTemplate, "LogEntry")); - LoggerType = Type.GetType(string.Format(TypeTemplate, "Logger")); - TraceEventTypeType = TraceEventTypeValues.Type; - if (LogEntryType == null - || TraceEventTypeType == null - || LoggerType == null) - { - return; - } - WriteLogEntry = GetWriteLogEntry(); - ShouldLogEntry = GetShouldLogEntry(); - } - - public EntLibLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Microsoft.Practices.EnterpriseLibrary.Logging.Logger not found"); - } - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new EntLibLogger(name, WriteLogEntry, ShouldLogEntry).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride - && TraceEventTypeType != null - && LogEntryType != null; - } - - private static Action GetWriteLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var messageParameter = Expression.Parameter(typeof(string), "message"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - messageParameter, - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("Write", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - messageParameter, - severityParameter).Compile(); - } - - private static Func GetShouldLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - Expression.Constant("***dummy***"), - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("ShouldLog", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - severityParameter).Compile(); - } - - private static MemberInitExpression GetWriteLogExpression(Expression message, - Expression severityParameter, ParameterExpression logNameParameter) - { - var entryType = LogEntryType; - MemberInitExpression memberInit = Expression.MemberInit(Expression.New(entryType), - Expression.Bind(entryType.GetPropertyPortable("Message"), message), - Expression.Bind(entryType.GetPropertyPortable("Severity"), severityParameter), - Expression.Bind( - entryType.GetPropertyPortable("TimeStamp"), - Expression.Property(null, typeof (DateTime).GetPropertyPortable("UtcNow"))), - Expression.Bind( - entryType.GetPropertyPortable("Categories"), - Expression.ListInit( - Expression.New(typeof (List)), - typeof (List).GetMethodPortable("Add", typeof (string)), - logNameParameter))); - return memberInit; - } - - internal class EntLibLogger - { - private readonly string _loggerName; - private readonly Action _writeLog; - private readonly Func _shouldLog; - - internal EntLibLogger(string loggerName, Action writeLog, Func shouldLog) - { - _loggerName = loggerName; - _writeLog = writeLog; - _shouldLog = shouldLog; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - var severity = MapSeverity(logLevel); - if (messageFunc == null) - { - return _shouldLog(_loggerName, severity); - } - - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - if (exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - _writeLog(_loggerName, messageFunc(), severity); - return true; - } - - public bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - var severity = MapSeverity(logLevel); - var message = messageFunc() + Environment.NewLine + exception; - _writeLog(_loggerName, message, severity); - return true; - } - - private static int MapSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Info: - return TraceEventTypeValues.Information; - default: - return TraceEventTypeValues.Verbose; - } - } - } - } - - internal class SerilogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public SerilogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Serilog.Log not found"); - } - _getLoggerByNameDelegate = GetForContextMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new SerilogLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - return message => GetPushProperty()("NDC", message); - } - - protected override OpenMdc GetOpenMdcMethod() - { - return (key, value) => GetPushProperty()(key, value); - } - - private static Func GetPushProperty() - { - Type ndcContextType = Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"); - MethodInfo pushPropertyMethod = ndcContextType.GetMethodPortable( - "PushProperty", - typeof(string), - typeof(object), - typeof(bool)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression pushPropertyMethodCall = Expression - .Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam); - var pushProperty = Expression - .Lambda>( - pushPropertyMethodCall, - nameParam, - valueParam, - destructureObjectParam) - .Compile(); - - return (key, value) => pushProperty(key, value, false); - } - - private static Type GetLogManagerType() - { - return Type.GetType("Serilog.Log, Serilog"); - } - - private static Func GetForContextMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("ForContext", typeof(string), typeof(object), typeof(bool)); - ParameterExpression propertyNameParam = Expression.Parameter(typeof(string), "propertyName"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectsParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression methodCall = Expression.Call(null, method, new Expression[] - { - propertyNameParam, - valueParam, - destructureObjectsParam - }); - var func = Expression.Lambda>( - methodCall, - propertyNameParam, - valueParam, - destructureObjectsParam) - .Compile(); - return name => func("Name", name, false); - } - - internal class SerilogLogger - { - private readonly object _logger; - private static readonly object DebugLevel; - private static readonly object ErrorLevel; - private static readonly object FatalLevel; - private static readonly object InformationLevel; - private static readonly object VerboseLevel; - private static readonly object WarningLevel; - private static readonly Func IsEnabled; - private static readonly Action Write; - private static readonly Action WriteException; - - static SerilogLogger() - { - var logEventLevelType = Type.GetType("Serilog.Events.LogEventLevel, Serilog"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type Serilog.Events.LogEventLevel was not found."); - } - DebugLevel = Enum.Parse(logEventLevelType, "Debug", false); - ErrorLevel = Enum.Parse(logEventLevelType, "Error", false); - FatalLevel = Enum.Parse(logEventLevelType, "Fatal", false); - InformationLevel = Enum.Parse(logEventLevelType, "Information", false); - VerboseLevel = Enum.Parse(logEventLevelType, "Verbose", false); - WarningLevel = Enum.Parse(logEventLevelType, "Warning", false); - - // Func isEnabled = (logger, level) => { return ((SeriLog.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("Serilog.ILogger, Serilog"); - if (loggerType == null) - { - throw new InvalidOperationException("Type Serilog.ILogger was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabled", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - IsEnabled = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Write = - // (logger, level, message, params) => { ((SeriLog.ILoggerILogger)logger).Write(level, message, params); } - MethodInfo writeMethodInfo = loggerType.GetMethodPortable("Write", logEventLevelType, typeof(string), typeof(object[])); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - ParameterExpression propertyValuesParam = Expression.Parameter(typeof(object[])); - MethodCallExpression writeMethodExp = Expression.Call( - instanceCast, - writeMethodInfo, - levelCast, - messageParam, - propertyValuesParam); - var expression = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - messageParam, - propertyValuesParam); - Write = expression.Compile(); - - // Action WriteException = - // (logger, level, exception, message) => { ((ILogger)logger).Write(level, exception, message, new object[]); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Write", - logEventLevelType, - typeof(Exception), - typeof(string), - typeof(object[])); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - levelCast, - exceptionParam, - messageParam, - propertyValuesParam); - WriteException = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - exceptionParam, - messageParam, - propertyValuesParam).Compile(); - } - - internal SerilogLogger(object logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsEnabled(_logger, logLevel); - } - if (exception != null) - { - return LogException(logLevel, messageFunc, exception, formatParameters); - } - - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - Write(_logger, DebugLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - Write(_logger, InformationLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - Write(_logger, WarningLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - Write(_logger, ErrorLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - Write(_logger, FatalLevel, messageFunc(), formatParameters); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - Write(_logger, VerboseLevel, messageFunc(), formatParameters); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception, object[] formatParams) - { - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - WriteException(_logger, DebugLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - WriteException(_logger, InformationLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - WriteException(_logger, WarningLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - WriteException(_logger, ErrorLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - WriteException(_logger, FatalLevel, exception, messageFunc(), formatParams); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - WriteException(_logger, VerboseLevel, exception, messageFunc(), formatParams); - return true; - } - break; - } - return false; - } - } - } - - internal class LoupeLogProvider : LogProviderBase - { - /// - /// The form of the Loupe Log.Write method we're using - /// - internal delegate void WriteDelegate( - int severity, - string logSystem, - int skipFrames, - Exception exception, - bool attributeToException, - int writeMode, - string detailsXml, - string category, - string caption, - string description, - params object[] args - ); - - private static bool s_providerIsAvailableOverride = true; - private readonly WriteDelegate _logWriteDelegate; - - public LoupeLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Gibraltar.Agent.Log (Loupe) not found"); - } - - _logWriteDelegate = GetLogWriteDelegate(); - } - - /// - /// Gets or sets a value indicating whether [provider is available override]. Used in tests. - /// - /// - /// true if [provider is available override]; otherwise, false. - /// - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new LoupeLogger(name, _logWriteDelegate).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - private static Type GetLogManagerType() - { - return Type.GetType("Gibraltar.Agent.Log, Gibraltar.Agent"); - } - - private static WriteDelegate GetLogWriteDelegate() - { - Type logManagerType = GetLogManagerType(); - Type logMessageSeverityType = Type.GetType("Gibraltar.Agent.LogMessageSeverity, Gibraltar.Agent"); - Type logWriteModeType = Type.GetType("Gibraltar.Agent.LogWriteMode, Gibraltar.Agent"); - - MethodInfo method = logManagerType.GetMethodPortable( - "Write", - logMessageSeverityType, typeof(string), typeof(int), typeof(Exception), typeof(bool), - logWriteModeType, typeof(string), typeof(string), typeof(string), typeof(string), typeof(object[])); - - var callDelegate = (WriteDelegate)method.CreateDelegate(typeof(WriteDelegate)); - return callDelegate; - } - - internal class LoupeLogger - { - private const string LogSystem = "LibLog"; - - private readonly string _category; - private readonly WriteDelegate _logWriteDelegate; - private readonly int _skipLevel; - - internal LoupeLogger(string category, WriteDelegate logWriteDelegate) - { - _category = category; - _logWriteDelegate = logWriteDelegate; -#if DEBUG - _skipLevel = 2; -#else - _skipLevel = 1; -#endif - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - //nothing to log.. - return true; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - _logWriteDelegate(ToLogMessageSeverity(logLevel), LogSystem, _skipLevel, exception, true, 0, null, - _category, null, messageFunc.Invoke()); - - return true; - } - - private int ToLogMessageSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - return TraceEventTypeValues.Verbose; - case LogLevel.Debug: - return TraceEventTypeValues.Verbose; - case LogLevel.Info: - return TraceEventTypeValues.Information; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - default: - throw new ArgumentOutOfRangeException("logLevel"); - } - } - } - } - - internal static class TraceEventTypeValues - { - internal static readonly Type Type; - internal static readonly int Verbose; - internal static readonly int Information; - internal static readonly int Warning; - internal static readonly int Error; - internal static readonly int Critical; - - static TraceEventTypeValues() - { - var assembly = typeof(Uri).GetAssemblyPortable(); // This is to get to the System.dll assembly in a PCL compatible way. - if (assembly == null) - { - return; - } - Type = assembly.GetType("System.Diagnostics.TraceEventType"); - if (Type == null) return; - Verbose = (int)Enum.Parse(Type, "Verbose", false); - Information = (int)Enum.Parse(Type, "Information", false); - Warning = (int)Enum.Parse(Type, "Warning", false); - Error = (int)Enum.Parse(Type, "Error", false); - Critical = (int)Enum.Parse(Type, "Critical", false); - } - } - - internal static class LogMessageFormatter - { - private static readonly Regex Pattern = new Regex(@"\{@?\w{1,}\}"); - - /// - /// Some logging frameworks support structured logging, such as serilog. This will allow you to add names to structured data in a format string: - /// For example: Log("Log message to {user}", user). This only works with serilog, but as the user of LibLog, you don't know if serilog is actually - /// used. So, this class simulates that. it will replace any text in {curly braces} with an index number. - /// - /// "Log {message} to {user}" would turn into => "Log {0} to {1}". Then the format parameters are handled using regular .net string.Format. - /// - /// The message builder. - /// The format parameters. - /// - public static Func SimulateStructuredLogging(Func messageBuilder, object[] formatParameters) - { - if (formatParameters == null || formatParameters.Length == 0) - { - return messageBuilder; - } - - return () => - { - string targetMessage = messageBuilder(); - int argumentIndex = 0; - foreach (Match match in Pattern.Matches(targetMessage)) - { - int notUsed; - if (!int.TryParse(match.Value.Substring(1, match.Value.Length -2), out notUsed)) - { - targetMessage = ReplaceFirst(targetMessage, match.Value, - "{" + argumentIndex++ + "}"); - } - } - try - { - return string.Format(CultureInfo.InvariantCulture, targetMessage, formatParameters); - } - catch (FormatException ex) - { - throw new FormatException("The input string '" + targetMessage + "' could not be formatted using string.Format", ex); - } - }; - } - - private static string ReplaceFirst(string text, string search, string replace) - { - int pos = text.IndexOf(search, StringComparison.Ordinal); - if (pos < 0) - { - return text; - } - return text.Substring(0, pos) + replace + text.Substring(pos + search.Length); - } - } - - internal static class TypeExtensions - { - internal static MethodInfo GetMethodPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, new Type[]{}); -#else - return type.GetMethod(name); -#endif - } - - internal static MethodInfo GetMethodPortable(this Type type, string name, params Type[] types) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, types); -#else - return type.GetMethod(name, types); -#endif - } - - internal static PropertyInfo GetPropertyPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeProperty(name); -#else - return type.GetProperty(name); -#endif - } - - internal static IEnumerable GetFieldsPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeFields(); -#else - return type.GetFields(); -#endif - } - - internal static Type GetBaseTypePortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().BaseType; -#else - return type.BaseType; -#endif - } - -#if LIBLOG_PORTABLE - internal static MethodInfo GetGetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.GetMethod; - } - - internal static MethodInfo GetSetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.SetMethod; - } -#endif - -#if !LIBLOG_PORTABLE - internal static object CreateDelegate(this MethodInfo methodInfo, Type delegateType) - { - return Delegate.CreateDelegate(delegateType, methodInfo); - } -#endif - - internal static Assembly GetAssemblyPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().Assembly; -#else - return type.Assembly; -#endif - } - } - - internal class DisposableAction : IDisposable - { - private readonly Action _onDispose; - - public DisposableAction(Action onDispose = null) - { - _onDispose = onDispose; - } - - public void Dispose() - { - if(_onDispose != null) - { - _onDispose(); - } - } - } -} diff --git a/Src/Solid-TradeService/5.ISP/Logger/DealServiceLogger.cs b/Src/Solid-TradeService/5.ISP/Logger/DealServiceLogger.cs deleted file mode 100644 index bd2b2a9..0000000 --- a/Src/Solid-TradeService/5.ISP/Logger/DealServiceLogger.cs +++ /dev/null @@ -1,35 +0,0 @@ -using TradeApp.Logging; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealServiceLogger : IDealServiceLogger - { - private static readonly ILog _logger = LogProvider.For(); - - public virtual void Saving(Deal deal) - { - _logger.Info($"Saving deal {deal.Id}."); - } - - public virtual void Saved(Deal deal) - { - _logger.Info($"Saved deal {deal.Id}."); - } - - public virtual void Loading(string id) - { - _logger.Info($"Loading deal {id}."); - } - - public virtual void DidNotFind(string id) - { - _logger.Info($"No deal {id} found."); - } - - public virtual void Loaded(Deal deal) - { - _logger.Info($"Returning deal {deal.Id}."); - } - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/5.ISP/Logger/IDealServiceLogger.cs b/Src/Solid-TradeService/5.ISP/Logger/IDealServiceLogger.cs deleted file mode 100644 index 6d3c6a2..0000000 --- a/Src/Solid-TradeService/5.ISP/Logger/IDealServiceLogger.cs +++ /dev/null @@ -1,13 +0,0 @@ -using TradeApp.Models; - -namespace TradeApp -{ - public interface IDealServiceLogger - { - void Saving(Deal deal); - void Saved(Deal deal); - void Loading(string id); - void DidNotFind(string id); - void Loaded(Deal deal); - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/5.ISP/Maybe.cs b/Src/Solid-TradeService/5.ISP/Maybe.cs deleted file mode 100644 index bc37dff..0000000 --- a/Src/Solid-TradeService/5.ISP/Maybe.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace TradeApp -{ - public class Maybe : IEnumerable - { - - private readonly IEnumerable _values; - - public Maybe() - { - _values = new T[0]; - } - - public Maybe(T value) - { - if (value == null) throw new ArgumentNullException(nameof(value)); - _values = new[] {value}; - } - - public IEnumerator GetEnumerator() - { - return _values.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} diff --git a/Src/Solid-TradeService/5.ISP/Models/Deal.cs b/Src/Solid-TradeService/5.ISP/Models/Deal.cs deleted file mode 100644 index da47454..0000000 --- a/Src/Solid-TradeService/5.ISP/Models/Deal.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -namespace TradeApp.Models -{ - public class Deal - { - private Deal(string id, double price, int quantity, string symbol, DateTime time) - { - Id = id; - Price = price; - Time = time; - Quantity = quantity; - Symbol = symbol; - } - - public static Deal Empty => new Deal("Empty", 0, 0, "Unset", DateTime.MinValue); - - public string Id { get; } - public double Price { get; } - public DateTime Time { get; } - public int Quantity { get; } - - public string Symbol { get; } - - public OrderDirection Direction - { - get { - return Quantity >= 0 ? OrderDirection.Buy : OrderDirection.Sell; - } - } - - public Deal With(string id = null, double? price = null, int? quantity = null, string symbol = null, DateTime? time = null) - { - return new Deal( - id ?? Id, - price ?? Price, - quantity ?? Quantity, - symbol ?? Symbol, - time ?? Time - ); - - } - - public override string ToString() - { - return $"OrderId: {Id} {Direction} order for {Quantity} unit{(Quantity == 1 ? "" : "s")} of {Symbol}"; - } - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/5.ISP/Models/OrderDirection.cs b/Src/Solid-TradeService/5.ISP/Models/OrderDirection.cs deleted file mode 100644 index c0df608..0000000 --- a/Src/Solid-TradeService/5.ISP/Models/OrderDirection.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace TradeApp.Models -{ - public enum OrderDirection - { - Buy, - Sell - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/5.ISP/Program.cs b/Src/Solid-TradeService/5.ISP/Program.cs deleted file mode 100644 index a6bd937..0000000 --- a/Src/Solid-TradeService/5.ISP/Program.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Linq; -using TradeApp.App_Packages.LibLog._4._2; -using TradeApp.Models; - -namespace TradeApp -{ - class Program - { - static void Main(string[] args) - { - string username = Environment.UserName; - - Logging.LogProvider.SetCurrentLogProvider(new ColoredConsoleLogProvider()); - - DealService service = new DealService(username); - - var id = Guid.NewGuid().ToString(); - var deal = Deal.Empty.With( - id, - 500.00, - 10, - "MSFT", - DateTime.Now - ); - - service.Save(id, deal); - - - Console.WriteLine(); - Console.WriteLine(); - - var vincentDeal = service.Load(id).DefaultIfEmpty(Deal.Empty).Single(); - Console.WriteLine(vincentDeal); - - Console.ReadLine(); - } - } -} diff --git a/Src/Solid-TradeService/5.ISP/Properties/AssemblyInfo.cs b/Src/Solid-TradeService/5.ISP/Properties/AssemblyInfo.cs deleted file mode 100644 index b681b7c..0000000 --- a/Src/Solid-TradeService/5.ISP/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -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("TradeApp")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TradeApp")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[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("bba07b19-254a-4ef0-bcc5-f8954c963537")] - -// 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")] diff --git a/Src/Solid-TradeService/5.ISP/Readme.md b/Src/Solid-TradeService/5.ISP/Readme.md deleted file mode 100644 index 9950d2f..0000000 --- a/Src/Solid-TradeService/5.ISP/Readme.md +++ /dev/null @@ -1,37 +0,0 @@ -# Step 4 : Liskov Substitution Principle - -- Try resolve GetFileName LSP violation by adding a IFileLocator interface - - Extract method GetFileName(int id) in interface IFileLocator - - rename DealStorage in FileDealStorage - - implement IFileLocator in FileDealStorage - - add constuctor to set WorkingDirectory from username value - - in DealService add new Factory method to get a IFileLocator - -- Try resolve other issues - - extract IDealStorage - - SQLDealStorage and FileDealStorage now implement IDealStorage - - Interface must used id not path, we need to hide implementation - - Create a folder Storage and move 'storage' file in - -- Apply ISP on Caching - - extract interface from DealCaching - - Create a caching folder and move file in it - -- Apply ISP on Serializer - - extract interface from DealSerializer - - Create a Serializer folder and move file in it - -- Apply ISP on Logger - - extract interface from DealServiceLogger - - Create a Logger folder and move files in it - -- Use interface in DealService - - use interface everywhere - - clean code and refactoring naming - - remove all call to FileLocator, change query signature to return Maybe - -- Try to use same method signature when you can - - Storage.WriteDeal => Storage.Save - - Cache.AddOrUpdate = > Cache.Save - - Cache.GetOrAdd => Cache.Load - - Storage.ReadDeal => Storage.Load \ No newline at end of file diff --git a/Src/Solid-TradeService/5.ISP/Serializer/DealSerializer.cs b/Src/Solid-TradeService/5.ISP/Serializer/DealSerializer.cs deleted file mode 100644 index 014c248..0000000 --- a/Src/Solid-TradeService/5.ISP/Serializer/DealSerializer.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Linq; -using Newtonsoft.Json; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealSerializer : IDealSerializer - { - public virtual string SerializeDeal(Deal deal) - { - return JsonConvert.SerializeObject(deal); - } - - public virtual Maybe DeserializeDeal(Maybe serializedDeal) - { - if(!serializedDeal.Any()) return new Maybe(); - - try - { - return new Maybe(JsonConvert.DeserializeObject(serializedDeal.First())); - } - catch (Exception) - { - return new Maybe(); - } - } - } -} diff --git a/Src/Solid-TradeService/5.ISP/Serializer/IDealSerializer.cs b/Src/Solid-TradeService/5.ISP/Serializer/IDealSerializer.cs deleted file mode 100644 index ab6a5fb..0000000 --- a/Src/Solid-TradeService/5.ISP/Serializer/IDealSerializer.cs +++ /dev/null @@ -1,10 +0,0 @@ -using TradeApp.Models; - -namespace TradeApp -{ - public interface IDealSerializer - { - string SerializeDeal(Deal deal); - Maybe DeserializeDeal(Maybe serializedDeal); - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/5.ISP/Storage/FileDealStorage.cs b/Src/Solid-TradeService/5.ISP/Storage/FileDealStorage.cs deleted file mode 100644 index 85d04ab..0000000 --- a/Src/Solid-TradeService/5.ISP/Storage/FileDealStorage.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Diagnostics.Contracts; -using System.IO; - -namespace TradeApp -{ - public class FileDealStorage : IFileLocator, IDealStorage - { - private readonly string _directory; - - public FileDealStorage(string directory) - { - _directory = directory; - } - - public void Save(string id, string serializedDeal) - { - var path = GetFileName(id).FullName; - File.WriteAllText(path, serializedDeal); - } - - public Maybe Load(string id) - { - try - { - var path = GetFileName(id).FullName; - var text = File.ReadAllText(path); - return new Maybe(text); - } - catch (Exception) - { - return new Maybe(); - } - } - - public FileInfo GetFileName(string id) - { - return new FileInfo(Path.Combine(_directory, id + ".json")); - } - } -} diff --git a/Src/Solid-TradeService/5.ISP/Storage/IDealStorage.cs b/Src/Solid-TradeService/5.ISP/Storage/IDealStorage.cs deleted file mode 100644 index b34c269..0000000 --- a/Src/Solid-TradeService/5.ISP/Storage/IDealStorage.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace TradeApp -{ - public interface IDealStorage - { - void Save(string id, string serializedDeal); - Maybe Load(string id); - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/5.ISP/Storage/IFileLocator.cs b/Src/Solid-TradeService/5.ISP/Storage/IFileLocator.cs deleted file mode 100644 index f28cc37..0000000 --- a/Src/Solid-TradeService/5.ISP/Storage/IFileLocator.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.IO; - -namespace TradeApp -{ - public interface IFileLocator - { - FileInfo GetFileName(string id); - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/5.ISP/Storage/SQLDealStorage.cs b/Src/Solid-TradeService/5.ISP/Storage/SQLDealStorage.cs deleted file mode 100644 index 0d76897..0000000 --- a/Src/Solid-TradeService/5.ISP/Storage/SQLDealStorage.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Data.SqlClient; -using System.IO; -using System.Linq; -using Dapper; - -namespace TradeApp -{ - public class SQLDealStorage : IDealStorage - { - private readonly string _connectionString; - - public SQLDealStorage(string connectionString) - { - _connectionString = connectionString; - } - - public Maybe Load(string id) - { - - using (SqlConnection connection = new SqlConnection(_connectionString)) - { - connection.Open(); - var result = connection.Query("select Value from Deals where Id = @Id", new { Id = id }).ToArray(); - if(result.Any()) - return new Maybe(result.First()); - - return new Maybe(); - } - } - - public void Save(string id, string serializedDeal) - { - using (SqlConnection connection = new SqlConnection(_connectionString)) - { - connection.Open(); - connection.Execute(@"delete from Deals where Id = @Id", new { Id = id }); - connection.Execute(@"insert Deals(Id, Value) values (@Id, @Value)", - new {Id = id, Value = serializedDeal}); - } - } - } -} diff --git a/Src/Solid-TradeService/5.ISP/TradeApp.csproj b/Src/Solid-TradeService/5.ISP/TradeApp.csproj deleted file mode 100644 index dbf7be4..0000000 --- a/Src/Solid-TradeService/5.ISP/TradeApp.csproj +++ /dev/null @@ -1,134 +0,0 @@ - - - - - Debug - AnyCPU - {F4D8FF66-07AE-4DD4-8F9D-F22E84C4BD01} - Exe - Properties - TradeApp - TradeApp - v4.6 - 512 - true - 1 - - - AnyCPU - true - full - false - bin\Debug\ - TRACE;DEBUG - prompt - 4 - False - False - True - False - False - False - True - True - True - True - True - True - True - True - False - True - False - True - False - False - False - True - True - False - True - True - True - False - False - - - - - - - - True - False - False - True - Full - %28none%29 - 3 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Dapper.1.42\lib\net45\Dapper.dll - - - ..\..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - True - - - - ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/5.ISP/packages.config b/Src/Solid-TradeService/5.ISP/packages.config deleted file mode 100644 index 88af6e8..0000000 --- a/Src/Solid-TradeService/5.ISP/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/6.DIP/App.config b/Src/Solid-TradeService/6.DIP/App.config deleted file mode 100644 index 8324aa6..0000000 --- a/Src/Solid-TradeService/6.DIP/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/6.DIP/Caching/DealCaching.cs b/Src/Solid-TradeService/6.DIP/Caching/DealCaching.cs deleted file mode 100644 index 2f1286f..0000000 --- a/Src/Solid-TradeService/6.DIP/Caching/DealCaching.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Immutable; -using System.Linq; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealCaching : IDealReader, IDealWriter - { - private readonly IDealReader _reader; - private readonly IDealWriter _writer; - private ImmutableDictionary> _cache; - - public DealCaching(IDealReader reader, IDealWriter writer) - { - _reader = reader; - _writer = writer; - _cache = ImmutableDictionary>.Empty; - } - - public void Save(Maybe deal) - { - _writer.Save(deal); - ImmutableInterlocked.AddOrUpdate(ref _cache, deal.Single().Id, deal, (i, d) => deal); - - } - - public Maybe Load(string id) - { - return ImmutableInterlocked.GetOrAdd(ref _cache, id, i => _reader.Load(i)); - } - } -} diff --git a/Src/Solid-TradeService/6.DIP/DealService.cs b/Src/Solid-TradeService/6.DIP/DealService.cs deleted file mode 100644 index fdc49aa..0000000 --- a/Src/Solid-TradeService/6.DIP/DealService.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Diagnostics.Contracts; -using System.IO; -using System.Linq; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealService - { - private readonly IDealWriter _writer; - private readonly IDealReader _reader; - - public DealService(IDealWriter writer, IDealReader reader) - { - if (writer == null) { throw new ArgumentNullException(nameof(writer)); } - if (reader == null) { throw new ArgumentNullException(nameof(reader)); } - - _writer = writer; - _reader = reader; - - } - - public void Save(Maybe deal) - { - _writer.Save(deal); - } - - public Maybe Load(string id) - { - return _reader.Load(id); - } - } -} diff --git a/Src/Solid-TradeService/6.DIP/DealServiceDiagram.cd b/Src/Solid-TradeService/6.DIP/DealServiceDiagram.cd deleted file mode 100644 index 4007499..0000000 --- a/Src/Solid-TradeService/6.DIP/DealServiceDiagram.cd +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - AAAIgIAEAAAAAAAAAQAAAAAAAAAAIAAAAAAAAgAAAAA= - DealService.cs - - - - - - - - - - - - AAAAAAAAAIAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAA= - DealCaching.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAABA= - DealSerializer.cs - - - - - - AAAAAAAAAIEAAAAAAAAIAICAIAAAAAAAAAAAAAAAAAA= - DealServiceLogger.cs - - - - - - AAAAAAAAAEAAAAAAAAAABAAAQAAAAAAAAAAAAAAAAAA= - DealStorage.cs - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/6.DIP/IDealReader.cs b/Src/Solid-TradeService/6.DIP/IDealReader.cs deleted file mode 100644 index 904ed8b..0000000 --- a/Src/Solid-TradeService/6.DIP/IDealReader.cs +++ /dev/null @@ -1,9 +0,0 @@ -using TradeApp.Models; - -namespace TradeApp -{ - public interface IDealReader - { - Maybe Load(string id); - } -} diff --git a/Src/Solid-TradeService/6.DIP/IDealWriter.cs b/Src/Solid-TradeService/6.DIP/IDealWriter.cs deleted file mode 100644 index 4d1ae37..0000000 --- a/Src/Solid-TradeService/6.DIP/IDealWriter.cs +++ /dev/null @@ -1,9 +0,0 @@ -using TradeApp.Models; - -namespace TradeApp -{ - public interface IDealWriter - { - void Save(Maybe deal); - } -} diff --git a/Src/Solid-TradeService/6.DIP/Log/ColoredConsoleLogProvider.cs b/Src/Solid-TradeService/6.DIP/Log/ColoredConsoleLogProvider.cs deleted file mode 100644 index 6853892..0000000 --- a/Src/Solid-TradeService/6.DIP/Log/ColoredConsoleLogProvider.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using TradeApp.Logging; - -namespace TradeApp.App_Packages.LibLog._4._2 -{ - public class ColoredConsoleLogProvider : ILogProvider - { - private static readonly Dictionary Colors = new Dictionary - { - {LogLevel.Fatal, ConsoleColor.Red}, - {LogLevel.Error, ConsoleColor.Yellow}, - {LogLevel.Warn, ConsoleColor.Magenta}, - {LogLevel.Info, ConsoleColor.White}, - {LogLevel.Debug, ConsoleColor.Gray}, - {LogLevel.Trace, ConsoleColor.DarkGray}, - }; - - public Logger GetLogger(string name) - { - return (logLevel, messageFunc, exception, formatParameters) => - { - if (messageFunc == null) - { - return true; // All log levels are enabled - } - - ConsoleColor consoleColor; - if (Colors.TryGetValue(logLevel, out consoleColor)) - { - var originalForground = Console.ForegroundColor; - try - { - Console.ForegroundColor = consoleColor; - WriteMessage(logLevel, name, messageFunc, formatParameters, exception); - } - finally - { - Console.ForegroundColor = originalForground; - } - } - else - { - WriteMessage(logLevel, name, messageFunc, formatParameters, exception); - } - - return true; - }; - } - - private static void WriteMessage( - LogLevel logLevel, - string name, - Func messageFunc, - object[] formatParameters, - Exception exception) - { - var message = string.Format(CultureInfo.InvariantCulture, messageFunc(), formatParameters); - if (exception != null) - { - message = message + "|" + exception; - } - Console.WriteLine("{0} | {1} | {2} | {3}", DateTime.UtcNow, logLevel, name, message); - } - - public IDisposable OpenNestedContext(string message) - { - return NullDisposable.Instance; - } - - public IDisposable OpenMappedContext(string key, string value) - { - return NullDisposable.Instance; - } - - private class NullDisposable : IDisposable - { - internal static readonly IDisposable Instance = new NullDisposable(); - - public void Dispose() - { } - } - } -} diff --git a/Src/Solid-TradeService/6.DIP/Log/LibLog.cs b/Src/Solid-TradeService/6.DIP/Log/LibLog.cs deleted file mode 100644 index f761084..0000000 --- a/Src/Solid-TradeService/6.DIP/Log/LibLog.cs +++ /dev/null @@ -1,1998 +0,0 @@ -//=============================================================================== -// LibLog -// -// https://github.com/damianh/LibLog -//=============================================================================== -// Copyright © 2011-2015 Damian Hickey. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//=============================================================================== - -// ReSharper disable PossibleNullReferenceException - -// Define LIBLOG_PORTABLE conditional compilation symbol for PCL compatibility -// -// Define LIBLOG_PUBLIC to enable ability to GET a logger (LogProvider.For<>() etc) from outside this library. NOTE: -// this can have unintended consequences of consumers of your library using your library to resolve a logger. If the -// reason is because you want to open this functionality to other projects within your solution, -// consider [InternalVisibleTo] instead. -// -// Define LIBLOG_PROVIDERS_ONLY if your library provides its own logging API and you just want to use the -// LibLog providers internally to provide built in support for popular logging frameworks. - -#pragma warning disable 1591 - -// If you copied this file manually, you need to change all "YourRootNameSpace" so not to clash with other libraries -// that use LibLog -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog -#else -namespace TradeApp.Logging -#endif -{ - using System.Collections.Generic; -#if LIBLOG_PROVIDERS_ONLY - using TradeApp.LibLog.LogProviders; -#else - using TradeApp.Logging.LogProviders; -#endif - using System; -#if !LIBLOG_PROVIDERS_ONLY - using System.Diagnostics; -#if !LIBLOG_PORTABLE - using System.Runtime.CompilerServices; -#endif -#endif - -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - delegate bool Logger(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters); - -#if !LIBLOG_PROVIDERS_ONLY - /// - /// Simple interface that represent a logger. - /// -#if LIBLOG_PUBLIC - public -#else - internal -#endif - interface ILog - { - /// - /// Log a message the specified log level. - /// - /// The log level. - /// The message function. - /// An optional exception. - /// Optional format parameters for the message generated by the messagefunc. - /// true if the message was logged. Otherwise false. - /// - /// Note to implementers: the message func should not be called if the loglevel is not enabled - /// so as not to incur performance penalties. - /// - /// To check IsEnabled call Log with only LogLevel and check the return value, no event will be written. - /// - bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters ); - } -#endif - - /// - /// The log level. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - enum LogLevel - { - Trace, - Debug, - Info, - Warn, - Error, - Fatal - } - -#if !LIBLOG_PROVIDERS_ONLY -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static partial class LogExtensions - { - public static bool IsDebugEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Debug, null); - } - - public static bool IsErrorEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Error, null); - } - - public static bool IsFatalEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Fatal, null); - } - - public static bool IsInfoEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Info, null); - } - - public static bool IsTraceEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Trace, null); - } - - public static bool IsWarnEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Warn, null); - } - - public static void Debug(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Debug, messageFunc); - } - - public static void Debug(this ILog logger, string message) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc()); - } - } - - public static void DebugFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsDebugEnabled()) - { - logger.LogFormat(LogLevel.Debug, message, args); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception, formatParams); - } - } - - public static void Error(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Error, messageFunc); - } - - public static void Error(this ILog logger, string message) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc()); - } - } - - public static void ErrorFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsErrorEnabled()) - { - logger.LogFormat(LogLevel.Error, message, args); - } - } - - public static void ErrorException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc(), exception, formatParams); - } - } - - public static void Fatal(this ILog logger, Func messageFunc) - { - logger.Log(LogLevel.Fatal, messageFunc); - } - - public static void Fatal(this ILog logger, string message) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc()); - } - } - - public static void FatalFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsFatalEnabled()) - { - logger.LogFormat(LogLevel.Fatal, message, args); - } - } - - public static void FatalException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc(), exception, formatParams); - } - } - - public static void Info(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Info, messageFunc); - } - - public static void Info(this ILog logger, string message) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc()); - } - } - - public static void InfoFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsInfoEnabled()) - { - logger.LogFormat(LogLevel.Info, message, args); - } - } - - public static void InfoException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc(), exception, formatParams); - } - } - - public static void Trace(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Trace, messageFunc); - } - - public static void Trace(this ILog logger, string message) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc()); - } - } - - public static void TraceFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsTraceEnabled()) - { - logger.LogFormat(LogLevel.Trace, message, args); - } - } - - public static void TraceException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc(), exception, formatParams); - } - } - - public static void Warn(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Warn, messageFunc); - } - - public static void Warn(this ILog logger, string message) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc()); - } - } - - public static void WarnFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsWarnEnabled()) - { - logger.LogFormat(LogLevel.Warn, message, args); - } - } - - public static void WarnException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc(), exception, formatParams); - } - } - - // ReSharper disable once UnusedParameter.Local - private static void GuardAgainstNullLogger(ILog logger) - { - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - } - - private static void LogFormat(this ILog logger, LogLevel logLevel, string message, params object[] args) - { - logger.Log(logLevel, message.AsFunc(), null, args); - } - - // Avoid the closure allocation, see https://gist.github.com/AArnott/d285feef75c18f6ecd2b - private static Func AsFunc(this T value) where T : class - { - return value.Return; - } - - private static T Return(this T value) - { - return value; - } - } -#endif - - /// - /// Represents a way to get a - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - interface ILogProvider - { - /// - /// Gets the specified named logger. - /// - /// Name of the logger. - /// The logger reference. - Logger GetLogger(string name); - - /// - /// Opens a nested diagnostics context. Not supported in EntLib logging. - /// - /// The message to add to the diagnostics context. - /// A disposable that when disposed removes the message from the context. - IDisposable OpenNestedContext(string message); - - /// - /// Opens a mapped diagnostics context. Not supported in EntLib logging. - /// - /// A key. - /// A value. - /// A disposable that when disposed removes the map from the context. - IDisposable OpenMappedContext(string key, string value); - } - - /// - /// Provides a mechanism to create instances of objects. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - static class LogProvider - { -#if !LIBLOG_PROVIDERS_ONLY - /// - /// The disable logging environment variable. If the environment variable is set to 'true', then logging - /// will be disabled. - /// - public const string DisableLoggingEnvironmentVariable = "TradeApp_LIBLOG_DISABLE"; - private const string NullLogProvider = "Current Log Provider is not set. Call SetCurrentLogProvider " + - "with a non-null value first."; - private static dynamic s_currentLogProvider; - private static Action s_onCurrentLogProviderSet; - - static LogProvider() - { - IsDisabled = false; - } - - /// - /// Sets the current log provider. - /// - /// The log provider. - public static void SetCurrentLogProvider(ILogProvider logProvider) - { - s_currentLogProvider = logProvider; - - RaiseOnCurrentLogProviderSet(); - } - - /// - /// Gets or sets a value indicating whether this is logging is disabled. - /// - /// - /// true if logging is disabled; otherwise, false. - /// - public static bool IsDisabled { get; set; } - - /// - /// Sets an action that is invoked when a consumer of your library has called SetCurrentLogProvider. It is - /// important that hook into this if you are using child libraries (especially ilmerged ones) that are using - /// LibLog (or other logging abstraction) so you adapt and delegate to them. - /// - /// - internal static Action OnCurrentLogProviderSet - { - set - { - s_onCurrentLogProviderSet = value; - RaiseOnCurrentLogProviderSet(); - } - } - - internal static ILogProvider CurrentLogProvider - { - get - { - return s_currentLogProvider; - } - } - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog For() - { - return GetLogger(typeof(T)); - } - -#if !LIBLOG_PORTABLE - /// - /// Gets a logger for the current class. - /// - /// An instance of - [MethodImpl(MethodImplOptions.NoInlining)] -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetCurrentClassLogger() - { - var stackFrame = new StackFrame(1, false); - return GetLogger(stackFrame.GetMethod().DeclaringType); - } -#endif - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(Type type) - { - return GetLogger(type.FullName); - } - - /// - /// Gets a logger with the specified name. - /// - /// The name. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(string name) - { - ILogProvider logProvider = CurrentLogProvider ?? ResolveLogProvider(); - return logProvider == null - ? NoOpLogger.Instance - : (ILog)new LoggerExecutionWrapper(logProvider.GetLogger(name), () => IsDisabled); - } - - /// - /// Opens a nested diagnostics context. - /// - /// A message. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenNestedContext(string message) - { - if(CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenNestedContext(message); - } - - /// - /// Opens a mapped diagnostics context. - /// - /// A key. - /// A value. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenMappedContext(string key, string value) - { - if (CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenMappedContext(key, value); - } -#endif - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate bool IsLoggerAvailable(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate ILogProvider CreateLogProvider(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - static readonly List> LogProviderResolvers = - new List> - { - new Tuple(SerilogLogProvider.IsLoggerAvailable, () => new SerilogLogProvider()), - new Tuple(NLogLogProvider.IsLoggerAvailable, () => new NLogLogProvider()), - new Tuple(Log4NetLogProvider.IsLoggerAvailable, () => new Log4NetLogProvider()), - new Tuple(EntLibLogProvider.IsLoggerAvailable, () => new EntLibLogProvider()), - new Tuple(LoupeLogProvider.IsLoggerAvailable, () => new LoupeLogProvider()), - }; - -#if !LIBLOG_PROVIDERS_ONLY - private static void RaiseOnCurrentLogProviderSet() - { - if (s_onCurrentLogProviderSet != null) - { - s_onCurrentLogProviderSet(s_currentLogProvider); - } - } -#endif - - internal static ILogProvider ResolveLogProvider() - { - try - { - foreach (var providerResolver in LogProviderResolvers) - { - if (providerResolver.Item1()) - { - return providerResolver.Item2(); - } - } - } - catch (Exception ex) - { -#if LIBLOG_PORTABLE - Debug.WriteLine( -#else - Console.WriteLine( -#endif - "Exception occurred resolving a log provider. Logging for this assembly {0} is disabled. {1}", - typeof(LogProvider).GetAssemblyPortable().FullName, - ex); - } - return null; - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class NoOpLogger : ILog - { - internal static readonly NoOpLogger Instance = new NoOpLogger(); - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - return false; - } - } -#endif - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class LoggerExecutionWrapper : ILog - { - private readonly Logger _logger; - private readonly Func _getIsDisabled; - internal const string FailedToGenerateLogMessage = "Failed to generate log message"; - - internal LoggerExecutionWrapper(Logger logger, Func getIsDisabled = null) - { - _logger = logger; - _getIsDisabled = getIsDisabled ?? (() => false); - } - - internal Logger WrappedLogger - { - get { return _logger; } - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters) - { - if (_getIsDisabled()) - { - return false; - } -#if !LIBLOG_PORTABLE - var envVar = Environment.GetEnvironmentVariable(LogProvider.DisableLoggingEnvironmentVariable); - - if (envVar != null && envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) - { - return false; - } -#endif - - if (messageFunc == null) - { - return _logger(logLevel, null); - } - - Func wrappedMessageFunc = () => - { - try - { - return messageFunc(); - } - catch (Exception ex) - { - Log(LogLevel.Error, () => FailedToGenerateLogMessage, ex); - } - return null; - }; - return _logger(logLevel, wrappedMessageFunc, exception, formatParameters); - } - } -#endif -} - -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog.LogProviders -#else -namespace TradeApp.Logging.LogProviders -#endif -{ - using System; - using System.Collections.Generic; -#if !LIBLOG_PORTABLE - using System.Diagnostics; -#endif - using System.Globalization; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; -#if !LIBLOG_PORTABLE - using System.Text; -#endif - using System.Text.RegularExpressions; - - internal abstract class LogProviderBase : ILogProvider - { - protected delegate IDisposable OpenNdc(string message); - protected delegate IDisposable OpenMdc(string key, string value); - - private readonly Lazy _lazyOpenNdcMethod; - private readonly Lazy _lazyOpenMdcMethod; - private static readonly IDisposable NoopDisposableInstance = new DisposableAction(); - - protected LogProviderBase() - { - _lazyOpenNdcMethod - = new Lazy(GetOpenNdcMethod); - _lazyOpenMdcMethod - = new Lazy(GetOpenMdcMethod); - } - - public abstract Logger GetLogger(string name); - - public IDisposable OpenNestedContext(string message) - { - return _lazyOpenNdcMethod.Value(message); - } - - public IDisposable OpenMappedContext(string key, string value) - { - return _lazyOpenMdcMethod.Value(key, value); - } - - protected virtual OpenNdc GetOpenNdcMethod() - { - return _ => NoopDisposableInstance; - } - - protected virtual OpenMdc GetOpenMdcMethod() - { - return (_, __) => NoopDisposableInstance; - } - } - - internal class NLogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public NLogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("NLog.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new NLogLogger(_getLoggerByNameDelegate(name)).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("NLog.NestedDiagnosticsContext, NLog"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("NLog.MappedDiagnosticsContext, NLog"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("NLog.LogManager, NLog"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class NLogLogger - { - private readonly dynamic _logger; - - internal NLogLogger(dynamic logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - if(exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.Debug(messageFunc()); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.Info(messageFunc()); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.Warn(messageFunc()); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.Error(messageFunc()); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.Fatal(messageFunc()); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.Trace(messageFunc()); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.DebugException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.InfoException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.WarnException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.ErrorException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.FatalException(messageFunc(), exception); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.TraceException(messageFunc(), exception); - return true; - } - break; - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Debug: - return _logger.IsDebugEnabled; - case LogLevel.Info: - return _logger.IsInfoEnabled; - case LogLevel.Warn: - return _logger.IsWarnEnabled; - case LogLevel.Error: - return _logger.IsErrorEnabled; - case LogLevel.Fatal: - return _logger.IsFatalEnabled; - default: - return _logger.IsTraceEnabled; - } - } - } - } - - internal class Log4NetLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public Log4NetLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("log4net.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new Log4NetLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("log4net.NDC, log4net"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("log4net.MDC, log4net"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("log4net.LogManager, log4net"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class Log4NetLogger - { - private readonly dynamic _logger; - private static Type s_callerStackBoundaryType; - private static readonly object CallerStackBoundaryTypeSync = new object(); - - private readonly object _levelDebug; - private readonly object _levelInfo; - private readonly object _levelWarn; - private readonly object _levelError; - private readonly object _levelFatal; - private readonly Func _isEnabledForDelegate; - private readonly Action _logDelegate; - - internal Log4NetLogger(dynamic logger) - { - _logger = logger.Logger; - - var logEventLevelType = Type.GetType("log4net.Core.Level, log4net"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type log4net.Core.Level was not found."); - } - - var levelFields = logEventLevelType.GetFieldsPortable().ToList(); - _levelDebug = levelFields.First(x => x.Name == "Debug").GetValue(null); - _levelInfo = levelFields.First(x => x.Name == "Info").GetValue(null); - _levelWarn = levelFields.First(x => x.Name == "Warn").GetValue(null); - _levelError = levelFields.First(x => x.Name == "Error").GetValue(null); - _levelFatal = levelFields.First(x => x.Name == "Fatal").GetValue(null); - - // Func isEnabledFor = (logger, level) => { return ((log4net.Core.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("log4net.Core.ILogger, log4net"); - if (loggerType == null) - { - throw new InvalidOperationException("Type log4net.Core.ILogger, was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabledFor", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression callerStackBoundaryDeclaringTypeParam = Expression.Parameter(typeof(Type)); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - _isEnabledForDelegate = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Log = - // (logger, callerStackBoundaryDeclaringType, level, message, exception) => { ((ILogger)logger).Write(callerStackBoundaryDeclaringType, level, message, exception); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Log", - typeof(Type), - logEventLevelType, - typeof(string), - typeof(Exception)); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - var writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - callerStackBoundaryDeclaringTypeParam, - levelCast, - messageParam, - exceptionParam); - _logDelegate = Expression.Lambda>( - writeMethodExp, - instanceParam, - callerStackBoundaryDeclaringTypeParam, - levelParam, - messageParam, - exceptionParam).Compile(); - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - - if (!IsLogLevelEnable(logLevel)) - { - return false; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - // determine correct caller - this might change due to jit optimizations with method inlining - if (s_callerStackBoundaryType == null) - { - lock (CallerStackBoundaryTypeSync) - { -#if !LIBLOG_PORTABLE - StackTrace stack = new StackTrace(); - Type thisType = GetType(); - s_callerStackBoundaryType = Type.GetType("LoggerExecutionWrapper"); - for (var i = 1; i < stack.FrameCount; i++) - { - if (!IsInTypeHierarchy(thisType, stack.GetFrame(i).GetMethod().DeclaringType)) - { - s_callerStackBoundaryType = stack.GetFrame(i - 1).GetMethod().DeclaringType; - break; - } - } -#else - s_callerStackBoundaryType = typeof (LoggerExecutionWrapper); -#endif - } - } - - var translatedLevel = TranslateLevel(logLevel); - _logDelegate(_logger, s_callerStackBoundaryType, translatedLevel, messageFunc(), exception); - return true; - } - - private bool IsInTypeHierarchy(Type currentType, Type checkType) - { - while (currentType != null && currentType != typeof(object)) - { - if (currentType == checkType) - { - return true; - } - currentType = currentType.GetBaseTypePortable(); - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - var level = TranslateLevel(logLevel); - return _isEnabledForDelegate(_logger, level); - } - - private object TranslateLevel(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - case LogLevel.Debug: - return _levelDebug; - case LogLevel.Info: - return _levelInfo; - case LogLevel.Warn: - return _levelWarn; - case LogLevel.Error: - return _levelError; - case LogLevel.Fatal: - return _levelFatal; - default: - throw new ArgumentOutOfRangeException("logLevel", logLevel, null); - } - } - } - } - - internal class EntLibLogProvider : LogProviderBase - { - private const string TypeTemplate = "Microsoft.Practices.EnterpriseLibrary.Logging.{0}, Microsoft.Practices.EnterpriseLibrary.Logging"; - private static bool s_providerIsAvailableOverride = true; - private static readonly Type LogEntryType; - private static readonly Type LoggerType; - private static readonly Type TraceEventTypeType; - private static readonly Action WriteLogEntry; - private static readonly Func ShouldLogEntry; - - static EntLibLogProvider() - { - LogEntryType = Type.GetType(string.Format(TypeTemplate, "LogEntry")); - LoggerType = Type.GetType(string.Format(TypeTemplate, "Logger")); - TraceEventTypeType = TraceEventTypeValues.Type; - if (LogEntryType == null - || TraceEventTypeType == null - || LoggerType == null) - { - return; - } - WriteLogEntry = GetWriteLogEntry(); - ShouldLogEntry = GetShouldLogEntry(); - } - - public EntLibLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Microsoft.Practices.EnterpriseLibrary.Logging.Logger not found"); - } - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new EntLibLogger(name, WriteLogEntry, ShouldLogEntry).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride - && TraceEventTypeType != null - && LogEntryType != null; - } - - private static Action GetWriteLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var messageParameter = Expression.Parameter(typeof(string), "message"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - messageParameter, - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("Write", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - messageParameter, - severityParameter).Compile(); - } - - private static Func GetShouldLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - Expression.Constant("***dummy***"), - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("ShouldLog", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - severityParameter).Compile(); - } - - private static MemberInitExpression GetWriteLogExpression(Expression message, - Expression severityParameter, ParameterExpression logNameParameter) - { - var entryType = LogEntryType; - MemberInitExpression memberInit = Expression.MemberInit(Expression.New(entryType), - Expression.Bind(entryType.GetPropertyPortable("Message"), message), - Expression.Bind(entryType.GetPropertyPortable("Severity"), severityParameter), - Expression.Bind( - entryType.GetPropertyPortable("TimeStamp"), - Expression.Property(null, typeof (DateTime).GetPropertyPortable("UtcNow"))), - Expression.Bind( - entryType.GetPropertyPortable("Categories"), - Expression.ListInit( - Expression.New(typeof (List)), - typeof (List).GetMethodPortable("Add", typeof (string)), - logNameParameter))); - return memberInit; - } - - internal class EntLibLogger - { - private readonly string _loggerName; - private readonly Action _writeLog; - private readonly Func _shouldLog; - - internal EntLibLogger(string loggerName, Action writeLog, Func shouldLog) - { - _loggerName = loggerName; - _writeLog = writeLog; - _shouldLog = shouldLog; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - var severity = MapSeverity(logLevel); - if (messageFunc == null) - { - return _shouldLog(_loggerName, severity); - } - - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - if (exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - _writeLog(_loggerName, messageFunc(), severity); - return true; - } - - public bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - var severity = MapSeverity(logLevel); - var message = messageFunc() + Environment.NewLine + exception; - _writeLog(_loggerName, message, severity); - return true; - } - - private static int MapSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Info: - return TraceEventTypeValues.Information; - default: - return TraceEventTypeValues.Verbose; - } - } - } - } - - internal class SerilogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public SerilogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Serilog.Log not found"); - } - _getLoggerByNameDelegate = GetForContextMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new SerilogLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - return message => GetPushProperty()("NDC", message); - } - - protected override OpenMdc GetOpenMdcMethod() - { - return (key, value) => GetPushProperty()(key, value); - } - - private static Func GetPushProperty() - { - Type ndcContextType = Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"); - MethodInfo pushPropertyMethod = ndcContextType.GetMethodPortable( - "PushProperty", - typeof(string), - typeof(object), - typeof(bool)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression pushPropertyMethodCall = Expression - .Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam); - var pushProperty = Expression - .Lambda>( - pushPropertyMethodCall, - nameParam, - valueParam, - destructureObjectParam) - .Compile(); - - return (key, value) => pushProperty(key, value, false); - } - - private static Type GetLogManagerType() - { - return Type.GetType("Serilog.Log, Serilog"); - } - - private static Func GetForContextMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("ForContext", typeof(string), typeof(object), typeof(bool)); - ParameterExpression propertyNameParam = Expression.Parameter(typeof(string), "propertyName"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectsParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression methodCall = Expression.Call(null, method, new Expression[] - { - propertyNameParam, - valueParam, - destructureObjectsParam - }); - var func = Expression.Lambda>( - methodCall, - propertyNameParam, - valueParam, - destructureObjectsParam) - .Compile(); - return name => func("Name", name, false); - } - - internal class SerilogLogger - { - private readonly object _logger; - private static readonly object DebugLevel; - private static readonly object ErrorLevel; - private static readonly object FatalLevel; - private static readonly object InformationLevel; - private static readonly object VerboseLevel; - private static readonly object WarningLevel; - private static readonly Func IsEnabled; - private static readonly Action Write; - private static readonly Action WriteException; - - static SerilogLogger() - { - var logEventLevelType = Type.GetType("Serilog.Events.LogEventLevel, Serilog"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type Serilog.Events.LogEventLevel was not found."); - } - DebugLevel = Enum.Parse(logEventLevelType, "Debug", false); - ErrorLevel = Enum.Parse(logEventLevelType, "Error", false); - FatalLevel = Enum.Parse(logEventLevelType, "Fatal", false); - InformationLevel = Enum.Parse(logEventLevelType, "Information", false); - VerboseLevel = Enum.Parse(logEventLevelType, "Verbose", false); - WarningLevel = Enum.Parse(logEventLevelType, "Warning", false); - - // Func isEnabled = (logger, level) => { return ((SeriLog.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("Serilog.ILogger, Serilog"); - if (loggerType == null) - { - throw new InvalidOperationException("Type Serilog.ILogger was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabled", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - IsEnabled = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Write = - // (logger, level, message, params) => { ((SeriLog.ILoggerILogger)logger).Write(level, message, params); } - MethodInfo writeMethodInfo = loggerType.GetMethodPortable("Write", logEventLevelType, typeof(string), typeof(object[])); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - ParameterExpression propertyValuesParam = Expression.Parameter(typeof(object[])); - MethodCallExpression writeMethodExp = Expression.Call( - instanceCast, - writeMethodInfo, - levelCast, - messageParam, - propertyValuesParam); - var expression = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - messageParam, - propertyValuesParam); - Write = expression.Compile(); - - // Action WriteException = - // (logger, level, exception, message) => { ((ILogger)logger).Write(level, exception, message, new object[]); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Write", - logEventLevelType, - typeof(Exception), - typeof(string), - typeof(object[])); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - levelCast, - exceptionParam, - messageParam, - propertyValuesParam); - WriteException = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - exceptionParam, - messageParam, - propertyValuesParam).Compile(); - } - - internal SerilogLogger(object logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsEnabled(_logger, logLevel); - } - if (exception != null) - { - return LogException(logLevel, messageFunc, exception, formatParameters); - } - - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - Write(_logger, DebugLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - Write(_logger, InformationLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - Write(_logger, WarningLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - Write(_logger, ErrorLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - Write(_logger, FatalLevel, messageFunc(), formatParameters); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - Write(_logger, VerboseLevel, messageFunc(), formatParameters); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception, object[] formatParams) - { - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - WriteException(_logger, DebugLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - WriteException(_logger, InformationLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - WriteException(_logger, WarningLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - WriteException(_logger, ErrorLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - WriteException(_logger, FatalLevel, exception, messageFunc(), formatParams); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - WriteException(_logger, VerboseLevel, exception, messageFunc(), formatParams); - return true; - } - break; - } - return false; - } - } - } - - internal class LoupeLogProvider : LogProviderBase - { - /// - /// The form of the Loupe Log.Write method we're using - /// - internal delegate void WriteDelegate( - int severity, - string logSystem, - int skipFrames, - Exception exception, - bool attributeToException, - int writeMode, - string detailsXml, - string category, - string caption, - string description, - params object[] args - ); - - private static bool s_providerIsAvailableOverride = true; - private readonly WriteDelegate _logWriteDelegate; - - public LoupeLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Gibraltar.Agent.Log (Loupe) not found"); - } - - _logWriteDelegate = GetLogWriteDelegate(); - } - - /// - /// Gets or sets a value indicating whether [provider is available override]. Used in tests. - /// - /// - /// true if [provider is available override]; otherwise, false. - /// - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new LoupeLogger(name, _logWriteDelegate).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - private static Type GetLogManagerType() - { - return Type.GetType("Gibraltar.Agent.Log, Gibraltar.Agent"); - } - - private static WriteDelegate GetLogWriteDelegate() - { - Type logManagerType = GetLogManagerType(); - Type logMessageSeverityType = Type.GetType("Gibraltar.Agent.LogMessageSeverity, Gibraltar.Agent"); - Type logWriteModeType = Type.GetType("Gibraltar.Agent.LogWriteMode, Gibraltar.Agent"); - - MethodInfo method = logManagerType.GetMethodPortable( - "Write", - logMessageSeverityType, typeof(string), typeof(int), typeof(Exception), typeof(bool), - logWriteModeType, typeof(string), typeof(string), typeof(string), typeof(string), typeof(object[])); - - var callDelegate = (WriteDelegate)method.CreateDelegate(typeof(WriteDelegate)); - return callDelegate; - } - - internal class LoupeLogger - { - private const string LogSystem = "LibLog"; - - private readonly string _category; - private readonly WriteDelegate _logWriteDelegate; - private readonly int _skipLevel; - - internal LoupeLogger(string category, WriteDelegate logWriteDelegate) - { - _category = category; - _logWriteDelegate = logWriteDelegate; -#if DEBUG - _skipLevel = 2; -#else - _skipLevel = 1; -#endif - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - //nothing to log.. - return true; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - _logWriteDelegate(ToLogMessageSeverity(logLevel), LogSystem, _skipLevel, exception, true, 0, null, - _category, null, messageFunc.Invoke()); - - return true; - } - - private int ToLogMessageSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - return TraceEventTypeValues.Verbose; - case LogLevel.Debug: - return TraceEventTypeValues.Verbose; - case LogLevel.Info: - return TraceEventTypeValues.Information; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - default: - throw new ArgumentOutOfRangeException("logLevel"); - } - } - } - } - - internal static class TraceEventTypeValues - { - internal static readonly Type Type; - internal static readonly int Verbose; - internal static readonly int Information; - internal static readonly int Warning; - internal static readonly int Error; - internal static readonly int Critical; - - static TraceEventTypeValues() - { - var assembly = typeof(Uri).GetAssemblyPortable(); // This is to get to the System.dll assembly in a PCL compatible way. - if (assembly == null) - { - return; - } - Type = assembly.GetType("System.Diagnostics.TraceEventType"); - if (Type == null) return; - Verbose = (int)Enum.Parse(Type, "Verbose", false); - Information = (int)Enum.Parse(Type, "Information", false); - Warning = (int)Enum.Parse(Type, "Warning", false); - Error = (int)Enum.Parse(Type, "Error", false); - Critical = (int)Enum.Parse(Type, "Critical", false); - } - } - - internal static class LogMessageFormatter - { - private static readonly Regex Pattern = new Regex(@"\{@?\w{1,}\}"); - - /// - /// Some logging frameworks support structured logging, such as serilog. This will allow you to add names to structured data in a format string: - /// For example: Log("Log message to {user}", user). This only works with serilog, but as the user of LibLog, you don't know if serilog is actually - /// used. So, this class simulates that. it will replace any text in {curly braces} with an index number. - /// - /// "Log {message} to {user}" would turn into => "Log {0} to {1}". Then the format parameters are handled using regular .net string.Format. - /// - /// The message builder. - /// The format parameters. - /// - public static Func SimulateStructuredLogging(Func messageBuilder, object[] formatParameters) - { - if (formatParameters == null || formatParameters.Length == 0) - { - return messageBuilder; - } - - return () => - { - string targetMessage = messageBuilder(); - int argumentIndex = 0; - foreach (Match match in Pattern.Matches(targetMessage)) - { - int notUsed; - if (!int.TryParse(match.Value.Substring(1, match.Value.Length -2), out notUsed)) - { - targetMessage = ReplaceFirst(targetMessage, match.Value, - "{" + argumentIndex++ + "}"); - } - } - try - { - return string.Format(CultureInfo.InvariantCulture, targetMessage, formatParameters); - } - catch (FormatException ex) - { - throw new FormatException("The input string '" + targetMessage + "' could not be formatted using string.Format", ex); - } - }; - } - - private static string ReplaceFirst(string text, string search, string replace) - { - int pos = text.IndexOf(search, StringComparison.Ordinal); - if (pos < 0) - { - return text; - } - return text.Substring(0, pos) + replace + text.Substring(pos + search.Length); - } - } - - internal static class TypeExtensions - { - internal static MethodInfo GetMethodPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, new Type[]{}); -#else - return type.GetMethod(name); -#endif - } - - internal static MethodInfo GetMethodPortable(this Type type, string name, params Type[] types) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, types); -#else - return type.GetMethod(name, types); -#endif - } - - internal static PropertyInfo GetPropertyPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeProperty(name); -#else - return type.GetProperty(name); -#endif - } - - internal static IEnumerable GetFieldsPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeFields(); -#else - return type.GetFields(); -#endif - } - - internal static Type GetBaseTypePortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().BaseType; -#else - return type.BaseType; -#endif - } - -#if LIBLOG_PORTABLE - internal static MethodInfo GetGetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.GetMethod; - } - - internal static MethodInfo GetSetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.SetMethod; - } -#endif - -#if !LIBLOG_PORTABLE - internal static object CreateDelegate(this MethodInfo methodInfo, Type delegateType) - { - return Delegate.CreateDelegate(delegateType, methodInfo); - } -#endif - - internal static Assembly GetAssemblyPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().Assembly; -#else - return type.Assembly; -#endif - } - } - - internal class DisposableAction : IDisposable - { - private readonly Action _onDispose; - - public DisposableAction(Action onDispose = null) - { - _onDispose = onDispose; - } - - public void Dispose() - { - if(_onDispose != null) - { - _onDispose(); - } - } - } -} diff --git a/Src/Solid-TradeService/6.DIP/Logger/DealServiceLogger.cs b/Src/Solid-TradeService/6.DIP/Logger/DealServiceLogger.cs deleted file mode 100644 index f0fd77c..0000000 --- a/Src/Solid-TradeService/6.DIP/Logger/DealServiceLogger.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System.Linq; -using TradeApp.Logging; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealServiceLogger : IDealReader, IDealWriter - { - private readonly IDealReader _reader; - private readonly IDealWriter _writer; - private static readonly ILog _logger = LogProvider.For(); - - public DealServiceLogger(IDealReader reader, IDealWriter writer) - { - _reader = reader; - _writer = writer; - } - - public virtual void Saving(Maybe deal) - { - if(deal.Any()) - _logger.Info($"Saving : {deal}."); - else - _logger.Warn($" Try Saving : {deal}."); - - } - - public virtual void Saved(Maybe deal) - { - if (deal.Any()) - _logger.Info($"Saved : {deal}."); - else - _logger.Warn($" Try Saved : {deal}."); - } - - public virtual void Loading(string id) - { - _logger.Info($"Loading deal {id}."); - } - - public virtual void DidNotFind(string id) - { - _logger.Warn($"No deal {id} found."); - } - - public virtual void Loaded(Deal deal) - { - _logger.Info($"Returning deal {deal.Id}."); - } - - public Maybe Load(string id) - { - Loading(id); - var deal = _reader.Load(id); - if(deal.Any()) - Loaded(deal.Single()); - else - { - DidNotFind(id); - } - return deal; - } - - public void Save(Maybe deal) - { - Saving(deal); - _writer.Save(deal); - Saved(deal); - } - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/6.DIP/Maybe.cs b/Src/Solid-TradeService/6.DIP/Maybe.cs deleted file mode 100644 index c7b4c69..0000000 --- a/Src/Solid-TradeService/6.DIP/Maybe.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -namespace TradeApp -{ - public class Maybe : IEnumerable - { - - private readonly IEnumerable _values; - - public Maybe() - { - _values = new T[0]; - } - - public Maybe(T value) - { - if (value == null) throw new ArgumentNullException(nameof(value)); - _values = new[] {value}; - } - - public override string ToString() - { - if (_values.Any()) - return _values.Single().ToString(); - - return typeof(T).Name + " Is Empty"; - } - - public IEnumerator GetEnumerator() - { - return _values.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} diff --git a/Src/Solid-TradeService/6.DIP/Models/Deal.cs b/Src/Solid-TradeService/6.DIP/Models/Deal.cs deleted file mode 100644 index da47454..0000000 --- a/Src/Solid-TradeService/6.DIP/Models/Deal.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -namespace TradeApp.Models -{ - public class Deal - { - private Deal(string id, double price, int quantity, string symbol, DateTime time) - { - Id = id; - Price = price; - Time = time; - Quantity = quantity; - Symbol = symbol; - } - - public static Deal Empty => new Deal("Empty", 0, 0, "Unset", DateTime.MinValue); - - public string Id { get; } - public double Price { get; } - public DateTime Time { get; } - public int Quantity { get; } - - public string Symbol { get; } - - public OrderDirection Direction - { - get { - return Quantity >= 0 ? OrderDirection.Buy : OrderDirection.Sell; - } - } - - public Deal With(string id = null, double? price = null, int? quantity = null, string symbol = null, DateTime? time = null) - { - return new Deal( - id ?? Id, - price ?? Price, - quantity ?? Quantity, - symbol ?? Symbol, - time ?? Time - ); - - } - - public override string ToString() - { - return $"OrderId: {Id} {Direction} order for {Quantity} unit{(Quantity == 1 ? "" : "s")} of {Symbol}"; - } - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/6.DIP/Models/OrderDirection.cs b/Src/Solid-TradeService/6.DIP/Models/OrderDirection.cs deleted file mode 100644 index c0df608..0000000 --- a/Src/Solid-TradeService/6.DIP/Models/OrderDirection.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace TradeApp.Models -{ - public enum OrderDirection - { - Buy, - Sell - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/6.DIP/Program.cs b/Src/Solid-TradeService/6.DIP/Program.cs deleted file mode 100644 index 4196d6a..0000000 --- a/Src/Solid-TradeService/6.DIP/Program.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Linq; -using TradeApp.App_Packages.LibLog._4._2; -using TradeApp.Models; - -namespace TradeApp -{ - class Program - { - static void Main(string[] args) - { - string username = Environment.UserName; - - Logging.LogProvider.SetCurrentLogProvider(new ColoredConsoleLogProvider()); - - var serializer = new DealSerializer(); - var dealStorage = new FileDealStorage(username,serializer); - var dealCache = new DealCaching(dealStorage,dealStorage); - var dealLogger = new DealServiceLogger(dealCache,dealCache); - - var dealService = new DealService(dealLogger,dealLogger); - - var id = Guid.NewGuid().ToString(); - var deal = Deal.Empty.With( - id, - 500.00, - 10, - "MSFT", - DateTime.Now - ); - - dealService.Save(new Maybe(deal)); - - - Console.WriteLine(); - Console.WriteLine(); - - var vincentDeal = dealService.Load(id).DefaultIfEmpty(Deal.Empty).Single(); - Console.WriteLine(vincentDeal); - - - var unknownDeal = dealService.Load("Fizz"); - - dealService.Save(unknownDeal); - - Console.ReadLine(); - } - } -} diff --git a/Src/Solid-TradeService/6.DIP/Properties/AssemblyInfo.cs b/Src/Solid-TradeService/6.DIP/Properties/AssemblyInfo.cs deleted file mode 100644 index b681b7c..0000000 --- a/Src/Solid-TradeService/6.DIP/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -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("TradeApp")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TradeApp")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[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("bba07b19-254a-4ef0-bcc5-f8954c963537")] - -// 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")] diff --git a/Src/Solid-TradeService/6.DIP/Readme.md b/Src/Solid-TradeService/6.DIP/Readme.md deleted file mode 100644 index d725208..0000000 --- a/Src/Solid-TradeService/6.DIP/Readme.md +++ /dev/null @@ -1,5 +0,0 @@ -# Step 4 : Dependency Inversion - -- Create IDealWriter - - add Save method - - implement this interface everywhere and remove other Save from interfaces diff --git a/Src/Solid-TradeService/6.DIP/Serializer/DealSerializer.cs b/Src/Solid-TradeService/6.DIP/Serializer/DealSerializer.cs deleted file mode 100644 index ebc204f..0000000 --- a/Src/Solid-TradeService/6.DIP/Serializer/DealSerializer.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using Newtonsoft.Json; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealSerializer : IDealSerializer - { - public string SerializeDeal(Deal deal) - { - return JsonConvert.SerializeObject(deal); - } - - public Maybe DeserializeDeal(string serializedDeal) - { - try - { - return new Maybe(JsonConvert.DeserializeObject(serializedDeal)); - } - catch (Exception) - { - return new Maybe(); - } - } - } -} diff --git a/Src/Solid-TradeService/6.DIP/Serializer/IDealSerializer.cs b/Src/Solid-TradeService/6.DIP/Serializer/IDealSerializer.cs deleted file mode 100644 index ecf36b6..0000000 --- a/Src/Solid-TradeService/6.DIP/Serializer/IDealSerializer.cs +++ /dev/null @@ -1,10 +0,0 @@ -using TradeApp.Models; - -namespace TradeApp -{ - public interface IDealSerializer - { - string SerializeDeal(Deal deal); - Maybe DeserializeDeal(string serializedDeal); - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/6.DIP/Storage/FileDealStorage.cs b/Src/Solid-TradeService/6.DIP/Storage/FileDealStorage.cs deleted file mode 100644 index 7eae277..0000000 --- a/Src/Solid-TradeService/6.DIP/Storage/FileDealStorage.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using TradeApp.Models; - -namespace TradeApp -{ - public class FileDealStorage : IFileLocator, IDealReader, IDealWriter - { - private readonly string _directory; - private readonly IDealSerializer _serializer; - - public FileDealStorage(string directory, IDealSerializer serializer) - { - _directory = directory; - _serializer = serializer; - } - - public void Save(string id, string serializedDeal) - { - var path = GetFileName(id).FullName; - File.WriteAllText(path, serializedDeal); - } - - public Maybe Load(string id) - { - try - { - var path = GetFileName(id).FullName; - var text = File.ReadAllText(path); - return new Maybe(text); - } - catch (Exception) - { - return new Maybe(); - } - } - - public FileInfo GetFileName(string id) - { - return new FileInfo(Path.Combine(_directory, id + ".json")); - } - - Maybe IDealReader.Load(string id) - { - try - { - var path = GetFileName(id).FullName; - var text = File.ReadAllText(path); - return _serializer.DeserializeDeal(text); - } - catch (Exception) - { - return new Maybe(); - } - } - - public void Save(Maybe deal) - { - if (deal.Any()) - { - var value = deal.Single(); - var path = GetFileName(value.Id).FullName; - var serializedDeal = _serializer.SerializeDeal(value); - File.WriteAllText(path, serializedDeal); - } - } - } -} diff --git a/Src/Solid-TradeService/6.DIP/Storage/IDealStorage.cs b/Src/Solid-TradeService/6.DIP/Storage/IDealStorage.cs deleted file mode 100644 index b34c269..0000000 --- a/Src/Solid-TradeService/6.DIP/Storage/IDealStorage.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace TradeApp -{ - public interface IDealStorage - { - void Save(string id, string serializedDeal); - Maybe Load(string id); - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/6.DIP/Storage/IFileLocator.cs b/Src/Solid-TradeService/6.DIP/Storage/IFileLocator.cs deleted file mode 100644 index f28cc37..0000000 --- a/Src/Solid-TradeService/6.DIP/Storage/IFileLocator.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.IO; - -namespace TradeApp -{ - public interface IFileLocator - { - FileInfo GetFileName(string id); - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/6.DIP/Storage/SQLDealStorage.cs b/Src/Solid-TradeService/6.DIP/Storage/SQLDealStorage.cs deleted file mode 100644 index 0d76897..0000000 --- a/Src/Solid-TradeService/6.DIP/Storage/SQLDealStorage.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Data.SqlClient; -using System.IO; -using System.Linq; -using Dapper; - -namespace TradeApp -{ - public class SQLDealStorage : IDealStorage - { - private readonly string _connectionString; - - public SQLDealStorage(string connectionString) - { - _connectionString = connectionString; - } - - public Maybe Load(string id) - { - - using (SqlConnection connection = new SqlConnection(_connectionString)) - { - connection.Open(); - var result = connection.Query("select Value from Deals where Id = @Id", new { Id = id }).ToArray(); - if(result.Any()) - return new Maybe(result.First()); - - return new Maybe(); - } - } - - public void Save(string id, string serializedDeal) - { - using (SqlConnection connection = new SqlConnection(_connectionString)) - { - connection.Open(); - connection.Execute(@"delete from Deals where Id = @Id", new { Id = id }); - connection.Execute(@"insert Deals(Id, Value) values (@Id, @Value)", - new {Id = id, Value = serializedDeal}); - } - } - } -} diff --git a/Src/Solid-TradeService/6.DIP/TradeApp.csproj b/Src/Solid-TradeService/6.DIP/TradeApp.csproj deleted file mode 100644 index bf515d9..0000000 --- a/Src/Solid-TradeService/6.DIP/TradeApp.csproj +++ /dev/null @@ -1,134 +0,0 @@ - - - - - Debug - AnyCPU - {EEF6D9D4-7516-4C94-B5F7-D6E50427E214} - Exe - Properties - TradeApp - TradeApp - v4.6 - 512 - true - 1 - - - AnyCPU - true - full - false - bin\Debug\ - TRACE;DEBUG - prompt - 4 - False - False - True - False - False - False - True - True - True - True - True - True - True - True - False - True - False - True - False - False - False - True - True - False - True - True - True - False - False - - - - - - - - True - False - False - True - Full - %28none%29 - 3 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Dapper.1.42\lib\net45\Dapper.dll - - - ..\..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - True - - - - ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/6.DIP/packages.config b/Src/Solid-TradeService/6.DIP/packages.config deleted file mode 100644 index 88af6e8..0000000 --- a/Src/Solid-TradeService/6.DIP/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/7.IOC/App.config b/Src/Solid-TradeService/7.IOC/App.config deleted file mode 100644 index 8324aa6..0000000 --- a/Src/Solid-TradeService/7.IOC/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/7.IOC/Caching/DealCaching.cs b/Src/Solid-TradeService/7.IOC/Caching/DealCaching.cs deleted file mode 100644 index c059601..0000000 --- a/Src/Solid-TradeService/7.IOC/Caching/DealCaching.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Immutable; -using System.Linq; -using Functional.Maybe; -using TradeApp.Models; - -namespace TradeApp -{ - public class Caching : IReadWrite where T : IIdentifiable - { - private readonly IReadWrite _decoretee; - private ImmutableDictionary> _cache; - - public Caching(IReadWrite decoretee) - { - _decoretee = decoretee; - - _cache = ImmutableDictionary>.Empty; - } - - public void Save(Maybe entity) - { - _decoretee.Save(entity); - if(entity.HasValue) - ImmutableInterlocked.AddOrUpdate(ref _cache, entity.Value.Id, entity, (i, d) => entity); - - } - - public Maybe Load(string id) - { - return ImmutableInterlocked.GetOrAdd(ref _cache, id, i => _decoretee.Load(i)); - } - } -} diff --git a/Src/Solid-TradeService/7.IOC/DealService.cs b/Src/Solid-TradeService/7.IOC/DealService.cs deleted file mode 100644 index 5672b21..0000000 --- a/Src/Solid-TradeService/7.IOC/DealService.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using Functional.Maybe; -using TradeApp.Models; - -namespace TradeApp -{ - public class DealService - { - private readonly IReadWrite _dealReadWrite; - - public DealService(IReadWrite dealReadWrite) - { - if (dealReadWrite == null) { throw new ArgumentNullException(nameof(dealReadWrite)); } - - _dealReadWrite = dealReadWrite; - } - - public void Save(Maybe deal) - { - _dealReadWrite.Save(deal); - } - - public Maybe Load(string id) - { - return _dealReadWrite.Load(id); - } - } -} diff --git a/Src/Solid-TradeService/7.IOC/DealServiceDiagram.cd b/Src/Solid-TradeService/7.IOC/DealServiceDiagram.cd deleted file mode 100644 index 4007499..0000000 --- a/Src/Solid-TradeService/7.IOC/DealServiceDiagram.cd +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - AAAIgIAEAAAAAAAAAQAAAAAAAAAAIAAAAAAAAgAAAAA= - DealService.cs - - - - - - - - - - - - AAAAAAAAAIAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAA= - DealCaching.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAABA= - DealSerializer.cs - - - - - - AAAAAAAAAIEAAAAAAAAIAICAIAAAAAAAAAAAAAAAAAA= - DealServiceLogger.cs - - - - - - AAAAAAAAAEAAAAAAAAAABAAAQAAAAAAAAAAAAAAAAAA= - DealStorage.cs - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/7.IOC/Log/ColoredConsoleLogProvider.cs b/Src/Solid-TradeService/7.IOC/Log/ColoredConsoleLogProvider.cs deleted file mode 100644 index 6853892..0000000 --- a/Src/Solid-TradeService/7.IOC/Log/ColoredConsoleLogProvider.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using TradeApp.Logging; - -namespace TradeApp.App_Packages.LibLog._4._2 -{ - public class ColoredConsoleLogProvider : ILogProvider - { - private static readonly Dictionary Colors = new Dictionary - { - {LogLevel.Fatal, ConsoleColor.Red}, - {LogLevel.Error, ConsoleColor.Yellow}, - {LogLevel.Warn, ConsoleColor.Magenta}, - {LogLevel.Info, ConsoleColor.White}, - {LogLevel.Debug, ConsoleColor.Gray}, - {LogLevel.Trace, ConsoleColor.DarkGray}, - }; - - public Logger GetLogger(string name) - { - return (logLevel, messageFunc, exception, formatParameters) => - { - if (messageFunc == null) - { - return true; // All log levels are enabled - } - - ConsoleColor consoleColor; - if (Colors.TryGetValue(logLevel, out consoleColor)) - { - var originalForground = Console.ForegroundColor; - try - { - Console.ForegroundColor = consoleColor; - WriteMessage(logLevel, name, messageFunc, formatParameters, exception); - } - finally - { - Console.ForegroundColor = originalForground; - } - } - else - { - WriteMessage(logLevel, name, messageFunc, formatParameters, exception); - } - - return true; - }; - } - - private static void WriteMessage( - LogLevel logLevel, - string name, - Func messageFunc, - object[] formatParameters, - Exception exception) - { - var message = string.Format(CultureInfo.InvariantCulture, messageFunc(), formatParameters); - if (exception != null) - { - message = message + "|" + exception; - } - Console.WriteLine("{0} | {1} | {2} | {3}", DateTime.UtcNow, logLevel, name, message); - } - - public IDisposable OpenNestedContext(string message) - { - return NullDisposable.Instance; - } - - public IDisposable OpenMappedContext(string key, string value) - { - return NullDisposable.Instance; - } - - private class NullDisposable : IDisposable - { - internal static readonly IDisposable Instance = new NullDisposable(); - - public void Dispose() - { } - } - } -} diff --git a/Src/Solid-TradeService/7.IOC/Log/LibLog.cs b/Src/Solid-TradeService/7.IOC/Log/LibLog.cs deleted file mode 100644 index f761084..0000000 --- a/Src/Solid-TradeService/7.IOC/Log/LibLog.cs +++ /dev/null @@ -1,1998 +0,0 @@ -//=============================================================================== -// LibLog -// -// https://github.com/damianh/LibLog -//=============================================================================== -// Copyright © 2011-2015 Damian Hickey. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//=============================================================================== - -// ReSharper disable PossibleNullReferenceException - -// Define LIBLOG_PORTABLE conditional compilation symbol for PCL compatibility -// -// Define LIBLOG_PUBLIC to enable ability to GET a logger (LogProvider.For<>() etc) from outside this library. NOTE: -// this can have unintended consequences of consumers of your library using your library to resolve a logger. If the -// reason is because you want to open this functionality to other projects within your solution, -// consider [InternalVisibleTo] instead. -// -// Define LIBLOG_PROVIDERS_ONLY if your library provides its own logging API and you just want to use the -// LibLog providers internally to provide built in support for popular logging frameworks. - -#pragma warning disable 1591 - -// If you copied this file manually, you need to change all "YourRootNameSpace" so not to clash with other libraries -// that use LibLog -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog -#else -namespace TradeApp.Logging -#endif -{ - using System.Collections.Generic; -#if LIBLOG_PROVIDERS_ONLY - using TradeApp.LibLog.LogProviders; -#else - using TradeApp.Logging.LogProviders; -#endif - using System; -#if !LIBLOG_PROVIDERS_ONLY - using System.Diagnostics; -#if !LIBLOG_PORTABLE - using System.Runtime.CompilerServices; -#endif -#endif - -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - delegate bool Logger(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters); - -#if !LIBLOG_PROVIDERS_ONLY - /// - /// Simple interface that represent a logger. - /// -#if LIBLOG_PUBLIC - public -#else - internal -#endif - interface ILog - { - /// - /// Log a message the specified log level. - /// - /// The log level. - /// The message function. - /// An optional exception. - /// Optional format parameters for the message generated by the messagefunc. - /// true if the message was logged. Otherwise false. - /// - /// Note to implementers: the message func should not be called if the loglevel is not enabled - /// so as not to incur performance penalties. - /// - /// To check IsEnabled call Log with only LogLevel and check the return value, no event will be written. - /// - bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters ); - } -#endif - - /// - /// The log level. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - enum LogLevel - { - Trace, - Debug, - Info, - Warn, - Error, - Fatal - } - -#if !LIBLOG_PROVIDERS_ONLY -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static partial class LogExtensions - { - public static bool IsDebugEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Debug, null); - } - - public static bool IsErrorEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Error, null); - } - - public static bool IsFatalEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Fatal, null); - } - - public static bool IsInfoEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Info, null); - } - - public static bool IsTraceEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Trace, null); - } - - public static bool IsWarnEnabled(this ILog logger) - { - GuardAgainstNullLogger(logger); - return logger.Log(LogLevel.Warn, null); - } - - public static void Debug(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Debug, messageFunc); - } - - public static void Debug(this ILog logger, string message) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc()); - } - } - - public static void DebugFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsDebugEnabled()) - { - logger.LogFormat(LogLevel.Debug, message, args); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception); - } - } - - public static void DebugException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsDebugEnabled()) - { - logger.Log(LogLevel.Debug, message.AsFunc(), exception, formatParams); - } - } - - public static void Error(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Error, messageFunc); - } - - public static void Error(this ILog logger, string message) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc()); - } - } - - public static void ErrorFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsErrorEnabled()) - { - logger.LogFormat(LogLevel.Error, message, args); - } - } - - public static void ErrorException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsErrorEnabled()) - { - logger.Log(LogLevel.Error, message.AsFunc(), exception, formatParams); - } - } - - public static void Fatal(this ILog logger, Func messageFunc) - { - logger.Log(LogLevel.Fatal, messageFunc); - } - - public static void Fatal(this ILog logger, string message) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc()); - } - } - - public static void FatalFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsFatalEnabled()) - { - logger.LogFormat(LogLevel.Fatal, message, args); - } - } - - public static void FatalException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsFatalEnabled()) - { - logger.Log(LogLevel.Fatal, message.AsFunc(), exception, formatParams); - } - } - - public static void Info(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Info, messageFunc); - } - - public static void Info(this ILog logger, string message) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc()); - } - } - - public static void InfoFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsInfoEnabled()) - { - logger.LogFormat(LogLevel.Info, message, args); - } - } - - public static void InfoException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsInfoEnabled()) - { - logger.Log(LogLevel.Info, message.AsFunc(), exception, formatParams); - } - } - - public static void Trace(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Trace, messageFunc); - } - - public static void Trace(this ILog logger, string message) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc()); - } - } - - public static void TraceFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsTraceEnabled()) - { - logger.LogFormat(LogLevel.Trace, message, args); - } - } - - public static void TraceException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsTraceEnabled()) - { - logger.Log(LogLevel.Trace, message.AsFunc(), exception, formatParams); - } - } - - public static void Warn(this ILog logger, Func messageFunc) - { - GuardAgainstNullLogger(logger); - logger.Log(LogLevel.Warn, messageFunc); - } - - public static void Warn(this ILog logger, string message) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc()); - } - } - - public static void WarnFormat(this ILog logger, string message, params object[] args) - { - if (logger.IsWarnEnabled()) - { - logger.LogFormat(LogLevel.Warn, message, args); - } - } - - public static void WarnException(this ILog logger, string message, Exception exception, params object[] formatParams) - { - if (logger.IsWarnEnabled()) - { - logger.Log(LogLevel.Warn, message.AsFunc(), exception, formatParams); - } - } - - // ReSharper disable once UnusedParameter.Local - private static void GuardAgainstNullLogger(ILog logger) - { - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - } - - private static void LogFormat(this ILog logger, LogLevel logLevel, string message, params object[] args) - { - logger.Log(logLevel, message.AsFunc(), null, args); - } - - // Avoid the closure allocation, see https://gist.github.com/AArnott/d285feef75c18f6ecd2b - private static Func AsFunc(this T value) where T : class - { - return value.Return; - } - - private static T Return(this T value) - { - return value; - } - } -#endif - - /// - /// Represents a way to get a - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - interface ILogProvider - { - /// - /// Gets the specified named logger. - /// - /// Name of the logger. - /// The logger reference. - Logger GetLogger(string name); - - /// - /// Opens a nested diagnostics context. Not supported in EntLib logging. - /// - /// The message to add to the diagnostics context. - /// A disposable that when disposed removes the message from the context. - IDisposable OpenNestedContext(string message); - - /// - /// Opens a mapped diagnostics context. Not supported in EntLib logging. - /// - /// A key. - /// A value. - /// A disposable that when disposed removes the map from the context. - IDisposable OpenMappedContext(string key, string value); - } - - /// - /// Provides a mechanism to create instances of objects. - /// -#if LIBLOG_PROVIDERS_ONLY - internal -#else - public -#endif - static class LogProvider - { -#if !LIBLOG_PROVIDERS_ONLY - /// - /// The disable logging environment variable. If the environment variable is set to 'true', then logging - /// will be disabled. - /// - public const string DisableLoggingEnvironmentVariable = "TradeApp_LIBLOG_DISABLE"; - private const string NullLogProvider = "Current Log Provider is not set. Call SetCurrentLogProvider " + - "with a non-null value first."; - private static dynamic s_currentLogProvider; - private static Action s_onCurrentLogProviderSet; - - static LogProvider() - { - IsDisabled = false; - } - - /// - /// Sets the current log provider. - /// - /// The log provider. - public static void SetCurrentLogProvider(ILogProvider logProvider) - { - s_currentLogProvider = logProvider; - - RaiseOnCurrentLogProviderSet(); - } - - /// - /// Gets or sets a value indicating whether this is logging is disabled. - /// - /// - /// true if logging is disabled; otherwise, false. - /// - public static bool IsDisabled { get; set; } - - /// - /// Sets an action that is invoked when a consumer of your library has called SetCurrentLogProvider. It is - /// important that hook into this if you are using child libraries (especially ilmerged ones) that are using - /// LibLog (or other logging abstraction) so you adapt and delegate to them. - /// - /// - internal static Action OnCurrentLogProviderSet - { - set - { - s_onCurrentLogProviderSet = value; - RaiseOnCurrentLogProviderSet(); - } - } - - internal static ILogProvider CurrentLogProvider - { - get - { - return s_currentLogProvider; - } - } - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog For() - { - return GetLogger(typeof(T)); - } - -#if !LIBLOG_PORTABLE - /// - /// Gets a logger for the current class. - /// - /// An instance of - [MethodImpl(MethodImplOptions.NoInlining)] -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetCurrentClassLogger() - { - var stackFrame = new StackFrame(1, false); - return GetLogger(stackFrame.GetMethod().DeclaringType); - } -#endif - - /// - /// Gets a logger for the specified type. - /// - /// The type whose name will be used for the logger. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(Type type) - { - return GetLogger(type.FullName); - } - - /// - /// Gets a logger with the specified name. - /// - /// The name. - /// An instance of -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static ILog GetLogger(string name) - { - ILogProvider logProvider = CurrentLogProvider ?? ResolveLogProvider(); - return logProvider == null - ? NoOpLogger.Instance - : (ILog)new LoggerExecutionWrapper(logProvider.GetLogger(name), () => IsDisabled); - } - - /// - /// Opens a nested diagnostics context. - /// - /// A message. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenNestedContext(string message) - { - if(CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenNestedContext(message); - } - - /// - /// Opens a mapped diagnostics context. - /// - /// A key. - /// A value. - /// An that closes context when disposed. -#if LIBLOG_PUBLIC - public -#else - internal -#endif - static IDisposable OpenMappedContext(string key, string value) - { - if (CurrentLogProvider == null) - { - throw new InvalidOperationException(NullLogProvider); - } - return CurrentLogProvider.OpenMappedContext(key, value); - } -#endif - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate bool IsLoggerAvailable(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - delegate ILogProvider CreateLogProvider(); - -#if LIBLOG_PROVIDERS_ONLY - private -#else - internal -#endif - static readonly List> LogProviderResolvers = - new List> - { - new Tuple(SerilogLogProvider.IsLoggerAvailable, () => new SerilogLogProvider()), - new Tuple(NLogLogProvider.IsLoggerAvailable, () => new NLogLogProvider()), - new Tuple(Log4NetLogProvider.IsLoggerAvailable, () => new Log4NetLogProvider()), - new Tuple(EntLibLogProvider.IsLoggerAvailable, () => new EntLibLogProvider()), - new Tuple(LoupeLogProvider.IsLoggerAvailable, () => new LoupeLogProvider()), - }; - -#if !LIBLOG_PROVIDERS_ONLY - private static void RaiseOnCurrentLogProviderSet() - { - if (s_onCurrentLogProviderSet != null) - { - s_onCurrentLogProviderSet(s_currentLogProvider); - } - } -#endif - - internal static ILogProvider ResolveLogProvider() - { - try - { - foreach (var providerResolver in LogProviderResolvers) - { - if (providerResolver.Item1()) - { - return providerResolver.Item2(); - } - } - } - catch (Exception ex) - { -#if LIBLOG_PORTABLE - Debug.WriteLine( -#else - Console.WriteLine( -#endif - "Exception occurred resolving a log provider. Logging for this assembly {0} is disabled. {1}", - typeof(LogProvider).GetAssemblyPortable().FullName, - ex); - } - return null; - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class NoOpLogger : ILog - { - internal static readonly NoOpLogger Instance = new NoOpLogger(); - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - return false; - } - } -#endif - } - -#if !LIBLOG_PROVIDERS_ONLY - internal class LoggerExecutionWrapper : ILog - { - private readonly Logger _logger; - private readonly Func _getIsDisabled; - internal const string FailedToGenerateLogMessage = "Failed to generate log message"; - - internal LoggerExecutionWrapper(Logger logger, Func getIsDisabled = null) - { - _logger = logger; - _getIsDisabled = getIsDisabled ?? (() => false); - } - - internal Logger WrappedLogger - { - get { return _logger; } - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters) - { - if (_getIsDisabled()) - { - return false; - } -#if !LIBLOG_PORTABLE - var envVar = Environment.GetEnvironmentVariable(LogProvider.DisableLoggingEnvironmentVariable); - - if (envVar != null && envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) - { - return false; - } -#endif - - if (messageFunc == null) - { - return _logger(logLevel, null); - } - - Func wrappedMessageFunc = () => - { - try - { - return messageFunc(); - } - catch (Exception ex) - { - Log(LogLevel.Error, () => FailedToGenerateLogMessage, ex); - } - return null; - }; - return _logger(logLevel, wrappedMessageFunc, exception, formatParameters); - } - } -#endif -} - -#if LIBLOG_PROVIDERS_ONLY -namespace TradeApp.LibLog.LogProviders -#else -namespace TradeApp.Logging.LogProviders -#endif -{ - using System; - using System.Collections.Generic; -#if !LIBLOG_PORTABLE - using System.Diagnostics; -#endif - using System.Globalization; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; -#if !LIBLOG_PORTABLE - using System.Text; -#endif - using System.Text.RegularExpressions; - - internal abstract class LogProviderBase : ILogProvider - { - protected delegate IDisposable OpenNdc(string message); - protected delegate IDisposable OpenMdc(string key, string value); - - private readonly Lazy _lazyOpenNdcMethod; - private readonly Lazy _lazyOpenMdcMethod; - private static readonly IDisposable NoopDisposableInstance = new DisposableAction(); - - protected LogProviderBase() - { - _lazyOpenNdcMethod - = new Lazy(GetOpenNdcMethod); - _lazyOpenMdcMethod - = new Lazy(GetOpenMdcMethod); - } - - public abstract Logger GetLogger(string name); - - public IDisposable OpenNestedContext(string message) - { - return _lazyOpenNdcMethod.Value(message); - } - - public IDisposable OpenMappedContext(string key, string value) - { - return _lazyOpenMdcMethod.Value(key, value); - } - - protected virtual OpenNdc GetOpenNdcMethod() - { - return _ => NoopDisposableInstance; - } - - protected virtual OpenMdc GetOpenMdcMethod() - { - return (_, __) => NoopDisposableInstance; - } - } - - internal class NLogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public NLogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("NLog.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new NLogLogger(_getLoggerByNameDelegate(name)).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("NLog.NestedDiagnosticsContext, NLog"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("NLog.MappedDiagnosticsContext, NLog"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("NLog.LogManager, NLog"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class NLogLogger - { - private readonly dynamic _logger; - - internal NLogLogger(dynamic logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - if(exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.Debug(messageFunc()); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.Info(messageFunc()); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.Warn(messageFunc()); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.Error(messageFunc()); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.Fatal(messageFunc()); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.Trace(messageFunc()); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - switch (logLevel) - { - case LogLevel.Debug: - if (_logger.IsDebugEnabled) - { - _logger.DebugException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Info: - if (_logger.IsInfoEnabled) - { - _logger.InfoException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Warn: - if (_logger.IsWarnEnabled) - { - _logger.WarnException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Error: - if (_logger.IsErrorEnabled) - { - _logger.ErrorException(messageFunc(), exception); - return true; - } - break; - case LogLevel.Fatal: - if (_logger.IsFatalEnabled) - { - _logger.FatalException(messageFunc(), exception); - return true; - } - break; - default: - if (_logger.IsTraceEnabled) - { - _logger.TraceException(messageFunc(), exception); - return true; - } - break; - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Debug: - return _logger.IsDebugEnabled; - case LogLevel.Info: - return _logger.IsInfoEnabled; - case LogLevel.Warn: - return _logger.IsWarnEnabled; - case LogLevel.Error: - return _logger.IsErrorEnabled; - case LogLevel.Fatal: - return _logger.IsFatalEnabled; - default: - return _logger.IsTraceEnabled; - } - } - } - } - - internal class Log4NetLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public Log4NetLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("log4net.LogManager not found"); - } - _getLoggerByNameDelegate = GetGetLoggerMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new Log4NetLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - Type ndcContextType = Type.GetType("log4net.NDC, log4net"); - MethodInfo pushMethod = ndcContextType.GetMethodPortable("Push", typeof(string)); - ParameterExpression messageParam = Expression.Parameter(typeof(string), "message"); - MethodCallExpression pushMethodCall = Expression.Call(null, pushMethod, messageParam); - return Expression.Lambda(pushMethodCall, messageParam).Compile(); - } - - protected override OpenMdc GetOpenMdcMethod() - { - Type mdcContextType = Type.GetType("log4net.MDC, log4net"); - - MethodInfo setMethod = mdcContextType.GetMethodPortable("Set", typeof(string), typeof(string)); - MethodInfo removeMethod = mdcContextType.GetMethodPortable("Remove", typeof(string)); - ParameterExpression keyParam = Expression.Parameter(typeof(string), "key"); - ParameterExpression valueParam = Expression.Parameter(typeof(string), "value"); - - MethodCallExpression setMethodCall = Expression.Call(null, setMethod, keyParam, valueParam); - MethodCallExpression removeMethodCall = Expression.Call(null, removeMethod, keyParam); - - Action set = Expression - .Lambda>(setMethodCall, keyParam, valueParam) - .Compile(); - Action remove = Expression - .Lambda>(removeMethodCall, keyParam) - .Compile(); - - return (key, value) => - { - set(key, value); - return new DisposableAction(() => remove(key)); - }; - } - - private static Type GetLogManagerType() - { - return Type.GetType("log4net.LogManager, log4net"); - } - - private static Func GetGetLoggerMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("GetLogger", typeof(string)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - MethodCallExpression methodCall = Expression.Call(null, method, nameParam); - return Expression.Lambda>(methodCall, nameParam).Compile(); - } - - internal class Log4NetLogger - { - private readonly dynamic _logger; - private static Type s_callerStackBoundaryType; - private static readonly object CallerStackBoundaryTypeSync = new object(); - - private readonly object _levelDebug; - private readonly object _levelInfo; - private readonly object _levelWarn; - private readonly object _levelError; - private readonly object _levelFatal; - private readonly Func _isEnabledForDelegate; - private readonly Action _logDelegate; - - internal Log4NetLogger(dynamic logger) - { - _logger = logger.Logger; - - var logEventLevelType = Type.GetType("log4net.Core.Level, log4net"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type log4net.Core.Level was not found."); - } - - var levelFields = logEventLevelType.GetFieldsPortable().ToList(); - _levelDebug = levelFields.First(x => x.Name == "Debug").GetValue(null); - _levelInfo = levelFields.First(x => x.Name == "Info").GetValue(null); - _levelWarn = levelFields.First(x => x.Name == "Warn").GetValue(null); - _levelError = levelFields.First(x => x.Name == "Error").GetValue(null); - _levelFatal = levelFields.First(x => x.Name == "Fatal").GetValue(null); - - // Func isEnabledFor = (logger, level) => { return ((log4net.Core.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("log4net.Core.ILogger, log4net"); - if (loggerType == null) - { - throw new InvalidOperationException("Type log4net.Core.ILogger, was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabledFor", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression callerStackBoundaryDeclaringTypeParam = Expression.Parameter(typeof(Type)); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - _isEnabledForDelegate = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Log = - // (logger, callerStackBoundaryDeclaringType, level, message, exception) => { ((ILogger)logger).Write(callerStackBoundaryDeclaringType, level, message, exception); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Log", - typeof(Type), - logEventLevelType, - typeof(string), - typeof(Exception)); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - var writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - callerStackBoundaryDeclaringTypeParam, - levelCast, - messageParam, - exceptionParam); - _logDelegate = Expression.Lambda>( - writeMethodExp, - instanceParam, - callerStackBoundaryDeclaringTypeParam, - levelParam, - messageParam, - exceptionParam).Compile(); - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsLogLevelEnable(logLevel); - } - - if (!IsLogLevelEnable(logLevel)) - { - return false; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - // determine correct caller - this might change due to jit optimizations with method inlining - if (s_callerStackBoundaryType == null) - { - lock (CallerStackBoundaryTypeSync) - { -#if !LIBLOG_PORTABLE - StackTrace stack = new StackTrace(); - Type thisType = GetType(); - s_callerStackBoundaryType = Type.GetType("LoggerExecutionWrapper"); - for (var i = 1; i < stack.FrameCount; i++) - { - if (!IsInTypeHierarchy(thisType, stack.GetFrame(i).GetMethod().DeclaringType)) - { - s_callerStackBoundaryType = stack.GetFrame(i - 1).GetMethod().DeclaringType; - break; - } - } -#else - s_callerStackBoundaryType = typeof (LoggerExecutionWrapper); -#endif - } - } - - var translatedLevel = TranslateLevel(logLevel); - _logDelegate(_logger, s_callerStackBoundaryType, translatedLevel, messageFunc(), exception); - return true; - } - - private bool IsInTypeHierarchy(Type currentType, Type checkType) - { - while (currentType != null && currentType != typeof(object)) - { - if (currentType == checkType) - { - return true; - } - currentType = currentType.GetBaseTypePortable(); - } - return false; - } - - private bool IsLogLevelEnable(LogLevel logLevel) - { - var level = TranslateLevel(logLevel); - return _isEnabledForDelegate(_logger, level); - } - - private object TranslateLevel(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - case LogLevel.Debug: - return _levelDebug; - case LogLevel.Info: - return _levelInfo; - case LogLevel.Warn: - return _levelWarn; - case LogLevel.Error: - return _levelError; - case LogLevel.Fatal: - return _levelFatal; - default: - throw new ArgumentOutOfRangeException("logLevel", logLevel, null); - } - } - } - } - - internal class EntLibLogProvider : LogProviderBase - { - private const string TypeTemplate = "Microsoft.Practices.EnterpriseLibrary.Logging.{0}, Microsoft.Practices.EnterpriseLibrary.Logging"; - private static bool s_providerIsAvailableOverride = true; - private static readonly Type LogEntryType; - private static readonly Type LoggerType; - private static readonly Type TraceEventTypeType; - private static readonly Action WriteLogEntry; - private static readonly Func ShouldLogEntry; - - static EntLibLogProvider() - { - LogEntryType = Type.GetType(string.Format(TypeTemplate, "LogEntry")); - LoggerType = Type.GetType(string.Format(TypeTemplate, "Logger")); - TraceEventTypeType = TraceEventTypeValues.Type; - if (LogEntryType == null - || TraceEventTypeType == null - || LoggerType == null) - { - return; - } - WriteLogEntry = GetWriteLogEntry(); - ShouldLogEntry = GetShouldLogEntry(); - } - - public EntLibLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Microsoft.Practices.EnterpriseLibrary.Logging.Logger not found"); - } - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new EntLibLogger(name, WriteLogEntry, ShouldLogEntry).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride - && TraceEventTypeType != null - && LogEntryType != null; - } - - private static Action GetWriteLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var messageParameter = Expression.Parameter(typeof(string), "message"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - messageParameter, - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("Write", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - messageParameter, - severityParameter).Compile(); - } - - private static Func GetShouldLogEntry() - { - // new LogEntry(...) - var logNameParameter = Expression.Parameter(typeof(string), "logName"); - var severityParameter = Expression.Parameter(typeof(int), "severity"); - - MemberInitExpression memberInit = GetWriteLogExpression( - Expression.Constant("***dummy***"), - Expression.Convert(severityParameter, TraceEventTypeType), - logNameParameter); - - //Logger.Write(new LogEntry(....)); - MethodInfo writeLogEntryMethod = LoggerType.GetMethodPortable("ShouldLog", LogEntryType); - var writeLogEntryExpression = Expression.Call(writeLogEntryMethod, memberInit); - - return Expression.Lambda>( - writeLogEntryExpression, - logNameParameter, - severityParameter).Compile(); - } - - private static MemberInitExpression GetWriteLogExpression(Expression message, - Expression severityParameter, ParameterExpression logNameParameter) - { - var entryType = LogEntryType; - MemberInitExpression memberInit = Expression.MemberInit(Expression.New(entryType), - Expression.Bind(entryType.GetPropertyPortable("Message"), message), - Expression.Bind(entryType.GetPropertyPortable("Severity"), severityParameter), - Expression.Bind( - entryType.GetPropertyPortable("TimeStamp"), - Expression.Property(null, typeof (DateTime).GetPropertyPortable("UtcNow"))), - Expression.Bind( - entryType.GetPropertyPortable("Categories"), - Expression.ListInit( - Expression.New(typeof (List)), - typeof (List).GetMethodPortable("Add", typeof (string)), - logNameParameter))); - return memberInit; - } - - internal class EntLibLogger - { - private readonly string _loggerName; - private readonly Action _writeLog; - private readonly Func _shouldLog; - - internal EntLibLogger(string loggerName, Action writeLog, Func shouldLog) - { - _loggerName = loggerName; - _writeLog = writeLog; - _shouldLog = shouldLog; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - var severity = MapSeverity(logLevel); - if (messageFunc == null) - { - return _shouldLog(_loggerName, severity); - } - - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - if (exception != null) - { - return LogException(logLevel, messageFunc, exception); - } - _writeLog(_loggerName, messageFunc(), severity); - return true; - } - - public bool LogException(LogLevel logLevel, Func messageFunc, Exception exception) - { - var severity = MapSeverity(logLevel); - var message = messageFunc() + Environment.NewLine + exception; - _writeLog(_loggerName, message, severity); - return true; - } - - private static int MapSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Info: - return TraceEventTypeValues.Information; - default: - return TraceEventTypeValues.Verbose; - } - } - } - } - - internal class SerilogLogProvider : LogProviderBase - { - private readonly Func _getLoggerByNameDelegate; - private static bool s_providerIsAvailableOverride = true; - - public SerilogLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Serilog.Log not found"); - } - _getLoggerByNameDelegate = GetForContextMethodCall(); - } - - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new SerilogLogger(_getLoggerByNameDelegate(name)).Log; - } - - internal static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - protected override OpenNdc GetOpenNdcMethod() - { - return message => GetPushProperty()("NDC", message); - } - - protected override OpenMdc GetOpenMdcMethod() - { - return (key, value) => GetPushProperty()(key, value); - } - - private static Func GetPushProperty() - { - Type ndcContextType = Type.GetType("Serilog.Context.LogContext, Serilog.FullNetFx"); - MethodInfo pushPropertyMethod = ndcContextType.GetMethodPortable( - "PushProperty", - typeof(string), - typeof(object), - typeof(bool)); - ParameterExpression nameParam = Expression.Parameter(typeof(string), "name"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression pushPropertyMethodCall = Expression - .Call(null, pushPropertyMethod, nameParam, valueParam, destructureObjectParam); - var pushProperty = Expression - .Lambda>( - pushPropertyMethodCall, - nameParam, - valueParam, - destructureObjectParam) - .Compile(); - - return (key, value) => pushProperty(key, value, false); - } - - private static Type GetLogManagerType() - { - return Type.GetType("Serilog.Log, Serilog"); - } - - private static Func GetForContextMethodCall() - { - Type logManagerType = GetLogManagerType(); - MethodInfo method = logManagerType.GetMethodPortable("ForContext", typeof(string), typeof(object), typeof(bool)); - ParameterExpression propertyNameParam = Expression.Parameter(typeof(string), "propertyName"); - ParameterExpression valueParam = Expression.Parameter(typeof(object), "value"); - ParameterExpression destructureObjectsParam = Expression.Parameter(typeof(bool), "destructureObjects"); - MethodCallExpression methodCall = Expression.Call(null, method, new Expression[] - { - propertyNameParam, - valueParam, - destructureObjectsParam - }); - var func = Expression.Lambda>( - methodCall, - propertyNameParam, - valueParam, - destructureObjectsParam) - .Compile(); - return name => func("Name", name, false); - } - - internal class SerilogLogger - { - private readonly object _logger; - private static readonly object DebugLevel; - private static readonly object ErrorLevel; - private static readonly object FatalLevel; - private static readonly object InformationLevel; - private static readonly object VerboseLevel; - private static readonly object WarningLevel; - private static readonly Func IsEnabled; - private static readonly Action Write; - private static readonly Action WriteException; - - static SerilogLogger() - { - var logEventLevelType = Type.GetType("Serilog.Events.LogEventLevel, Serilog"); - if (logEventLevelType == null) - { - throw new InvalidOperationException("Type Serilog.Events.LogEventLevel was not found."); - } - DebugLevel = Enum.Parse(logEventLevelType, "Debug", false); - ErrorLevel = Enum.Parse(logEventLevelType, "Error", false); - FatalLevel = Enum.Parse(logEventLevelType, "Fatal", false); - InformationLevel = Enum.Parse(logEventLevelType, "Information", false); - VerboseLevel = Enum.Parse(logEventLevelType, "Verbose", false); - WarningLevel = Enum.Parse(logEventLevelType, "Warning", false); - - // Func isEnabled = (logger, level) => { return ((SeriLog.ILogger)logger).IsEnabled(level); } - var loggerType = Type.GetType("Serilog.ILogger, Serilog"); - if (loggerType == null) - { - throw new InvalidOperationException("Type Serilog.ILogger was not found."); - } - MethodInfo isEnabledMethodInfo = loggerType.GetMethodPortable("IsEnabled", logEventLevelType); - ParameterExpression instanceParam = Expression.Parameter(typeof(object)); - UnaryExpression instanceCast = Expression.Convert(instanceParam, loggerType); - ParameterExpression levelParam = Expression.Parameter(typeof(object)); - UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType); - MethodCallExpression isEnabledMethodCall = Expression.Call(instanceCast, isEnabledMethodInfo, levelCast); - IsEnabled = Expression.Lambda>(isEnabledMethodCall, instanceParam, levelParam).Compile(); - - // Action Write = - // (logger, level, message, params) => { ((SeriLog.ILoggerILogger)logger).Write(level, message, params); } - MethodInfo writeMethodInfo = loggerType.GetMethodPortable("Write", logEventLevelType, typeof(string), typeof(object[])); - ParameterExpression messageParam = Expression.Parameter(typeof(string)); - ParameterExpression propertyValuesParam = Expression.Parameter(typeof(object[])); - MethodCallExpression writeMethodExp = Expression.Call( - instanceCast, - writeMethodInfo, - levelCast, - messageParam, - propertyValuesParam); - var expression = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - messageParam, - propertyValuesParam); - Write = expression.Compile(); - - // Action WriteException = - // (logger, level, exception, message) => { ((ILogger)logger).Write(level, exception, message, new object[]); } - MethodInfo writeExceptionMethodInfo = loggerType.GetMethodPortable("Write", - logEventLevelType, - typeof(Exception), - typeof(string), - typeof(object[])); - ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception)); - writeMethodExp = Expression.Call( - instanceCast, - writeExceptionMethodInfo, - levelCast, - exceptionParam, - messageParam, - propertyValuesParam); - WriteException = Expression.Lambda>( - writeMethodExp, - instanceParam, - levelParam, - exceptionParam, - messageParam, - propertyValuesParam).Compile(); - } - - internal SerilogLogger(object logger) - { - _logger = logger; - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - return IsEnabled(_logger, logLevel); - } - if (exception != null) - { - return LogException(logLevel, messageFunc, exception, formatParameters); - } - - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - Write(_logger, DebugLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - Write(_logger, InformationLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - Write(_logger, WarningLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - Write(_logger, ErrorLevel, messageFunc(), formatParameters); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - Write(_logger, FatalLevel, messageFunc(), formatParameters); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - Write(_logger, VerboseLevel, messageFunc(), formatParameters); - return true; - } - break; - } - return false; - } - - private bool LogException(LogLevel logLevel, Func messageFunc, Exception exception, object[] formatParams) - { - switch (logLevel) - { - case LogLevel.Debug: - if (IsEnabled(_logger, DebugLevel)) - { - WriteException(_logger, DebugLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Info: - if (IsEnabled(_logger, InformationLevel)) - { - WriteException(_logger, InformationLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Warn: - if (IsEnabled(_logger, WarningLevel)) - { - WriteException(_logger, WarningLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Error: - if (IsEnabled(_logger, ErrorLevel)) - { - WriteException(_logger, ErrorLevel, exception, messageFunc(), formatParams); - return true; - } - break; - case LogLevel.Fatal: - if (IsEnabled(_logger, FatalLevel)) - { - WriteException(_logger, FatalLevel, exception, messageFunc(), formatParams); - return true; - } - break; - default: - if (IsEnabled(_logger, VerboseLevel)) - { - WriteException(_logger, VerboseLevel, exception, messageFunc(), formatParams); - return true; - } - break; - } - return false; - } - } - } - - internal class LoupeLogProvider : LogProviderBase - { - /// - /// The form of the Loupe Log.Write method we're using - /// - internal delegate void WriteDelegate( - int severity, - string logSystem, - int skipFrames, - Exception exception, - bool attributeToException, - int writeMode, - string detailsXml, - string category, - string caption, - string description, - params object[] args - ); - - private static bool s_providerIsAvailableOverride = true; - private readonly WriteDelegate _logWriteDelegate; - - public LoupeLogProvider() - { - if (!IsLoggerAvailable()) - { - throw new InvalidOperationException("Gibraltar.Agent.Log (Loupe) not found"); - } - - _logWriteDelegate = GetLogWriteDelegate(); - } - - /// - /// Gets or sets a value indicating whether [provider is available override]. Used in tests. - /// - /// - /// true if [provider is available override]; otherwise, false. - /// - public static bool ProviderIsAvailableOverride - { - get { return s_providerIsAvailableOverride; } - set { s_providerIsAvailableOverride = value; } - } - - public override Logger GetLogger(string name) - { - return new LoupeLogger(name, _logWriteDelegate).Log; - } - - public static bool IsLoggerAvailable() - { - return ProviderIsAvailableOverride && GetLogManagerType() != null; - } - - private static Type GetLogManagerType() - { - return Type.GetType("Gibraltar.Agent.Log, Gibraltar.Agent"); - } - - private static WriteDelegate GetLogWriteDelegate() - { - Type logManagerType = GetLogManagerType(); - Type logMessageSeverityType = Type.GetType("Gibraltar.Agent.LogMessageSeverity, Gibraltar.Agent"); - Type logWriteModeType = Type.GetType("Gibraltar.Agent.LogWriteMode, Gibraltar.Agent"); - - MethodInfo method = logManagerType.GetMethodPortable( - "Write", - logMessageSeverityType, typeof(string), typeof(int), typeof(Exception), typeof(bool), - logWriteModeType, typeof(string), typeof(string), typeof(string), typeof(string), typeof(object[])); - - var callDelegate = (WriteDelegate)method.CreateDelegate(typeof(WriteDelegate)); - return callDelegate; - } - - internal class LoupeLogger - { - private const string LogSystem = "LibLog"; - - private readonly string _category; - private readonly WriteDelegate _logWriteDelegate; - private readonly int _skipLevel; - - internal LoupeLogger(string category, WriteDelegate logWriteDelegate) - { - _category = category; - _logWriteDelegate = logWriteDelegate; -#if DEBUG - _skipLevel = 2; -#else - _skipLevel = 1; -#endif - } - - public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters) - { - if (messageFunc == null) - { - //nothing to log.. - return true; - } - - messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters); - - _logWriteDelegate(ToLogMessageSeverity(logLevel), LogSystem, _skipLevel, exception, true, 0, null, - _category, null, messageFunc.Invoke()); - - return true; - } - - private int ToLogMessageSeverity(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - return TraceEventTypeValues.Verbose; - case LogLevel.Debug: - return TraceEventTypeValues.Verbose; - case LogLevel.Info: - return TraceEventTypeValues.Information; - case LogLevel.Warn: - return TraceEventTypeValues.Warning; - case LogLevel.Error: - return TraceEventTypeValues.Error; - case LogLevel.Fatal: - return TraceEventTypeValues.Critical; - default: - throw new ArgumentOutOfRangeException("logLevel"); - } - } - } - } - - internal static class TraceEventTypeValues - { - internal static readonly Type Type; - internal static readonly int Verbose; - internal static readonly int Information; - internal static readonly int Warning; - internal static readonly int Error; - internal static readonly int Critical; - - static TraceEventTypeValues() - { - var assembly = typeof(Uri).GetAssemblyPortable(); // This is to get to the System.dll assembly in a PCL compatible way. - if (assembly == null) - { - return; - } - Type = assembly.GetType("System.Diagnostics.TraceEventType"); - if (Type == null) return; - Verbose = (int)Enum.Parse(Type, "Verbose", false); - Information = (int)Enum.Parse(Type, "Information", false); - Warning = (int)Enum.Parse(Type, "Warning", false); - Error = (int)Enum.Parse(Type, "Error", false); - Critical = (int)Enum.Parse(Type, "Critical", false); - } - } - - internal static class LogMessageFormatter - { - private static readonly Regex Pattern = new Regex(@"\{@?\w{1,}\}"); - - /// - /// Some logging frameworks support structured logging, such as serilog. This will allow you to add names to structured data in a format string: - /// For example: Log("Log message to {user}", user). This only works with serilog, but as the user of LibLog, you don't know if serilog is actually - /// used. So, this class simulates that. it will replace any text in {curly braces} with an index number. - /// - /// "Log {message} to {user}" would turn into => "Log {0} to {1}". Then the format parameters are handled using regular .net string.Format. - /// - /// The message builder. - /// The format parameters. - /// - public static Func SimulateStructuredLogging(Func messageBuilder, object[] formatParameters) - { - if (formatParameters == null || formatParameters.Length == 0) - { - return messageBuilder; - } - - return () => - { - string targetMessage = messageBuilder(); - int argumentIndex = 0; - foreach (Match match in Pattern.Matches(targetMessage)) - { - int notUsed; - if (!int.TryParse(match.Value.Substring(1, match.Value.Length -2), out notUsed)) - { - targetMessage = ReplaceFirst(targetMessage, match.Value, - "{" + argumentIndex++ + "}"); - } - } - try - { - return string.Format(CultureInfo.InvariantCulture, targetMessage, formatParameters); - } - catch (FormatException ex) - { - throw new FormatException("The input string '" + targetMessage + "' could not be formatted using string.Format", ex); - } - }; - } - - private static string ReplaceFirst(string text, string search, string replace) - { - int pos = text.IndexOf(search, StringComparison.Ordinal); - if (pos < 0) - { - return text; - } - return text.Substring(0, pos) + replace + text.Substring(pos + search.Length); - } - } - - internal static class TypeExtensions - { - internal static MethodInfo GetMethodPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, new Type[]{}); -#else - return type.GetMethod(name); -#endif - } - - internal static MethodInfo GetMethodPortable(this Type type, string name, params Type[] types) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeMethod(name, types); -#else - return type.GetMethod(name, types); -#endif - } - - internal static PropertyInfo GetPropertyPortable(this Type type, string name) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeProperty(name); -#else - return type.GetProperty(name); -#endif - } - - internal static IEnumerable GetFieldsPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetRuntimeFields(); -#else - return type.GetFields(); -#endif - } - - internal static Type GetBaseTypePortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().BaseType; -#else - return type.BaseType; -#endif - } - -#if LIBLOG_PORTABLE - internal static MethodInfo GetGetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.GetMethod; - } - - internal static MethodInfo GetSetMethod(this PropertyInfo propertyInfo) - { - return propertyInfo.SetMethod; - } -#endif - -#if !LIBLOG_PORTABLE - internal static object CreateDelegate(this MethodInfo methodInfo, Type delegateType) - { - return Delegate.CreateDelegate(delegateType, methodInfo); - } -#endif - - internal static Assembly GetAssemblyPortable(this Type type) - { -#if LIBLOG_PORTABLE - return type.GetTypeInfo().Assembly; -#else - return type.Assembly; -#endif - } - } - - internal class DisposableAction : IDisposable - { - private readonly Action _onDispose; - - public DisposableAction(Action onDispose = null) - { - _onDispose = onDispose; - } - - public void Dispose() - { - if(_onDispose != null) - { - _onDispose(); - } - } - } -} diff --git a/Src/Solid-TradeService/7.IOC/Logger/DealServiceLogger.cs b/Src/Solid-TradeService/7.IOC/Logger/DealServiceLogger.cs deleted file mode 100644 index 765efc0..0000000 --- a/Src/Solid-TradeService/7.IOC/Logger/DealServiceLogger.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.ComponentModel; -using System.Linq; -using Functional.Maybe; -using TradeApp.Logging; -using TradeApp.Models; - -namespace TradeApp -{ - public class Logger : IReadWrite where T : IIdentifiable - { - private readonly IReadWrite _decoretee; - - private static readonly ILog _logger = LogProvider.For(); - - public Logger(IReadWrite decoretee) - { - _decoretee = decoretee; - } - - public virtual void Saving(Maybe entity) - { - if(entity.HasValue) - _logger.Info($"Saving : {entity}."); - else - _logger.Warn($" Try Saving : {entity}."); - - } - - public virtual void Saved(Maybe deal) - { - if (deal.HasValue) - _logger.Info($"Saved : {deal}."); - else - _logger.Warn($" Try Saved : {deal}."); - } - - public virtual void Loading(string id) - { - _logger.Info($"Loading deal {id}."); - } - - public virtual void DidNotFind(string id) - { - _logger.Warn($"No deal {id} found."); - } - - public virtual void Loaded(T entity) - { - _logger.Info($"Returning deal {entity.Id}."); - } - - public Maybe Load(string id) - { - Loading(id); - var entity = _decoretee.Load(id); - if(entity.HasValue) - Loaded(entity.Value); - else - { - DidNotFind(id); - } - return entity; - } - - public void Save(Maybe entity) - { - Saving(entity); - _decoretee.Save(entity); - Saved(entity); - } - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/7.IOC/Models/Deal.cs b/Src/Solid-TradeService/7.IOC/Models/Deal.cs deleted file mode 100644 index 15dffd9..0000000 --- a/Src/Solid-TradeService/7.IOC/Models/Deal.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -namespace TradeApp.Models -{ - public class Deal : IIdentifiable - { - private Deal(string id, double price, int quantity, string symbol, DateTime time) - { - Id = id; - Price = price; - Time = time; - Quantity = quantity; - Symbol = symbol; - } - - public static Deal Empty => new Deal("Empty", 0, 0, "Unset", DateTime.MinValue); - - public string Id { get; } - public double Price { get; } - public DateTime Time { get; } - public int Quantity { get; } - - public string Symbol { get; } - - public OrderDirection Direction - { - get { - return Quantity >= 0 ? OrderDirection.Buy : OrderDirection.Sell; - } - } - - public Deal With(string id = null, double? price = null, int? quantity = null, string symbol = null, DateTime? time = null) - { - return new Deal( - id ?? Id, - price ?? Price, - quantity ?? Quantity, - symbol ?? Symbol, - time ?? Time - ); - - } - - public override string ToString() - { - return $"OrderId: {Id} {Direction} order for {Quantity} unit{(Quantity == 1 ? "" : "s")} of {Symbol}"; - } - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/7.IOC/Models/IIdentifiable.cs b/Src/Solid-TradeService/7.IOC/Models/IIdentifiable.cs deleted file mode 100644 index 87b2adc..0000000 --- a/Src/Solid-TradeService/7.IOC/Models/IIdentifiable.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace TradeApp.Models -{ - public interface IIdentifiable - { - string Id { get; } - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/7.IOC/Models/OrderDirection.cs b/Src/Solid-TradeService/7.IOC/Models/OrderDirection.cs deleted file mode 100644 index c0df608..0000000 --- a/Src/Solid-TradeService/7.IOC/Models/OrderDirection.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace TradeApp.Models -{ - public enum OrderDirection - { - Buy, - Sell - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/7.IOC/Program.cs b/Src/Solid-TradeService/7.IOC/Program.cs deleted file mode 100644 index 8ad7ebe..0000000 --- a/Src/Solid-TradeService/7.IOC/Program.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using Functional.Maybe; -using SimpleInjector; -using SimpleInjector.Extensions; -using TradeApp.App_Packages.LibLog._4._2; -using TradeApp.Logging; -using TradeApp.Models; - -namespace TradeApp -{ - static class Program - { - static void Main(string[] args) - { - var dealService = ConfigureRoot(); - - var id = Guid.NewGuid().ToString(); - var deal = Deal.Empty.With( - id, - 500.00, - 10, - "MSFT", - DateTime.Now - ); - - dealService.Save(deal.ToMaybe()); - - - Console.WriteLine(); - Console.WriteLine(); - - var vincentDeal = dealService.Load(id).Or(Deal.Empty); - Console.WriteLine(vincentDeal); - - - var unknownDeal = dealService.Load("Fizz"); - - dealService.Save(unknownDeal); - - Console.ReadLine(); - } - - private static TRoot ConfigureRoot() where TRoot : class - { - LogProvider.SetCurrentLogProvider(new ColoredConsoleLogProvider()); - - var container = new Container(); - - container.Register(Lifestyle.Singleton); - container.Register(typeof(ISerializer), typeof(JsonSerializer),Lifestyle.Singleton); - container.Register(typeof(IFileLocator),typeof(FileStorage),Lifestyle.Singleton); - container.Register(typeof(IReadWrite),typeof(FileStorage),Lifestyle.Singleton); - - container.RegisterDecorator(typeof(IReadWrite), typeof(Caching)); - container.RegisterDecorator(typeof(IReadWrite), typeof(Logger)); - - container.Register(); - return container.GetInstance(); - } - } -} diff --git a/Src/Solid-TradeService/7.IOC/Properties/AssemblyInfo.cs b/Src/Solid-TradeService/7.IOC/Properties/AssemblyInfo.cs deleted file mode 100644 index b681b7c..0000000 --- a/Src/Solid-TradeService/7.IOC/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -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("TradeApp")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TradeApp")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[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("bba07b19-254a-4ef0-bcc5-f8954c963537")] - -// 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")] diff --git a/Src/Solid-TradeService/7.IOC/Readme.md b/Src/Solid-TradeService/7.IOC/Readme.md deleted file mode 100644 index 2ffaf21..0000000 --- a/Src/Solid-TradeService/7.IOC/Readme.md +++ /dev/null @@ -1,5 +0,0 @@ -# Step 7 : - -- create interface for entity : IIdentifiable -- Create IEntityReadWrite - diff --git a/Src/Solid-TradeService/7.IOC/Serializer/DealSerializer.cs b/Src/Solid-TradeService/7.IOC/Serializer/DealSerializer.cs deleted file mode 100644 index ba793fc..0000000 --- a/Src/Solid-TradeService/7.IOC/Serializer/DealSerializer.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using Functional.Maybe; -using Newtonsoft.Json; -using TradeApp.Models; - -namespace TradeApp -{ - public class JsonSerializer : ISerializer where T : IIdentifiable - { - public string Serialize(T entity) - { - return JsonConvert.SerializeObject(entity); - } - - public Maybe Deserialize(string serializedEntity) - { - try - { - return JsonConvert.DeserializeObject(serializedEntity).ToMaybe(); - } - catch (Exception) - { - return Maybe.Nothing; - } - } - } -} diff --git a/Src/Solid-TradeService/7.IOC/Serializer/IDealSerializer.cs b/Src/Solid-TradeService/7.IOC/Serializer/IDealSerializer.cs deleted file mode 100644 index b1f522a..0000000 --- a/Src/Solid-TradeService/7.IOC/Serializer/IDealSerializer.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Functional.Maybe; -using TradeApp.Models; - -namespace TradeApp -{ - public interface ISerializer where T : IIdentifiable - { - string Serialize(T entity); - Maybe Deserialize(string serializedEntity); - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/7.IOC/Storage/FileStorage.cs b/Src/Solid-TradeService/7.IOC/Storage/FileStorage.cs deleted file mode 100644 index b0b4227..0000000 --- a/Src/Solid-TradeService/7.IOC/Storage/FileStorage.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using Functional.Maybe; -using TradeApp.Models; - -namespace TradeApp -{ - public class FileStorage : IFileLocator, IReadWrite where T : IIdentifiable - { - private readonly string _directory; - private readonly ISerializer _serializer; - - public FileStorage(IUsersManager usersManager, ISerializer serializer) - { - _directory = usersManager.GetCurrentUserName(); - _serializer = serializer; - } - - public FileInfo GetFileName(string id) - { - return new FileInfo(Path.Combine(_directory, id + ".json")); - } - - public Maybe Load(string id) - { - try - { - var path = GetFileName(id).FullName; - var text = File.ReadAllText(path); - return _serializer.Deserialize(text); - } - catch (Exception) - { - return new Maybe(); - } - } - - public void Save(Maybe entity) - { - if (entity.HasValue) - { - var path = GetFileName(entity.Value.Id).FullName; - var serializedDeal = _serializer.Serialize(entity.Value); - File.WriteAllText(path, serializedDeal); - } - } - } -} diff --git a/Src/Solid-TradeService/7.IOC/Storage/IFileLocator.cs b/Src/Solid-TradeService/7.IOC/Storage/IFileLocator.cs deleted file mode 100644 index 09b3b58..0000000 --- a/Src/Solid-TradeService/7.IOC/Storage/IFileLocator.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.IO; -using TradeApp.Models; - -namespace TradeApp -{ - public interface IFileLocator where T : IIdentifiable - { - FileInfo GetFileName(string id); - } -} \ No newline at end of file diff --git a/Src/Solid-TradeService/7.IOC/Storage/SQLDealStorage.cs b/Src/Solid-TradeService/7.IOC/Storage/SQLDealStorage.cs deleted file mode 100644 index 5a7eb1a..0000000 --- a/Src/Solid-TradeService/7.IOC/Storage/SQLDealStorage.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Data.SqlClient; -using System.Linq; -using Dapper; -using Functional.Maybe; -using TradeApp.Models; - -namespace TradeApp -{ - public class SQLDealStorage : IReadWrite where T : IIdentifiable - { - private readonly string _connectionString; - private readonly ISerializer _serializer; - - public SQLDealStorage(string connectionString, ISerializer serializer) - { - _connectionString = connectionString; - _serializer = serializer; - } - - public Maybe Load(string id) - { - using (SqlConnection connection = new SqlConnection(_connectionString)) - { - connection.Open(); - var result = connection.Query("select Value from Deals where Id = @Id", new { Id = id }).ToArray(); - return result.Any() - ? _serializer.Deserialize(result.First()) - : Maybe.Nothing; - } - } - - public void Save(Maybe entity) - { - if(!entity.HasValue) return; - - using (var connection = new SqlConnection(_connectionString)) - { - var serializedDeal = _serializer.Serialize(entity.Value); - - connection.Open(); - connection.Execute(@"delete from Deals where Id = @Id", new { Id = entity.Value.Id }); - connection.Execute(@"insert Deals(Id, Value) values (@Id, @Value)", - new {entity.Value.Id, Value = serializedDeal }); - } - } - } -} diff --git a/Src/Solid-TradeService/7.IOC/TradeApp.csproj b/Src/Solid-TradeService/7.IOC/TradeApp.csproj deleted file mode 100644 index 3cb1342..0000000 --- a/Src/Solid-TradeService/7.IOC/TradeApp.csproj +++ /dev/null @@ -1,141 +0,0 @@ - - - - - Debug - AnyCPU - {BB7E15A0-6C2E-490E-8E4A-5866E28A7B42} - Exe - Properties - TradeApp - TradeApp - v4.6 - 512 - true - 1 - - - AnyCPU - true - full - false - bin\Debug\ - TRACE;DEBUG - prompt - 4 - False - False - True - False - False - False - True - True - True - True - True - True - True - True - False - True - False - True - False - False - False - True - True - False - True - True - True - False - False - - - - - - - - True - False - False - True - Full - %28none%29 - 3 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Dapper.1.42\lib\net45\Dapper.dll - - - ..\packages\Functional.Maybe.1.0.3\lib\Functional.Maybe.dll - True - - - ..\..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - True - - - ..\packages\SimpleInjector.2.8.3\lib\net45\SimpleInjector.dll - True - - - - ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/7.IOC/UsersManager.cs b/Src/Solid-TradeService/7.IOC/UsersManager.cs deleted file mode 100644 index 8c20781..0000000 --- a/Src/Solid-TradeService/7.IOC/UsersManager.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace TradeApp -{ - public interface IUsersManager - { - string GetCurrentUserName(); - } - - public class UsersManager : IUsersManager - { - public string GetCurrentUserName() - { - return Environment.UserName; - } - } -} diff --git a/Src/Solid-TradeService/7.IOC/packages.config b/Src/Solid-TradeService/7.IOC/packages.config deleted file mode 100644 index 423dbb5..0000000 --- a/Src/Solid-TradeService/7.IOC/packages.config +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/Src/Solid-TradeService/0.CodeBase/App.config b/Src/Solid-TradeService/App.config similarity index 60% rename from Src/Solid-TradeService/0.CodeBase/App.config rename to Src/Solid-TradeService/App.config index 8324aa6..d1428ad 100644 --- a/Src/Solid-TradeService/0.CodeBase/App.config +++ b/Src/Solid-TradeService/App.config @@ -1,6 +1,6 @@ - + - + - \ No newline at end of file + diff --git a/Src/Solid-TradeService/0.CodeBase/DealService.cs b/Src/Solid-TradeService/DealService.cs similarity index 100% rename from Src/Solid-TradeService/0.CodeBase/DealService.cs rename to Src/Solid-TradeService/DealService.cs diff --git a/Src/Solid-TradeService/0.CodeBase/Log/ColoredConsoleLogProvider.cs b/Src/Solid-TradeService/Log/ColoredConsoleLogProvider.cs similarity index 100% rename from Src/Solid-TradeService/0.CodeBase/Log/ColoredConsoleLogProvider.cs rename to Src/Solid-TradeService/Log/ColoredConsoleLogProvider.cs diff --git a/Src/Solid-TradeService/1.CQS_Maybe/Models/Deal.cs b/Src/Solid-TradeService/Models/Deal.cs similarity index 52% rename from Src/Solid-TradeService/1.CQS_Maybe/Models/Deal.cs rename to Src/Solid-TradeService/Models/Deal.cs index b67a5d7..7bb0cfd 100644 --- a/Src/Solid-TradeService/1.CQS_Maybe/Models/Deal.cs +++ b/Src/Solid-TradeService/Models/Deal.cs @@ -4,18 +4,12 @@ namespace TradeApp.Models public class Deal { public string Id { get; set; } - public double Price { get; internal set; } - public DateTime Time { get; internal set; } - public int Quantity { get; internal set; } - + public double Price { get; set; } + public DateTime Time { get; set; } + public int Quantity { get; set; } public string Symbol { get; set; } - - public OrderDirection Direction - { - get { - return Quantity >= 0 ? OrderDirection.Buy : OrderDirection.Sell; - } - } + public OrderDirection Direction { get; set; } + public override string ToString() { return string.Format("OrderId: {0} {1} order for {2} unit{3} of {4}", Id,Direction, Quantity, Quantity == 1 ? "" : "s", Symbol); diff --git a/Src/Solid-TradeService/0.CodeBase/Models/OrderDirection.cs b/Src/Solid-TradeService/Models/OrderDirection.cs similarity index 100% rename from Src/Solid-TradeService/0.CodeBase/Models/OrderDirection.cs rename to Src/Solid-TradeService/Models/OrderDirection.cs diff --git a/Src/Solid-TradeService/0.CodeBase/Program.cs b/Src/Solid-TradeService/Program.cs similarity index 77% rename from Src/Solid-TradeService/0.CodeBase/Program.cs rename to Src/Solid-TradeService/Program.cs index 580ec39..61bbadb 100644 --- a/Src/Solid-TradeService/0.CodeBase/Program.cs +++ b/Src/Solid-TradeService/Program.cs @@ -8,11 +8,10 @@ class Program { static void Main(string[] args) { - Logging.LogProvider.SetCurrentLogProvider(new ColoredConsoleLogProvider()); + Logging.LogProvider.SetCurrentLogProvider(new ColoredConsoleLogProvider()); - DealService service = new DealService(); + var service = new DealService { Username = "Vincent" }; - service.Username = "Vincent"; var id = Guid.NewGuid().ToString(); var deal = new Deal { @@ -22,6 +21,7 @@ static void Main(string[] args) Symbol = "MSFT", Time = DateTime.Now }; + var result = service.Save(id, deal); Console.WriteLine(result); @@ -29,8 +29,8 @@ static void Main(string[] args) Console.WriteLine(); Console.WriteLine(); - var vincentDeal = service.Load(id); - Console.WriteLine(vincentDeal); + var vincentDeal = service.Load(id); + Console.WriteLine(vincentDeal); Console.ReadLine(); } diff --git a/Src/Solid-TradeService/0.CodeBase/Properties/AssemblyInfo.cs b/Src/Solid-TradeService/Properties/AssemblyInfo.cs similarity index 100% rename from Src/Solid-TradeService/0.CodeBase/Properties/AssemblyInfo.cs rename to Src/Solid-TradeService/Properties/AssemblyInfo.cs diff --git a/Src/Solid-TradeService/Solid-TradeService.sln b/Src/Solid-TradeService/Solid-TradeService.sln index a0d3186..4d936f3 100644 --- a/Src/Solid-TradeService/Solid-TradeService.sln +++ b/Src/Solid-TradeService/Solid-TradeService.sln @@ -1,41 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.22823.1 +VisualStudioVersion = 14.0.24720.0 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2.SRP", "2.SRP", "{55C2830D-0C99-499D-84ED-B096533C6F1F}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1.CQS_Maybe", "1.CQS_Maybe", "{06AC0605-14FB-4E87-90D6-E51BB657D929}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3.OCP", "3.OCP", "{10CD9A2D-2CF7-4826-AA1E-5E6ADFD36D74}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "4.LSP", "4.LSP", "{E56C865C-9961-49C0-8CC7-904FEECC4FA9}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "5.ISP", "5.ISP", "{7CA23CF5-B32B-490E-B1D2-B8BF2BA2A135}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "6.DIP", "6.DIP", "{6C547043-F1A2-4121-98CB-D7564FF686D6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "7.IOC", "7.IOC", "{3AA6B187-8A26-4BA2-8D87-1A3FD6FF9DDC}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "0.CodeBase", "0.CodeBase", "{743F476E-0A91-4D3E-8EBF-BE77B5CBF8BF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TradeApp", "0.CodeBase\TradeApp.csproj", "{1B62092F-1346-454F-BD50-365BC0E556D7}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TradeApp", "1.CQS_Maybe\TradeApp.csproj", "{8C216700-5A1E-4F66-BC79-3A24EF7E1EC4}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TradeApp", "2.SRP\TradeApp.csproj", "{A2380718-A48F-4333-94F0-FAF25C9EE17E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TradeApp", "3.OCP\TradeApp.csproj", "{986AEC51-2775-4B65-AF59-2DA17455376C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "8.Tests", "8.Tests", "{190F8130-B359-49CD-9A8F-0F18DDBD4218}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TradeApp", "4.LSP\TradeApp.csproj", "{3417DA3A-14F9-4720-9F4E-D59C2E3AB77B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TradeApp", "5.ISP\TradeApp.csproj", "{F4D8FF66-07AE-4DD4-8F9D-F22E84C4BD01}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TradeApp", "6.DIP\TradeApp.csproj", "{EEF6D9D4-7516-4C94-B5F7-D6E50427E214}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TradeApp", "7.IOC\TradeApp.csproj", "{BB7E15A0-6C2E-490E-8E4A-5866E28A7B42}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TradeApp", "TradeApp.csproj", "{1B62092F-1346-454F-BD50-365BC0E556D7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -47,46 +15,8 @@ Global {1B62092F-1346-454F-BD50-365BC0E556D7}.Debug|Any CPU.Build.0 = Debug|Any CPU {1B62092F-1346-454F-BD50-365BC0E556D7}.Release|Any CPU.ActiveCfg = Release|Any CPU {1B62092F-1346-454F-BD50-365BC0E556D7}.Release|Any CPU.Build.0 = Release|Any CPU - {8C216700-5A1E-4F66-BC79-3A24EF7E1EC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8C216700-5A1E-4F66-BC79-3A24EF7E1EC4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8C216700-5A1E-4F66-BC79-3A24EF7E1EC4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8C216700-5A1E-4F66-BC79-3A24EF7E1EC4}.Release|Any CPU.Build.0 = Release|Any CPU - {A2380718-A48F-4333-94F0-FAF25C9EE17E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A2380718-A48F-4333-94F0-FAF25C9EE17E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A2380718-A48F-4333-94F0-FAF25C9EE17E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A2380718-A48F-4333-94F0-FAF25C9EE17E}.Release|Any CPU.Build.0 = Release|Any CPU - {986AEC51-2775-4B65-AF59-2DA17455376C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {986AEC51-2775-4B65-AF59-2DA17455376C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {986AEC51-2775-4B65-AF59-2DA17455376C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {986AEC51-2775-4B65-AF59-2DA17455376C}.Release|Any CPU.Build.0 = Release|Any CPU - {3417DA3A-14F9-4720-9F4E-D59C2E3AB77B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3417DA3A-14F9-4720-9F4E-D59C2E3AB77B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3417DA3A-14F9-4720-9F4E-D59C2E3AB77B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3417DA3A-14F9-4720-9F4E-D59C2E3AB77B}.Release|Any CPU.Build.0 = Release|Any CPU - {F4D8FF66-07AE-4DD4-8F9D-F22E84C4BD01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F4D8FF66-07AE-4DD4-8F9D-F22E84C4BD01}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F4D8FF66-07AE-4DD4-8F9D-F22E84C4BD01}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F4D8FF66-07AE-4DD4-8F9D-F22E84C4BD01}.Release|Any CPU.Build.0 = Release|Any CPU - {EEF6D9D4-7516-4C94-B5F7-D6E50427E214}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EEF6D9D4-7516-4C94-B5F7-D6E50427E214}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EEF6D9D4-7516-4C94-B5F7-D6E50427E214}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EEF6D9D4-7516-4C94-B5F7-D6E50427E214}.Release|Any CPU.Build.0 = Release|Any CPU - {BB7E15A0-6C2E-490E-8E4A-5866E28A7B42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BB7E15A0-6C2E-490E-8E4A-5866E28A7B42}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BB7E15A0-6C2E-490E-8E4A-5866E28A7B42}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BB7E15A0-6C2E-490E-8E4A-5866E28A7B42}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {1B62092F-1346-454F-BD50-365BC0E556D7} = {743F476E-0A91-4D3E-8EBF-BE77B5CBF8BF} - {8C216700-5A1E-4F66-BC79-3A24EF7E1EC4} = {06AC0605-14FB-4E87-90D6-E51BB657D929} - {A2380718-A48F-4333-94F0-FAF25C9EE17E} = {55C2830D-0C99-499D-84ED-B096533C6F1F} - {986AEC51-2775-4B65-AF59-2DA17455376C} = {10CD9A2D-2CF7-4826-AA1E-5E6ADFD36D74} - {3417DA3A-14F9-4720-9F4E-D59C2E3AB77B} = {E56C865C-9961-49C0-8CC7-904FEECC4FA9} - {F4D8FF66-07AE-4DD4-8F9D-F22E84C4BD01} = {7CA23CF5-B32B-490E-B1D2-B8BF2BA2A135} - {EEF6D9D4-7516-4C94-B5F7-D6E50427E214} = {6C547043-F1A2-4121-98CB-D7564FF686D6} - {BB7E15A0-6C2E-490E-8E4A-5866E28A7B42} = {3AA6B187-8A26-4BA2-8D87-1A3FD6FF9DDC} - EndGlobalSection EndGlobal diff --git a/Src/Solid-TradeService/0.CodeBase/TradeApp.csproj b/Src/Solid-TradeService/TradeApp.csproj similarity index 84% rename from Src/Solid-TradeService/0.CodeBase/TradeApp.csproj rename to Src/Solid-TradeService/TradeApp.csproj index 8a3e992..329dca6 100644 --- a/Src/Solid-TradeService/0.CodeBase/TradeApp.csproj +++ b/Src/Solid-TradeService/TradeApp.csproj @@ -9,9 +9,10 @@ Properties TradeApp TradeApp - v4.6 + v4.5 512 true + AnyCPU @@ -22,6 +23,7 @@ DEBUG;TRACE prompt 4 + false AnyCPU @@ -31,15 +33,16 @@ TRACE prompt 4 + false - - ..\..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + + packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll True - ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll True @@ -51,8 +54,8 @@ + - @@ -61,7 +64,9 @@ - + + Designer +