diff --git a/src/Akeneo/Akeneo.csproj b/src/Akeneo/Akeneo.csproj
index d3c8b00..497af55 100644
--- a/src/Akeneo/Akeneo.csproj
+++ b/src/Akeneo/Akeneo.csproj
@@ -1,7 +1,7 @@
- netstandard1.5;net451
+ netstandard2.0
Akeneo.NET
0.1.14
pardahlman
@@ -13,19 +13,26 @@
https://github.com/pardahlman/akeneo-csharp
git
akeneo, pim
+ true
+ 1.5
-
- NETSTANDARD1_5, LIBLOG_PORTABLE
+
+ NETSTANDARD2_0, LIBLOG_PORTABLE
-
+
+
+
-
-
-
+
+
+ all
+ runtime; build; native; contentfiles; analyzers
+
+
\ No newline at end of file
diff --git a/src/Akeneo/AkeneoClient.cs b/src/Akeneo/AkeneoClient.cs
index c986b0d..ede363d 100644
--- a/src/Akeneo/AkeneoClient.cs
+++ b/src/Akeneo/AkeneoClient.cs
@@ -26,7 +26,7 @@ public class AkeneoClient : AkenioClientBase, IAkeneoClient
private readonly SearchQueryBuilder _searchBuilder;
private readonly ILog _logger = LogProvider.For();
- public AkeneoClient(AkeneoOptions options)
+ public AkeneoClient(AkeneoOptions options)
: this(options.ApiEndpoint, new AuthenticationClient(options.ApiEndpoint, options.ClientId, options.ClientSecret, options.UserName, options.Password)) { }
public AkeneoClient(Uri apiEndPoint, IAuthenticationClient authClient) : base(apiEndPoint, authClient)
@@ -46,7 +46,14 @@ public AkeneoClient(Uri apiEndPoint, IAuthenticationClient authClient) : base(ap
: default(TModel);
}
- public async Task GetAsync(string parentCode, string code, CancellationToken ct = default(CancellationToken)) where TModel : ModelBase
+ public async Task GetByUrl(string url, CancellationToken ct = default(CancellationToken))
+ {
+ _logger.Debug($"Getting resource from URL '{url}'.");
+ HttpResponseMessage response = await GetAsync(url, ct);
+ return await response.Content.ReadAsStringAsync();
+ }
+
+ public async Task GetAsync(string parentCode, string code, CancellationToken ct = default(CancellationToken)) where TModel : ModelBase
{
var endpoint = _endpointResolver.ForResource(parentCode, code);
_logger.Debug($"Getting resource '{typeof(TModel).Name}' from URL '{endpoint}'.");
@@ -62,7 +69,13 @@ public AkeneoClient(Uri apiEndPoint, IAuthenticationClient authClient) : base(ap
return FilterAsync(queryString, ct);
}
- public async Task> FilterAsync(string queryString, CancellationToken ct = default(CancellationToken)) where TModel : ModelBase
+ public Task> SearchAndGetAllAsync(IEnumerable criterias, CancellationToken ct = default(CancellationToken)) where TModel : ModelBase
+ {
+ var queryString = _searchBuilder.GetQueryStringParam(criterias);
+ return FilterAndGetAllAsync(queryString, null, ct);
+ }
+
+ public async Task> FilterAsync(string queryString, CancellationToken ct = default(CancellationToken)) where TModel : ModelBase
{
var endpoint = _endpointResolver.ForResourceType();
_logger.Debug($"Filtering resource '{typeof(TModel).Name}' from URL '{endpoint}' with query '{queryString}'.");
@@ -71,13 +84,36 @@ public AkeneoClient(Uri apiEndPoint, IAuthenticationClient authClient) : base(ap
result.Code = response.StatusCode;
return result;
}
+ public async Task> FilterAndGetAllAsync(string queryString, string cursor = null, CancellationToken ct = default(CancellationToken)) where TModel : ModelBase
+ {
+ var endpoint = _endpointResolver.WithSearchAfter(100, cursor);
+ _logger.Debug($"Filtering resource '{typeof(TModel).Name}' from URL '{endpoint}' with query '{queryString}'.");
+ var response = await GetAsync($"{endpoint}{queryString}", ct);
+
+ if (!response.IsSuccessStatusCode) throw new HttpRequestException($"Error while executing GET reques: {endpoint}{queryString}");
+
+ PaginationResult paginationResult = await response.Content.ReadAsJsonAsync>();
+ paginationResult.Code = response.StatusCode;
+
+ List items = paginationResult.GetItems();
- public Task> GetManyAsync(int page = 1, int limit = 10, bool withCount = false, CancellationToken ct = default(CancellationToken)) where TModel : ModelBase
+ var nextCursor = paginationResult.Links.GetCursor();
+
+ if (nextCursor != null)
+ {
+ var nextItems = await FilterAndGetAllAsync(queryString, nextCursor, ct);
+ items.AddRange(nextItems);
+ }
+
+ return items;
+ }
+
+ public Task> GetManyAsync(int page = 1, int limit = 10, bool withCount = false, CancellationToken ct = default(CancellationToken)) where TModel : ModelBase
{
return GetManyAsync(null, page, limit, withCount, ct);
}
- public async Task> GetManyAsync(string parentCode, int page = 1, int limit = 10, bool withCount = false, CancellationToken ct = default(CancellationToken)) where TModel : ModelBase
+ public async Task> GetManyAsync(string parentCode, int page = 1, int limit = 10, bool withCount = false, CancellationToken ct = default(CancellationToken)) where TModel : ModelBase
{
var endpoint = _endpointResolver.ForPagination(parentCode, page, limit, withCount);
_logger.Debug($"Getting multiple resource '{typeof(TModel).Name}' from URL '{endpoint}'.");
@@ -87,6 +123,28 @@ public AkeneoClient(Uri apiEndPoint, IAuthenticationClient authClient) : base(ap
: PaginationResult.Empty;
}
+ public async Task> GetAllAsync(string cursor = null, CancellationToken ct = default(CancellationToken)) where TModel : ModelBase
+ {
+ var endpoint = _endpointResolver.WithSearchAfter(100, cursor);
+ _logger.Debug($"Getting multiple resource '{typeof(TModel).Name}' from URL '{endpoint}'.");
+ var response = await GetAsync(endpoint, ct);
+
+ if (!response.IsSuccessStatusCode) return new List();
+
+ PaginationResult paginationResult = await response.Content.ReadAsJsonAsync>();
+ var items = paginationResult.GetItems();
+
+ var nextCursor = paginationResult.Links.GetCursor();
+
+ if (nextCursor != null)
+ {
+ var nextItems = await GetAllAsync(nextCursor, ct);
+ items.AddRange(nextItems);
+ }
+
+ return items;
+ }
+
public async Task CreateAsync(TModel model, CancellationToken ct = default(CancellationToken)) where TModel : ModelBase
{
var option = model as AttributeOption;
diff --git a/src/Akeneo/Client/PaginationResult.cs b/src/Akeneo/Client/PaginationResult.cs
index b81187f..e556328 100644
--- a/src/Akeneo/Client/PaginationResult.cs
+++ b/src/Akeneo/Client/PaginationResult.cs
@@ -1,7 +1,9 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
+using System.Web;
using Newtonsoft.Json;
namespace Akeneo.Client
@@ -39,11 +41,22 @@ public static List GetItems(this PaginationResult result)
public static class PaginationDictionaryExtensions
{
private static readonly string Next = "next";
+ private static readonly string SearchAfter = "search_after";
public static PaginationLink GetNext(this IDictionary links)
{
return links.ContainsKey(Next) ? links[Next] : null;
}
+
+ public static string GetCursor(this IDictionary links)
+ {
+ if (!links.TryGetValue(Next, out var link)) return null;
+
+ Uri myUri = new Uri(link.Href);
+ string cursor = HttpUtility.ParseQueryString(myUri.Query).Get(SearchAfter);
+ cursor = WebUtility.UrlEncode(cursor);
+ return cursor;
+ }
}
diff --git a/src/Akeneo/Common/EndpointResolver.cs b/src/Akeneo/Common/EndpointResolver.cs
index 9c9d45d..bff3d10 100644
--- a/src/Akeneo/Common/EndpointResolver.cs
+++ b/src/Akeneo/Common/EndpointResolver.cs
@@ -15,6 +15,8 @@ public class EndpointResolver
private static readonly Type Product = typeof(Product);
private static readonly Type MediaFile = typeof(MediaFile);
private static readonly Type Locale = typeof(Locale);
+ private static readonly Type ProductModel = typeof(ProductModel);
+ private static readonly Type FamilyVariant = typeof(FamilyVariant);
private readonly ConcurrentDictionary _typeToEndpointCache;
@@ -116,6 +118,14 @@ protected virtual string GetResourceEndpoint(Type modelType)
{
return Endpoints.Locale;
}
+ if (ProductModel.GetTypeInfo().IsAssignableFrom(type))
+ {
+ return Endpoints.ProductModel;
+ }
+ if (FamilyVariant.GetTypeInfo().IsAssignableFrom(type))
+ {
+ return Endpoints.FamilyVariant;
+ }
throw new NotSupportedException($"Unable to find API endpoint for type {modelType.FullName}");
});
}
@@ -131,5 +141,13 @@ public string ForPagination(string parentCode, int page = 1, int limit =
var baseUrl = ForResourceType(parentCode);
return $"{baseUrl}?page={page}&limit={limit}&with_count={withCount.ToString().ToLower()}";
}
+
+ public string WithSearchAfter(int limit = 100, string searchAfter = null) where TModel : ModelBase
+ {
+ var baseUrl = ForResourceType();
+ return searchAfter == null
+ ? $"{baseUrl}?pagination_type=search_after&limit={limit}"
+ : $"{baseUrl}?pagination_type=search_after&limit={limit}&search_after={searchAfter}";
+ }
}
}
diff --git a/src/Akeneo/Common/Endpoints.cs b/src/Akeneo/Common/Endpoints.cs
index cc2a46b..64febf8 100644
--- a/src/Akeneo/Common/Endpoints.cs
+++ b/src/Akeneo/Common/Endpoints.cs
@@ -9,5 +9,7 @@ public class Endpoints
public const string Families = "api/rest/v1/families";
public const string MediaFiles = "api/rest/v1/media-files";
public const string Locale = "api/rest/v1/locales";
+ public const string ProductModel = "api/rest/v1/product-models";
+ public const string FamilyVariant = "/api/rest/v1/families/{1}/variants";
}
-}
+}
\ No newline at end of file
diff --git a/src/Akeneo/Logging/LibLog.cs b/src/Akeneo/Logging/LibLog.cs
deleted file mode 100644
index c90d5ff..0000000
--- a/src/Akeneo/Logging/LibLog.cs
+++ /dev/null
@@ -1,2380 +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 [InternalsVisibleTo] 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
-
-using System.Diagnostics.CodeAnalysis;
-
-[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Akeneo.Logging")]
-[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Akeneo.Logging.Logger.#Invoke(Akeneo.Logging.LogLevel,System.Func`1,System.Exception,System.Object[])")]
-
-// If you copied this file manually, you need to change all "Akeneo" so not to clash with other libraries
-// that use LibLog
-#if LIBLOG_PROVIDERS_ONLY
-namespace Akeneo.LibLog
-#else
-namespace Akeneo.Logging
-#endif
-{
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
-#if LIBLOG_PROVIDERS_ONLY
- using Akeneo.LibLog.LogProviders;
-#else
- using Akeneo.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_PORTABLE
- [ExcludeFromCodeCoverage]
-#endif
-#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 Debug(this ILog logger, string message, params object[] args)
- {
- logger.DebugFormat(message, args);
- }
-
- public static void Debug(this ILog logger, Exception exception, string message, params object[] args)
- {
- logger.DebugException(message, exception, args);
- }
-
- 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 Error(this ILog logger, string message, params object[] args)
- {
- logger.ErrorFormat(message, args);
- }
-
- public static void Error(this ILog logger, Exception exception, string message, params object[] args)
- {
- logger.ErrorException(message, exception, args);
- }
-
- 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 Fatal(this ILog logger, string message, params object[] args)
- {
- logger.FatalFormat(message, args);
- }
-
- public static void Fatal(this ILog logger, Exception exception, string message, params object[] args)
- {
- logger.FatalException(message, exception, args);
- }
-
- 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 Info(this ILog logger, string message, params object[] args)
- {
- logger.InfoFormat(message, args);
- }
-
- public static void Info(this ILog logger, Exception exception, string message, params object[] args)
- {
- logger.InfoException(message, exception, args);
- }
-
- 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 Trace(this ILog logger, string message, params object[] args)
- {
- logger.TraceFormat(message, args);
- }
-
- public static void Trace(this ILog logger, Exception exception, string message, params object[] args)
- {
- logger.TraceException(message, exception, args);
- }
-
- 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 Warn(this ILog logger, string message, params object[] args)
- {
- logger.WarnFormat(message, args);
- }
-
- public static void Warn(this ILog logger, Exception exception, string message, params object[] args)
- {
- logger.WarnException(message, exception, args);
- }
-
- 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_PORTABLE
- [ExcludeFromCodeCoverage]
-#endif
-#if LIBLOG_PROVIDERS_ONLY
- internal
-#else
- public
-#endif
- static class LogProvider
- {
-#if !LIBLOG_PROVIDERS_ONLY
- 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;
-
- [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
- 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.
- /// If the type is null then this name will be used as the log name instead
- /// An instance of
-#if LIBLOG_PUBLIC
- public
-#else
- internal
-#endif
- static ILog GetLogger(Type type, string fallbackTypeName = "System.Object")
- {
- // If the type passed in is null then fallback to the type name specified
- return GetLogger(type != null ? type.FullName : fallbackTypeName);
- }
-
- ///
- /// 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.
- [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "SetCurrentLogProvider")]
-#if LIBLOG_PUBLIC
- public
-#else
- internal
-#endif
- static IDisposable OpenNestedContext(string message)
- {
- ILogProvider logProvider = CurrentLogProvider ?? ResolveLogProvider();
-
- return logProvider == null
- ? new DisposableAction(() => { })
- : logProvider.OpenNestedContext(message);
- }
-
- ///
- /// Opens a mapped diagnostics context.
- ///
- /// A key.
- /// A value.
- /// An that closes context when disposed.
- [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "SetCurrentLogProvider")]
-#if LIBLOG_PUBLIC
- public
-#else
- internal
-#endif
- static IDisposable OpenMappedContext(string key, string value)
- {
- ILogProvider logProvider = CurrentLogProvider ?? ResolveLogProvider();
-
- return logProvider == null
- ? new DisposableAction(() => { })
- : logProvider.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
-
- [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Console.WriteLine(System.String,System.Object,System.Object)")]
- [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
- 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
-#if !LIBLOG_PORTABLE
- [ExcludeFromCodeCoverage]
-#endif
- 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
-#if !LIBLOG_PORTABLE
- [ExcludeFromCodeCoverage]
-#endif
- 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; }
- }
-
- [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
- public bool Log(LogLevel logLevel, Func messageFunc, Exception exception = null, params object[] formatParameters)
- {
- if (_getIsDisabled())
- {
- return false;
- }
- 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 Akeneo.LibLog.LogProviders
-#else
-namespace Akeneo.Logging.LogProviders
-#endif
-{
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
-#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;
-
-#if !LIBLOG_PORTABLE
- [ExcludeFromCodeCoverage]
-#endif
- 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;
- }
- }
-
-#if !LIBLOG_PORTABLE
- [ExcludeFromCodeCoverage]
-#endif
- internal class NLogLogProvider : LogProviderBase
- {
- private readonly Func _getLoggerByNameDelegate;
- private static bool s_providerIsAvailableOverride = true;
-
- [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "LogManager")]
- [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "NLog")]
- 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();
- }
-
-#if !LIBLOG_PORTABLE
- [ExcludeFromCodeCoverage]
-#endif
- internal class NLogLogger
- {
- private readonly dynamic _logger;
-
- private static Func _logEventInfoFact;
-
- private static readonly object _levelTrace;
- private static readonly object _levelDebug;
- private static readonly object _levelInfo;
- private static readonly object _levelWarn;
- private static readonly object _levelError;
- private static readonly object _levelFatal;
-
- static NLogLogger()
- {
- try
- {
- var logEventLevelType = Type.GetType("NLog.LogLevel, NLog");
- if (logEventLevelType == null)
- {
- throw new InvalidOperationException("Type NLog.LogLevel was not found.");
- }
-
- var levelFields = logEventLevelType.GetFieldsPortable().ToList();
- _levelTrace = levelFields.First(x => x.Name == "Trace").GetValue(null);
- _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);
-
- var logEventInfoType = Type.GetType("NLog.LogEventInfo, NLog");
- if (logEventInfoType == null)
- {
- throw new InvalidOperationException("Type NLog.LogEventInfo was not found.");
- }
- MethodInfo createLogEventInfoMethodInfo = logEventInfoType.GetMethodPortable("Create",
- logEventLevelType, typeof(string), typeof(Exception), typeof(IFormatProvider), typeof(string), typeof(object[]));
- ParameterExpression loggerNameParam = Expression.Parameter(typeof(string));
- ParameterExpression levelParam = Expression.Parameter(typeof(object));
- ParameterExpression messageParam = Expression.Parameter(typeof(string));
- ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception));
- UnaryExpression levelCast = Expression.Convert(levelParam, logEventLevelType);
- MethodCallExpression createLogEventInfoMethodCall = Expression.Call(null,
- createLogEventInfoMethodInfo,
- levelCast, loggerNameParam, exceptionParam,
- Expression.Constant(null, typeof(IFormatProvider)), messageParam, Expression.Constant(null, typeof(object[])));
- _logEventInfoFact = Expression.Lambda>(createLogEventInfoMethodCall,
- loggerNameParam, levelParam, messageParam, exceptionParam).Compile();
- }
- catch { }
- }
-
- internal NLogLogger(dynamic logger)
- {
- _logger = logger;
- }
-
- [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
- public bool Log(LogLevel logLevel, Func messageFunc, Exception exception, params object[] formatParameters)
- {
- if (messageFunc == null)
- {
- return IsLogLevelEnable(logLevel);
- }
- messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters);
-
- if (_logEventInfoFact != null)
- {
- if (IsLogLevelEnable(logLevel))
- {
- var nlogLevel = this.TranslateLevel(logLevel);
- Type s_callerStackBoundaryType;
-#if !LIBLOG_PORTABLE
- StackTrace stack = new StackTrace();
- Type thisType = GetType();
- Type knownType0 = typeof(LoggerExecutionWrapper);
- Type knownType1 = typeof(LogExtensions);
- //Maybe inline, so we may can't found any LibLog classes in stack
- s_callerStackBoundaryType = null;
- for (var i = 0; i < stack.FrameCount; i++)
- {
- var declaringType = stack.GetFrame(i).GetMethod().DeclaringType;
- if (!IsInTypeHierarchy(thisType, declaringType) &&
- !IsInTypeHierarchy(knownType0, declaringType) &&
- !IsInTypeHierarchy(knownType1, declaringType))
- {
- if (i > 1)
- s_callerStackBoundaryType = stack.GetFrame(i - 1).GetMethod().DeclaringType;
- break;
- }
- }
-#else
- s_callerStackBoundaryType = null;
-#endif
- if (s_callerStackBoundaryType != null)
- _logger.Log(s_callerStackBoundaryType, _logEventInfoFact(_logger.Name, nlogLevel, messageFunc(), exception));
- else
- _logger.Log(_logEventInfoFact(_logger.Name, nlogLevel, messageFunc(), exception));
- return true;
- }
- return false;
- }
-
- 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 static bool IsInTypeHierarchy(Type currentType, Type checkType)
- {
- while (currentType != null && currentType != typeof(object))
- {
- if (currentType == checkType)
- {
- return true;
- }
- currentType = currentType.GetBaseTypePortable();
- }
- return false;
- }
-
- [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
- 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;
- }
- }
-
- private object TranslateLevel(LogLevel logLevel)
- {
- switch (logLevel)
- {
- case LogLevel.Trace:
- return _levelTrace;
- 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);
- }
- }
- }
- }
-
-#if !LIBLOG_PORTABLE
- [ExcludeFromCodeCoverage]
-#endif
- internal class Log4NetLogProvider : LogProviderBase
- {
- private readonly Func _getLoggerByNameDelegate;
- private static bool s_providerIsAvailableOverride = true;
-
- [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "LogManager")]
- 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 logicalThreadContextType = Type.GetType("log4net.LogicalThreadContext, log4net");
- PropertyInfo stacksProperty = logicalThreadContextType.GetPropertyPortable("Stacks");
- Type logicalThreadContextStacksType = stacksProperty.PropertyType;
- PropertyInfo stacksIndexerProperty = logicalThreadContextStacksType.GetPropertyPortable("Item");
- Type stackType = stacksIndexerProperty.PropertyType;
- MethodInfo pushMethod = stackType.GetMethodPortable("Push");
-
- ParameterExpression messageParameter =
- Expression.Parameter(typeof(string), "message");
-
- // message => LogicalThreadContext.Stacks.Item["NDC"].Push(message);
- MethodCallExpression callPushBody =
- Expression.Call(
- Expression.Property(Expression.Property(null, stacksProperty),
- stacksIndexerProperty,
- Expression.Constant("NDC")),
- pushMethod,
- messageParameter);
-
- OpenNdc result =
- Expression.Lambda(callPushBody, messageParameter)
- .Compile();
-
- return result;
- }
-
- protected override OpenMdc GetOpenMdcMethod()
- {
- Type logicalThreadContextType = Type.GetType("log4net.LogicalThreadContext, log4net");
- PropertyInfo propertiesProperty = logicalThreadContextType.GetPropertyPortable("Properties");
- Type logicalThreadContextPropertiesType = propertiesProperty.PropertyType;
- PropertyInfo propertiesIndexerProperty = logicalThreadContextPropertiesType.GetPropertyPortable("Item");
-
- MethodInfo removeMethod = logicalThreadContextPropertiesType.GetMethodPortable("Remove");
-
- ParameterExpression keyParam = Expression.Parameter(typeof(string), "key");
- ParameterExpression valueParam = Expression.Parameter(typeof(string), "value");
-
- MemberExpression propertiesExpression = Expression.Property(null, propertiesProperty);
-
- // (key, value) => LogicalThreadContext.Properties.Item[key] = value;
- BinaryExpression setProperties = Expression.Assign(Expression.Property(propertiesExpression, propertiesIndexerProperty, keyParam), valueParam);
-
- // key => LogicalThreadContext.Properties.Remove(key);
- MethodCallExpression removeMethodCall = Expression.Call(propertiesExpression, removeMethod, keyParam);
-
- Action set = Expression
- .Lambda>(setProperties, 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();
- }
-
-#if !LIBLOG_PORTABLE
- [ExcludeFromCodeCoverage]
-#endif
- 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