Add project files.

This commit is contained in:
Daniel Clark
2022-11-01 15:26:08 +00:00
parent daa7b59f22
commit 7e4f880821
408 changed files with 16863 additions and 0 deletions
@@ -0,0 +1,14 @@
using System.IO;
using System.Reflection;
namespace TheXamlGuy.Framework.Core
{
public static class AssemblyExtensions
{
public static Stream? ExtractResource(this Assembly assembly, string filename)
{
string? resourceName = $"{assembly.GetName()?.Name?.Replace("-", "_")}.{filename}";
return assembly.GetManifestResourceStream(resourceName);
}
}
}
@@ -0,0 +1,15 @@
using System.Collections.Generic;
namespace TheXamlGuy.Framework.Core
{
public static class ICollectionExtensions
{
public static void AddRange<T>(this ICollection<T> target, IEnumerable<T> source)
{
foreach (T item in source)
{
target.Add(item);
}
}
}
}
@@ -0,0 +1,13 @@
using System;
namespace TheXamlGuy.Framework.Core
{
public static class IDisposableExtensions
{
public static T Dispose<T>(this T target) where T : IDisposable
{
target.Dispose();
return target;
}
}
}
@@ -0,0 +1,10 @@
namespace TheXamlGuy.Framework.Core.Extensions
{
public static class IDisposerExtensions
{
public static void Add(this IDisposer disposer, object subject, IEnumerable<IDisposable> disposers)
{
disposer.Add(subject, disposers.ToArray());
}
}
}
@@ -0,0 +1,26 @@
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Reflection;
namespace TheXamlGuy.Framework.Core;
public static class IEventAggregatorExtensions
{
public static IDisposable Subscribe<TEvent>(this IEventAggregator eventAggregator, Action<TEvent> onNext, IScheduler? scheduler = null, Func<TEvent, bool>? where = null)
{
scheduler ??= Scheduler.Default;
where ??= x => true;
return eventAggregator.GetEvent<TEvent>().Where(where).ObserveOn(scheduler).WeakSubscribe(eventAggregator.Invoker, onNext);
}
public static IDisposable SubscribeUI<TEvent>(this IEventAggregator eventAggregator, Action<TEvent> onNext, Func<TEvent, bool>? where = null)
{
return eventAggregator.Subscribe(onNext, eventAggregator.Dispatcher, where);
}
public static void Publish<TEvent>(this IEventAggregator eventAggregator) where TEvent : new()
{
eventAggregator.Publish(new TEvent());
}
}
@@ -0,0 +1,37 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace TheXamlGuy.Framework.Core
{
public static class IHostBuilderExtensions
{
public static IHostBuilder UseContentRoot(this IHostBuilder hostBuilder, string contentRoot, bool createDirectory)
{
if (!Directory.Exists(contentRoot) && createDirectory)
{
Directory.CreateDirectory(contentRoot);
}
return hostBuilder.UseContentRoot(contentRoot);
}
public static IHostBuilder ConfigureEvents(this IHostBuilder hostBuilder, Action<IEventBuilder> builderDelegate)
{
hostBuilder.ConfigureServices((hostBuilderContext, serviceCollection) =>
{
EventBuilder? builder = new();
builderDelegate?.Invoke(builder);
foreach (IEventBuilderConfiguration? configuration in builder.Configurations)
{
Type? type = configuration.GetType().GetGenericArguments()[0];
serviceCollection.AddSingleton(typeof(IEventBuilderConfiguration<>).MakeGenericType(type), configuration);
serviceCollection.AddSingleton(typeof(EventHandler<>).MakeGenericType(type));
}
});
return hostBuilder;
}
}
}
@@ -0,0 +1,12 @@
namespace TheXamlGuy.Framework.Core
{
public interface IMediatorAsyncHandler<TRequest>
{
Task Handle(TRequest request, CancellationToken cancellationToken = default);
}
public interface IMediatorAsyncHandler<TResponse, TRequest>
{
Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken = default);
}
}
@@ -0,0 +1,27 @@
using System.Threading.Tasks;
namespace TheXamlGuy.Framework.Core
{
public static class IMediatorExtensions
{
public static void Handle<TEvent>(this IMediator mediator) where TEvent : new()
{
mediator.Handle(new TEvent());
}
public static TResponse? Handle<TResponse, TRequest>(this IMediator mediator, params object[] parameters) where TRequest : new()
{
return mediator.Handle<TResponse?>(new TRequest(), parameters);
}
public static Task HandleAsync<TEvent>(this IMediator mediator) where TEvent : new()
{
return mediator.HandleAsync(new TEvent());
}
public static Task<TResponse?> HandleAsync<TResponse, TRequest>(this IMediator mediator, params object[] parameters) where TRequest : new()
{
return mediator.HandleAsync<TResponse?>(new TRequest(), parameters);
}
}
}
@@ -0,0 +1,12 @@
namespace TheXamlGuy.Framework.Core
{
public interface IMediatorHandler<TRequest>
{
void Handle(TRequest request);
}
public interface IMediatorHandler<TResponse, TRequest>
{
TResponse Handle(TRequest request);
}
}
@@ -0,0 +1,29 @@
using System;
using System.Reflection;
namespace TheXamlGuy.Framework.Core
{
public static class IObservableExtensions
{
public static IDisposable WeakSubscribe<TEvent>(this IObservable<TEvent> observable, IEventAggregatorInvoker invoker, Action<TEvent> onNext)
{
MethodInfo methodInfo = onNext.Method;
WeakReference weakReference = new(onNext.Target);
IDisposable? subscription = null;
subscription = observable.Subscribe(item =>
{
if (weakReference.Target is object target)
{
invoker.Invoke(target, item, methodInfo);
}
else
{
subscription?.Dispose();
}
});
return subscription;
}
}
}
@@ -0,0 +1,103 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.Reflection;
namespace TheXamlGuy.Framework.Core
{
public static class IServiceCollectionExtensions
{
public static IServiceCollection AddConfiguration<TConfiguration>(this IServiceCollection serviceCollection, IConfiguration configuration) where TConfiguration : class, new()
{
serviceCollection.Configure<TConfiguration>(configuration);
serviceCollection.AddTransient(provider => provider.GetService<IOptionsMonitor<TConfiguration>>()!.CurrentValue);
serviceCollection.AddTransient<ConfigurationInitializer<TConfiguration>>();
return serviceCollection;
}
public static IServiceCollection AddCreatable<TService, TImplementation>(this IServiceCollection services)
{
return services.AddSingleton(typeof(IServiceCreator<>).MakeGenericType(typeof(TService)), typeof(ServiceCreator<,>).MakeGenericType(typeof(TService), typeof(TImplementation)));
}
public static IServiceCollection AddCreatable(this IServiceCollection services, Type serviceType, Type implementationType)
{
return services.AddSingleton(typeof(IServiceCreator<>).MakeGenericType(serviceType), typeof(ServiceCreator<,>).MakeGenericType(serviceType, implementationType));
}
public static IServiceCollection AddCreatableSingleton(this IServiceCollection services, Type serviceType, Type implementationType)
{
services.AddSingleton(serviceType, implementationType);
services.AddCreatable(serviceType, implementationType);
return services;
}
public static IServiceCollection AddCreatableTransient(this IServiceCollection services, Type serviceType, Type implementationType)
{
services.AddTransient(serviceType, implementationType);
services.AddCreatable(serviceType, implementationType);
return services;
}
public static IServiceCollection AddReqiredCore(this IServiceCollection services)
{
return services
.AddSingleton<IServiceFactory>(provider => new ServiceFactory(provider.GetService, (type, parameters) => ActivatorUtilities.CreateInstance(provider, type, parameters!)))
.AddSingleton<IDisposer, Disposer>()
.AddSingleton<IEventAggregator, EventAggregator>()
.AddSingleton<IEventAggregatorInvoker, EventAggregatorInvoker>()
.AddSingleton<IMediator, Mediator>()
.AddSingleton<IScope, Scope>()
.AddTransient<IPropertyBinderCollection, PropertyBinderCollection>()
.AddTransient<IPropertyBuilder, PropertyBuilder>()
.AddSingleton<IInitialization, Initialization>(provider => new Initialization(() =>
{
return services.Where(x => x.ServiceType.GetInterfaces()
.Contains(typeof(IInitializer)) || x.ServiceType == typeof(IInitializer))
.GroupBy(x => x.ServiceType)
.Select(x => x.First())
.SelectMany(x => provider.GetServices(x.ServiceType)
.Select(x => (IInitializer?)x)).ToList();
}))
.RegisterHandlers();
}
public static IServiceCollection AddWritableConfiguration<TConfiguration>(this IServiceCollection serviceCollection, IConfiguration configuration) where TConfiguration : class, new()
{
serviceCollection.Configure<TConfiguration>(configuration);
serviceCollection.AddTransient<IConfigurationWriter<TConfiguration>, ConfigurationWriter<TConfiguration>>();
serviceCollection.AddTransient(provider => provider.GetService<IOptionsMonitor<TConfiguration>>()!.CurrentValue);
serviceCollection.AddTransient<IMediatorHandler<Write<TConfiguration>>, WriteHandler<TConfiguration>>();
serviceCollection.AddTransient<ConfigurationInitializer<TConfiguration>>();
return serviceCollection;
}
public static IServiceCollection RegisterHandlers(this IServiceCollection services, params Assembly[] assemblies)
{
foreach (Tuple<Type, Type> item in GetImplementations(assemblies.Append(Assembly.GetCallingAssembly()), "Handler", typeof(IMediatorHandler<>), typeof(IMediatorHandler<,>), typeof(IMediatorAsyncHandler<>), typeof(IMediatorAsyncHandler<,>)))
{
if (!item.Item2.GetConstructors().Any(x => x.IsPublic))
{
continue;
}
services.AddCreatableTransient(item.Item1, item.Item2);
}
return services;
}
private static IEnumerable<Tuple<Type, Type>> GetImplementations(IEnumerable<Assembly> assemblies, string endsWith, params Type[] interfaces)
{
return assemblies.Distinct().SelectMany(a => a.GetTypes())
.Where(impl => impl.IsClass && impl.IsPublic && !impl.IsAbstract && impl.Name.EndsWith(endsWith))
.SelectMany(impl => impl.GetInterfaces(), (impl, iface) => new { impl, iface })
.Where(i => i.iface.IsGenericType && interfaces.Contains(i.iface.GetGenericTypeDefinition()))
.Select(x => Tuple.Create(x.iface, x.impl));
}
}
}
@@ -0,0 +1,21 @@
namespace TheXamlGuy.Framework.Core
{
public static class IServiceFactoryExtensions
{
public static T? Get<T>(this IServiceFactory serviceFactory)
{
return serviceFactory.Get<T>(typeof(T));
}
public static T Create<T>(this IServiceFactory serviceFactory, params object?[] parameters)
{
return serviceFactory.Create<T>(typeof(T), parameters);
}
public static object? Create(this IServiceFactory serviceFactory, Type type)
{
ServiceFactoryDescriptor? descriptor = new(serviceFactory);
return descriptor.Create(type);
}
}
}
@@ -0,0 +1,21 @@
using System;
namespace TheXamlGuy.Framework.Core
{
public static class StringExtensions
{
public static int CountSubstring(this string text, string textToMatch, StringComparison stringComparison)
{
int count = 0;
int minIndex = text.IndexOf(textToMatch, 0, stringComparison);
while (minIndex != -1)
{
minIndex = text.IndexOf(textToMatch, minIndex + textToMatch.Length, stringComparison);
count++;
}
return count;
}
}
}