127 lines
3.8 KiB
C#
127 lines
3.8 KiB
C#
using Serilog;
|
|
using Splat;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace SPTInstaller.Helpers;
|
|
|
|
/// <summary>
|
|
/// A helper class to handle simple service registration to Splat with constructor parameter injection
|
|
/// </summary>
|
|
/// <remarks>Splat only recognizes the registered types and doesn't account for interfaces :(</remarks>
|
|
internal static class ServiceHelper
|
|
{
|
|
private static bool TryRegisterInstance<T, T2>(object[] parameters = null)
|
|
{
|
|
var instance = Activator.CreateInstance(typeof(T2), parameters);
|
|
|
|
if (instance != null)
|
|
{
|
|
Locator.CurrentMutable.RegisterConstant<T>((T)instance);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register a class as a service
|
|
/// </summary>
|
|
/// <typeparam name="T">class to register</typeparam>
|
|
public static void Register<T>() where T : class => Register<T, T>();
|
|
|
|
/// <summary>
|
|
/// Register a class as a service by another type
|
|
/// </summary>
|
|
/// <typeparam name="T">type to register as</typeparam>
|
|
/// <typeparam name="T2">class to register</typeparam>
|
|
public static void Register<T, T2>() where T : class
|
|
{
|
|
var constructors = typeof(T2).GetConstructors();
|
|
|
|
foreach (var constructor in constructors)
|
|
{
|
|
var parmesan = constructor.GetParameters();
|
|
|
|
if (parmesan.Length == 0)
|
|
{
|
|
if (TryRegisterInstance<T, T2>()) return;
|
|
|
|
continue;
|
|
}
|
|
|
|
List<object> parameters = new List<object>();
|
|
|
|
for (int i = 0; i < parmesan.Length; i++)
|
|
{
|
|
var parm = parmesan[i];
|
|
|
|
var parmValue = Get(parm.ParameterType);
|
|
|
|
if (parmValue != null) parameters.Add(parmValue);
|
|
}
|
|
|
|
if (TryRegisterInstance<T, T2>(parameters.ToArray())) return;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a service from splat
|
|
/// </summary>
|
|
/// <param name="type"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="InvalidOperationException">Thrown if the service isn't found</exception>
|
|
public static object Get(Type type)
|
|
{
|
|
var service = Locator.Current.GetService(type);
|
|
|
|
if (service == null)
|
|
{
|
|
var message = $"Could not locate service of type '{type.Name}'";
|
|
Log.Error(message);
|
|
throw new InvalidOperationException(message);
|
|
}
|
|
|
|
return service;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a service from splat
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
/// <exception cref="InvalidOperationException">Thrown if the service isn't found</exception>
|
|
public static T Get<T>()
|
|
{
|
|
var service = Locator.Current.GetService<T>();
|
|
|
|
if (service == null)
|
|
{
|
|
var message = $"Could not locate service of type '{nameof(T)}'";
|
|
Log.Error(message);
|
|
throw new InvalidOperationException(message);
|
|
}
|
|
|
|
return service;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get all services of a type
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
/// <exception cref="InvalidOperationException">thrown if no services are found</exception>
|
|
public static T[] GetAll<T>()
|
|
{
|
|
var services = Locator.Current.GetServices<T>().ToArray();
|
|
|
|
if (services == null || services.Count() == 0)
|
|
{
|
|
var message = $"Could not locate service of type '{nameof(T)}'";
|
|
Log.Error(message);
|
|
throw new InvalidOperationException(message);
|
|
}
|
|
|
|
return services;
|
|
}
|
|
} |