fix: avoid journal service webapi explorer dependency

This commit is contained in:
Meik
2026-07-01 00:29:04 +02:00
parent 587a38b149
commit 1e3ec1cc22
3 changed files with 99 additions and 2 deletions

View File

@@ -96,6 +96,103 @@ namespace C4IT.F4SD
return GetRequiredService<IJournalService>();
}
internal object GetJournalServiceInstance()
{
try
{
return GetRequiredService<IJournalService>();
}
catch (Exception ex)
{
LogEntry($"IJournalService could not be resolved by the Matrix42 container. Falling back to direct JournalService construction. {ex.GetType().FullName}: {ex.Message}", LogLevels.Warning);
return CreateJournalServiceInstance();
}
}
private object CreateJournalServiceInstance()
{
var journalServiceType = FindLoadedType("Matrix42.ServiceManager.BizLogic.Services.JournalService")
?? Type.GetType("Matrix42.ServiceManager.BizLogic.Services.JournalService, Matrix42.ServiceManager.BizLogic", true);
var constructor = journalServiceType
.GetConstructors()
.OrderByDescending(item => item.GetParameters().Length)
.FirstOrDefault();
if (constructor == null)
throw new InvalidOperationException($"No public constructor was found for {journalServiceType.FullName}.");
var parameters = constructor.GetParameters();
var arguments = new object[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
arguments[i] = ResolveJournalServiceConstructorParameter(parameters[i]);
return constructor.Invoke(arguments);
}
private object ResolveJournalServiceConstructorParameter(System.Reflection.ParameterInfo parameter)
{
if (parameter.ParameterType == typeof(IDependencyResolver))
return _resolver;
if (parameter.ParameterType.FullName == "Matrix42.Contracts.Platform.MsTeams.ITeamsNotificationService")
return CreateNoOpInterfaceProxy(parameter.ParameterType);
var service = _resolver.TryGet(parameter.ParameterType);
if (service != null)
return service;
throw new InvalidOperationException($"Required JournalService constructor dependency is not registered: {parameter.ParameterType.FullName} ({parameter.Name}).");
}
private static Type FindLoadedType(string fullName)
{
return AppDomain.CurrentDomain
.GetAssemblies()
.Select(assembly => assembly.GetType(fullName, false))
.FirstOrDefault(type => type != null);
}
private static object CreateNoOpInterfaceProxy(Type interfaceType)
{
var createMethod = typeof(DispatchProxy)
.GetMethods(BindingFlags.Public | BindingFlags.Static)
.Single(method => method.Name == nameof(DispatchProxy.Create) && method.IsGenericMethodDefinition);
return createMethod
.MakeGenericMethod(interfaceType, typeof(NoOpInterfaceProxy))
.Invoke(null, null);
}
private sealed class NoOpInterfaceProxy : DispatchProxy
{
protected override object Invoke(MethodInfo targetMethod, object[] args)
{
return GetDefaultValue(targetMethod?.ReturnType);
}
}
private static object GetDefaultValue(Type returnType)
{
if (returnType == null || returnType == typeof(void))
return null;
if (returnType == typeof(Task))
return Task.CompletedTask;
if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>))
{
var resultType = returnType.GetGenericArguments()[0];
var result = resultType.IsValueType ? Activator.CreateInstance(resultType) : null;
return typeof(Task)
.GetMethods(BindingFlags.Public | BindingFlags.Static)
.Single(method => method.Name == nameof(Task.FromResult) && method.IsGenericMethodDefinition)
.MakeGenericMethod(resultType)
.Invoke(null, new[] { result });
}
return returnType.IsValueType ? Activator.CreateInstance(returnType) : null;
}
[Route("getDirectLinkCreateTicket"), HttpGet]
public async Task<F4SDHelperService.DirectLink> getDirectLinkCreateTicket(string sid = "", string assetname = "")
{