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

@@ -13,7 +13,7 @@
<EnableDefaultCompileItems>false</EnableDefaultCompileItems> <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<M42ExtensionId>6673a25d-33d6-4072-91d9-abed4be1a966</M42ExtensionId> <M42ExtensionId>6673a25d-33d6-4072-91d9-abed4be1a966</M42ExtensionId>
<M42AssemblyPattern>C4ITF4SD*.*</M42AssemblyPattern> <M42AssemblyPattern>C4ITF4SD*.*</M42AssemblyPattern>
<M42PackageVersion>1.4.0.26</M42PackageVersion> <M42PackageVersion>1.4.0.27</M42PackageVersion>
<M42BuildPackage>true</M42BuildPackage> <M42BuildPackage>true</M42BuildPackage>
</PropertyGroup> </PropertyGroup>

View File

@@ -1448,7 +1448,7 @@ namespace C4IT.F4SD
private static IReadOnlyList<Matrix42.Contracts.Platform.Data.JournalEntryInfo> LoadJournalEntries(Guid activityEOID) private static IReadOnlyList<Matrix42.Contracts.Platform.Data.JournalEntryInfo> LoadJournalEntries(Guid activityEOID)
{ {
var journalService = F4SDM42WebApiController.defaultInstance.GetJournalService(); var journalService = F4SDM42WebApiController.defaultInstance.GetJournalServiceInstance();
var serviceType = journalService.GetType(); var serviceType = journalService.GetType();
var objectLinkTemplate = "<a href=\"#\" class=\"mx-object-journal--link {0} {1}\">{2}</a>"; var objectLinkTemplate = "<a href=\"#\" class=\"mx-object-journal--link {0} {1}\">{2}</a>";
var methods = serviceType var methods = serviceType

View File

@@ -96,6 +96,103 @@ namespace C4IT.F4SD
return GetRequiredService<IJournalService>(); 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] [Route("getDirectLinkCreateTicket"), HttpGet]
public async Task<F4SDHelperService.DirectLink> getDirectLinkCreateTicket(string sid = "", string assetname = "") public async Task<F4SDHelperService.DirectLink> getDirectLinkCreateTicket(string sid = "", string assetname = "")
{ {