mirror of
https://github.com/AlexMacocian/WpfExtended.git
synced 2026-07-22 01:39:30 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1325a6821e | |||
| cd68132463 | |||
| 7e9c3c5f64 |
@@ -21,6 +21,7 @@ jobs:
|
||||
env:
|
||||
Solution_Path: WpfExtended.sln
|
||||
Actions_Allow_Unsecure_Commands: true
|
||||
Test_Project_Path: WpfExtended.Test\WpfExtended.Tests.csproj
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace WpfExtended.Tests.Configuration
|
||||
namespace SystemExtensions.DependencyInjection.Tests.Configuration
|
||||
{
|
||||
public sealed class DummyOptions
|
||||
{
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Extensions;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WpfExtended.Tests.Http
|
||||
{
|
||||
public class HttpMessageLogger : DelegatingHandler
|
||||
{
|
||||
private readonly ILogger logger;
|
||||
public HttpMessageLogger(ILogger logger, HttpMessageHandler innerHandler) : base(innerHandler)
|
||||
{
|
||||
this.logger = logger.ThrowIfNull(nameof(logger));
|
||||
}
|
||||
|
||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
this.logger.LogInformation($"{request.Method} - {request.RequestUri}");
|
||||
var response = await base.SendAsync(request, cancellationToken);
|
||||
this.logger.LogInformation($"{response.RequestMessage.RequestUri} - {response.StatusCode}");
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Configuration;
|
||||
using System.Extensions;
|
||||
using System.Windows.Extensions;
|
||||
using WpfExtended.Tests.Configuration;
|
||||
using SystemExtensions.DependencyInjection.Tests.Configuration;
|
||||
|
||||
namespace WpfExtended.Tests.Services
|
||||
{
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Http.Logging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Slim;
|
||||
using System;
|
||||
using System.Extensions;
|
||||
using System.Http;
|
||||
using System.Net.Http;
|
||||
using System.Windows.Extensions;
|
||||
using System.Windows.Extensions.Http;
|
||||
using WpfExtended.Test;
|
||||
using WpfExtended.Tests.Http;
|
||||
using WpfExtended.Tests.Services;
|
||||
|
||||
namespace WpfExtended.Tests
|
||||
@@ -15,22 +15,17 @@ namespace WpfExtended.Tests
|
||||
{
|
||||
private static Launcher Instance { get; } = new Launcher();
|
||||
|
||||
[STAThread]
|
||||
public static int Main()
|
||||
{
|
||||
return Instance.Run();
|
||||
}
|
||||
|
||||
protected override void SetupServiceManager(IServiceManager serviceManager)
|
||||
{
|
||||
serviceManager.RegisterDebugLoggerFactory();
|
||||
serviceManager.RegisterResolver(
|
||||
new HttpClientResolver()
|
||||
.WithHttpMessageHandlerFactory((sp, category) =>
|
||||
.WithHttpMessageHandlerFactory((serviceProvider, categoryType) =>
|
||||
{
|
||||
var loggerType = typeof(ILogger<>).MakeGenericType(category);
|
||||
var logger = sp.GetService(loggerType).As<ILogger>();
|
||||
return new HttpMessageLogger(logger, new HttpClientHandler());
|
||||
var loggerType = typeof(ILogger<>).MakeGenericType(categoryType);
|
||||
var logger = serviceProvider.GetService(loggerType).As<ILogger>();
|
||||
var handler = new LoggingHttpMessageHandler(logger) { InnerHandler = new HttpClientHandler() };
|
||||
return handler;
|
||||
}));
|
||||
serviceManager.RegisterOptionsManager();
|
||||
}
|
||||
@@ -1,12 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FlaUI.UIA3" Version="3.2.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.0.0-beta0001" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
|
||||
<PackageReference Include="Microsoft.TestPlatform" Version="16.10.0" />
|
||||
<PackageReference Include="Microsoft.TestPlatform.TestHost" Version="16.10.0" />
|
||||
<PackageReference Include="Moq" Version="4.16.1" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.4" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.2.4" />
|
||||
<PackageReference Include="SystemExtensions.NetStandard" Version="1.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
namespace System.Windows.Extensions
|
||||
{
|
||||
public sealed class DefaultOptionsManager : IOptionsManager
|
||||
{
|
||||
public T GetOptions<T>() where T : class
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
public void UpdateOptions<T>(T value) where T : class
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace System.Windows.Extensions
|
||||
{
|
||||
public interface ILiveOptions<T> : IOptions<T>
|
||||
where T : class
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace System.Windows.Extensions
|
||||
{
|
||||
public interface ILiveUpdateableOptions<T> : ILiveOptions<T>, IUpdateableOptions<T>
|
||||
where T : class
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace System.Windows.Extensions
|
||||
{
|
||||
public interface IOptionsManager
|
||||
{
|
||||
T GetOptions<T>()
|
||||
where T : class;
|
||||
void UpdateOptions<T>(T value)
|
||||
where T : class;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace System.Windows.Extensions
|
||||
{
|
||||
public interface IUpdateableOptions<out T> : IOptions<T>
|
||||
where T : class
|
||||
{
|
||||
/// <summary>
|
||||
/// Updates the configuration with the current value stored in <see cref="IOptions{TOptions}.Value"/>.
|
||||
/// </summary>
|
||||
void UpdateOption();
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Slim.Resolvers;
|
||||
|
||||
namespace System.Windows.Extensions
|
||||
{
|
||||
public sealed class LiveOptionsResolver : IDependencyResolver
|
||||
{
|
||||
private static readonly Type optionsType = typeof(LiveUpdateableOptionsWrapper<>);
|
||||
|
||||
public bool CanResolve(Type type)
|
||||
{
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ILiveOptions<>))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public object Resolve(Slim.IServiceProvider serviceProvider, Type type)
|
||||
{
|
||||
var typedOptionsType = optionsType.MakeGenericType(type.GetGenericArguments());
|
||||
var configurationManager = serviceProvider.GetService<IOptionsManager>();
|
||||
|
||||
return Activator.CreateInstance(typedOptionsType, configurationManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using Slim.Resolvers;
|
||||
|
||||
namespace System.Windows.Extensions
|
||||
{
|
||||
public sealed class LiveUpdateableOptionsResolver : IDependencyResolver
|
||||
{
|
||||
private static readonly Type optionsType = typeof(LiveUpdateableOptionsWrapper<>);
|
||||
|
||||
public bool CanResolve(Type type)
|
||||
{
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ILiveUpdateableOptions<>))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public object Resolve(Slim.IServiceProvider serviceProvider, Type type)
|
||||
{
|
||||
var typedOptionsType = optionsType.MakeGenericType(type.GetGenericArguments());
|
||||
var configurationManager = serviceProvider.GetService<IOptionsManager>();
|
||||
return Activator.CreateInstance(typedOptionsType, configurationManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using System.Extensions;
|
||||
|
||||
namespace System.Windows.Extensions
|
||||
{
|
||||
public sealed class LiveUpdateableOptionsWrapper<T> : ILiveUpdateableOptions<T>
|
||||
where T : class
|
||||
{
|
||||
private readonly IOptionsManager configurationManager;
|
||||
|
||||
private T value;
|
||||
|
||||
public T Value
|
||||
{
|
||||
get
|
||||
{
|
||||
this.value = this.configurationManager.GetOptions<T>();
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
public LiveUpdateableOptionsWrapper(IOptionsManager configurationManager)
|
||||
{
|
||||
this.configurationManager = configurationManager.ThrowIfNull(nameof(configurationManager));
|
||||
}
|
||||
|
||||
public void UpdateOption()
|
||||
{
|
||||
this.configurationManager.UpdateOptions<T>(this.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using Slim.Resolvers;
|
||||
|
||||
namespace System.Windows.Extensions
|
||||
{
|
||||
public sealed class OptionsResolver : IDependencyResolver
|
||||
{
|
||||
private static readonly Type optionsType = typeof(OptionsWrapper<>);
|
||||
private static readonly Type configurationType = typeof(IOptionsManager);
|
||||
|
||||
public bool CanResolve(Type type)
|
||||
{
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IOptions<>))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public object Resolve(Slim.IServiceProvider serviceProvider, Type type)
|
||||
{
|
||||
var typedOptionsType = optionsType.MakeGenericType(type.GetGenericArguments());
|
||||
var configurationManager = serviceProvider.GetService<IOptionsManager>();
|
||||
var optionsValue = configurationType
|
||||
.GetMethod(nameof(IOptionsManager.GetOptions))
|
||||
.MakeGenericMethod(type.GetGenericArguments())
|
||||
.Invoke(configurationManager, Array.Empty<object>());
|
||||
|
||||
return Activator.CreateInstance(typedOptionsType, optionsValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
using Slim.Resolvers;
|
||||
|
||||
namespace System.Windows.Extensions
|
||||
{
|
||||
public sealed class UpdateableOptionsResolver : IDependencyResolver
|
||||
{
|
||||
private static readonly Type optionsType = typeof(UpdateableOptionsWrapper<>);
|
||||
private static readonly Type configurationType = typeof(IOptionsManager);
|
||||
|
||||
public bool CanResolve(Type type)
|
||||
{
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IUpdateableOptions<>))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public object Resolve(Slim.IServiceProvider serviceProvider, Type type)
|
||||
{
|
||||
var typedOptionsType = optionsType.MakeGenericType(type.GetGenericArguments());
|
||||
var configurationManager = serviceProvider.GetService<IOptionsManager>();
|
||||
var optionsValue = configurationType
|
||||
.GetMethod(nameof(IOptionsManager.GetOptions))
|
||||
.MakeGenericMethod(type.GetGenericArguments())
|
||||
.Invoke(configurationManager, Array.Empty<object>());
|
||||
|
||||
return Activator.CreateInstance(typedOptionsType, configurationManager, optionsValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using System.Extensions;
|
||||
|
||||
namespace System.Windows.Extensions
|
||||
{
|
||||
public sealed class UpdateableOptionsWrapper<T> : IUpdateableOptions<T>
|
||||
where T : class
|
||||
{
|
||||
private readonly IOptionsManager configurationManager;
|
||||
|
||||
public T Value { get; }
|
||||
|
||||
public UpdateableOptionsWrapper(IOptionsManager configurationManager, T options)
|
||||
{
|
||||
this.configurationManager = configurationManager.ThrowIfNull(nameof(configurationManager));
|
||||
this.Value = options;
|
||||
}
|
||||
|
||||
public void UpdateOption()
|
||||
{
|
||||
this.configurationManager.UpdateOptions(this.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Slim;
|
||||
using System.Extensions;
|
||||
using System.Net.Http;
|
||||
using System.Windows.Extensions.Http;
|
||||
using WpfExtended.Logging;
|
||||
|
||||
namespace System.Windows.Extensions
|
||||
{
|
||||
public static class ServiceManagerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers a <see cref="IOptionsManager"/> with the default <see cref="DefaultOptionsManager"/>.
|
||||
/// This call also registers the resolver that resolves <see cref="IUpdateableOptions{T}"/> and <see cref="IOptions{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="serviceManager"><see cref="IServiceManager"/>.</param>
|
||||
/// <returns>Provided <see cref="IServiceManager"/>.</returns>
|
||||
public static IServiceManager RegisterOptionsManager(this IServiceManager serviceManager)
|
||||
{
|
||||
serviceManager.RegisterSingleton<IOptionsManager, DefaultOptionsManager>();
|
||||
serviceManager.RegisterOptionsResolver();
|
||||
|
||||
return serviceManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a <see cref="IOptionsManager"/>.
|
||||
/// This call also registers the resolver that resolves <see cref="IUpdateableOptions{T}"/> and <see cref="IOptions{T}"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Implementation of <see cref="IOptionsManager"/>.</typeparam>
|
||||
/// <param name="serviceManager"><see cref="IServiceManager"/>.</param>
|
||||
/// <returns>Provided <see cref="IServiceManager"/>.</returns>
|
||||
public static IServiceManager RegisterOptionsManager<T>(this IServiceManager serviceManager)
|
||||
where T : IOptionsManager
|
||||
{
|
||||
serviceManager.RegisterSingleton<IOptionsManager, T>();
|
||||
serviceManager.RegisterOptionsResolver();
|
||||
|
||||
return serviceManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers resolvers for <see cref="IOptions{TOptions}"/> and <see cref="IUpdateableOptions{T}"/>.
|
||||
/// Depends on a <see cref="IOptionsManager"/> in order to properly resolve options.
|
||||
/// </summary>
|
||||
/// <param name="serviceManager"><see cref="IServiceManager"/>.</param>
|
||||
/// <returns><see cref="IServiceManager"/>.</returns>
|
||||
public static IServiceManager RegisterOptionsResolver(this IServiceManager serviceManager)
|
||||
{
|
||||
serviceManager.ThrowIfNull(nameof(serviceManager));
|
||||
|
||||
serviceManager.RegisterResolver(new OptionsResolver());
|
||||
serviceManager.RegisterResolver(new UpdateableOptionsResolver());
|
||||
serviceManager.RegisterResolver(new LiveOptionsResolver());
|
||||
serviceManager.RegisterResolver(new LiveUpdateableOptionsResolver());
|
||||
|
||||
return serviceManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a <see cref="ILogsWriter"/> with the default <see cref="CVLoggerProvider"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TLogsWriter">Implementation of <see cref="ILogsWriter"/>.</typeparam>
|
||||
/// <param name="serviceManager"><see cref="IServiceProducer"/>.</param>
|
||||
/// <returns>Provided <see cref="IServiceProducer"/>.</returns>
|
||||
public static IServiceProducer RegisterLogWriter<TLogsWriter>(this IServiceProducer serviceManager)
|
||||
where TLogsWriter : ILogsWriter
|
||||
{
|
||||
serviceManager.ThrowIfNull(nameof(serviceManager));
|
||||
|
||||
serviceManager.RegisterSingleton<ILogsWriter, TLogsWriter>();
|
||||
serviceManager.RegisterScoped<ILoggerFactory, LoggerFactory>(sp =>
|
||||
{
|
||||
var factory = new LoggerFactory();
|
||||
factory.AddProvider(new CVLoggerProvider(sp.GetService<ILogsWriter>()));
|
||||
return factory;
|
||||
});
|
||||
|
||||
return serviceManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a <see cref="ILogsWriter"/> with the default <see cref="CVLoggerProvider"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TILogsWriter">Interface of <see cref="ILogsWriter"/>.</typeparam>
|
||||
/// <typeparam name="TLogsWriter">Implementation of <see cref="ILogsWriter"/>.</typeparam>
|
||||
/// <param name="serviceManager"><see cref="IServiceProducer"/>.</param>
|
||||
/// <returns>Provided <see cref="IServiceProducer"/>.</returns>
|
||||
public static IServiceProducer RegisterLogWriter<TILogsWriter, TLogsWriter>(this IServiceProducer serviceManager)
|
||||
where TLogsWriter : TILogsWriter
|
||||
where TILogsWriter : class, ILogsWriter
|
||||
{
|
||||
serviceManager.ThrowIfNull(nameof(serviceManager));
|
||||
|
||||
serviceManager.RegisterSingleton<TILogsWriter, TLogsWriter>();
|
||||
serviceManager.RegisterScoped<ILoggerFactory, LoggerFactory>(sp =>
|
||||
{
|
||||
var factory = new LoggerFactory();
|
||||
factory.AddProvider(new CVLoggerProvider(sp.GetService<TILogsWriter>()));
|
||||
return factory;
|
||||
});
|
||||
|
||||
return serviceManager;
|
||||
}
|
||||
|
||||
public static IServiceManager RegisterLoggerFactory(this IServiceManager serviceManager, Func<Slim.IServiceProvider, ILoggerFactory> loggerFactory)
|
||||
{
|
||||
serviceManager.ThrowIfNull(nameof(serviceManager));
|
||||
|
||||
serviceManager.RegisterSingleton<ILoggerFactory, ILoggerFactory>(loggerFactory);
|
||||
return serviceManager;
|
||||
}
|
||||
|
||||
public static IServiceManager RegisterDebugLoggerFactory(this IServiceManager serviceManager)
|
||||
{
|
||||
serviceManager.ThrowIfNull(nameof(serviceManager));
|
||||
|
||||
serviceManager.RegisterLogWriter<ILogsWriter, DebugLogsWriter>();
|
||||
return serviceManager;
|
||||
}
|
||||
|
||||
public static IServiceManager RegisterHttpFactory(this IServiceManager serviceManager)
|
||||
{
|
||||
serviceManager.ThrowIfNull(nameof(serviceManager));
|
||||
|
||||
serviceManager.RegisterResolver(new HttpClientResolver());
|
||||
return serviceManager;
|
||||
}
|
||||
|
||||
public static IServiceManager RegisterHttpFactory(this IServiceManager serviceManager, Func<Slim.IServiceProvider, Type, HttpMessageHandler> handlerFactory)
|
||||
{
|
||||
serviceManager.ThrowIfNull(nameof(serviceManager));
|
||||
|
||||
serviceManager.RegisterResolver(
|
||||
new HttpClientResolver()
|
||||
.WithHttpMessageHandlerFactory(handlerFactory));
|
||||
return serviceManager;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Slim.Resolvers;
|
||||
using System.Extensions;
|
||||
using System.Http;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace System.Windows.Extensions.Http
|
||||
{
|
||||
public sealed class HttpClientResolver : IDependencyResolver
|
||||
{
|
||||
private static readonly Type clientType = typeof(HttpClient<>);
|
||||
private static readonly Type loggerType = typeof(ILogger<>);
|
||||
|
||||
/// <summary>
|
||||
/// Factory method. <see cref="Type"/> parameter of the factory is the scope of <see cref="IHttpClient{TScope}"/>.
|
||||
/// </summary>
|
||||
public Func<Slim.IServiceProvider, Type, HttpMessageHandler> HttpMessageHandlerFactory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="HttpMessageHandlerFactory"/>.
|
||||
/// </summary>
|
||||
/// <param name="factory">Factory method. <see cref="Type"/> parameter of the factory is the scope of <see cref="IHttpClient{TScope}"/>.</param>
|
||||
/// <returns></returns>
|
||||
public HttpClientResolver WithHttpMessageHandlerFactory(Func<Slim.IServiceProvider, Type, HttpMessageHandler> factory)
|
||||
{
|
||||
this.HttpMessageHandlerFactory = factory;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool CanResolve(Type type)
|
||||
{
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IHttpClient<>))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public object Resolve(Slim.IServiceProvider serviceProvider, Type type)
|
||||
{
|
||||
var typedClientType = clientType.MakeGenericType(type.GetGenericArguments());
|
||||
var typedLoggerType = loggerType.MakeGenericType(type.GetGenericArguments());
|
||||
var logger = serviceProvider.GetService(typedLoggerType).As<ILogger>();
|
||||
var handler = this.HttpMessageHandlerFactory?.Invoke(serviceProvider, type.GetGenericArguments().First());
|
||||
var httpClient = handler is null ?
|
||||
Activator.CreateInstance(typedClientType) :
|
||||
Activator.CreateInstance(typedClientType, new object[] { handler });
|
||||
return httpClient;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Debug;
|
||||
using Slim;
|
||||
using System.Extensions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Extensions;
|
||||
using WpfExtended.Models;
|
||||
|
||||
namespace WpfExtended.Logging
|
||||
{
|
||||
public sealed class CVLogger : ILogger
|
||||
{
|
||||
private readonly string category;
|
||||
private readonly CVLoggerProvider cvLoggerProvider;
|
||||
|
||||
public CVLogger(string category, CVLoggerProvider debugLoggerProvider)
|
||||
{
|
||||
this.category = category;
|
||||
this.cvLoggerProvider = debugLoggerProvider.ThrowIfNull(nameof(debugLoggerProvider));
|
||||
}
|
||||
|
||||
public IDisposable BeginScope<TState>(TState state)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
|
||||
{
|
||||
var message = formatter(state, exception);
|
||||
|
||||
var log = new Log
|
||||
{
|
||||
Exception = exception,
|
||||
LogLevel = logLevel,
|
||||
EventId = eventId.Name,
|
||||
Message = message,
|
||||
Category = category,
|
||||
LogTime = DateTime.Now
|
||||
};
|
||||
|
||||
this.cvLoggerProvider.LogEntry(log);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
using Microsoft.CorrelationVector;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Extensions;
|
||||
using WpfExtended.Models;
|
||||
|
||||
namespace WpfExtended.Logging
|
||||
{
|
||||
public sealed class CVLoggerProvider : ILoggerProvider
|
||||
{
|
||||
private readonly ILogsWriter logsManager;
|
||||
private CorrelationVector correlationVector;
|
||||
|
||||
public CVLoggerProvider(ILogsWriter logsWriter)
|
||||
{
|
||||
this.logsManager = logsWriter.ThrowIfNull(nameof(logsWriter));
|
||||
this.correlationVector = new CorrelationVector();
|
||||
}
|
||||
|
||||
public void LogEntry(Log log)
|
||||
{
|
||||
if (this.correlationVector is not null)
|
||||
{
|
||||
log.CorrelationVector = this.correlationVector.Value.ToString();
|
||||
this.correlationVector.Increment();
|
||||
}
|
||||
|
||||
this.logsManager.WriteLog(log);
|
||||
}
|
||||
|
||||
public ILogger CreateLogger(string categoryName)
|
||||
{
|
||||
if (this.correlationVector is not null)
|
||||
{
|
||||
this.correlationVector = CorrelationVector.Extend(this.correlationVector.ToString());
|
||||
}
|
||||
|
||||
return new CVLogger(categoryName, this);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using WpfExtended.Models;
|
||||
|
||||
namespace WpfExtended.Logging
|
||||
{
|
||||
public sealed class DebugLogsWriter : ILogsWriter
|
||||
{
|
||||
public void WriteLog(Log log)
|
||||
{
|
||||
Debug.WriteLine($"{log.LogTime} - {log.Category} - {log.EventId} - {log.CorrelationVector} - {log.LogLevel} - {log.Message}{Environment.NewLine}{log.Exception}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using WpfExtended.Models;
|
||||
|
||||
namespace WpfExtended.Logging
|
||||
{
|
||||
public interface ILogsWriter
|
||||
{
|
||||
void WriteLog(Log log);
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Slim.Resolvers;
|
||||
using System.Linq;
|
||||
|
||||
namespace System.Windows.Extensions.Logging
|
||||
{
|
||||
public sealed class LoggerResolver : IDependencyResolver
|
||||
{
|
||||
public bool CanResolve(Type type)
|
||||
{
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ILogger<>) ||
|
||||
type == typeof(ILogger))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public object Resolve(Slim.IServiceProvider serviceProvider, Type type)
|
||||
{
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ILogger<>))
|
||||
{
|
||||
return ResolveScopedLogger(serviceProvider, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ResolveLogger(serviceProvider, type);
|
||||
}
|
||||
}
|
||||
|
||||
private static object ResolveScopedLogger(Slim.IServiceProvider serviceProvider, Type type)
|
||||
{
|
||||
var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
|
||||
var categoryTypes = type.GetGenericArguments();
|
||||
var createLoggerMethod = typeof(LoggerFactoryExtensions).GetMethods().Where(m => m.IsGenericMethodDefinition && m.Name == nameof(LoggerFactoryExtensions.CreateLogger)).First();
|
||||
return createLoggerMethod.MakeGenericMethod(categoryTypes.First()).Invoke(null, new object[] { loggerFactory });
|
||||
}
|
||||
|
||||
private static object ResolveLogger(Slim.IServiceProvider serviceProvider, Type type)
|
||||
{
|
||||
var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
|
||||
return loggerFactory.CreateLogger(string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
|
||||
namespace WpfExtended.Models
|
||||
{
|
||||
public sealed record Log
|
||||
{
|
||||
public Exception Exception { get; set; }
|
||||
public DateTime LogTime { get; set; }
|
||||
public string Category { get; set; }
|
||||
public string EventId { get; set; }
|
||||
public LogLevel LogLevel { get; set; }
|
||||
public string Message { get; set; }
|
||||
public string CorrelationVector { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
||||
<PackageLicenseFile>License.txt</PackageLicenseFile>
|
||||
<Version>0.5</Version>
|
||||
<Version>0.6</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Description>Extension library for Windows Presentation Platform.
|
||||
|
||||
@@ -86,8 +86,9 @@ http://www.java2s.com/Open-Source/CSharp_Free_Code/Windows_Presentation_Foundati
|
||||
<PackageReference Include="Microsoft.CorrelationVector" Version="1.0.42" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="5.0.0" />
|
||||
<PackageReference Include="Slim" Version="1.5.0" />
|
||||
<PackageReference Include="Slim" Version="1.5.1" />
|
||||
<PackageReference Include="SystemExtensions.NetStandard" Version="1.3.0" />
|
||||
<PackageReference Include="SystemExtensions.NetStandard.DependencyInjection" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
<Import Project="ShaderCompiler.target" />
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user