Add project files.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user