diff --git a/F4SDM42WebApi/F4SD - M42WebApi.csproj b/F4SDM42WebApi/F4SD - M42WebApi.csproj
index 40a3eca..632e8ee 100644
--- a/F4SDM42WebApi/F4SD - M42WebApi.csproj
+++ b/F4SDM42WebApi/F4SD - M42WebApi.csproj
@@ -13,7 +13,7 @@
false
6673a25d-33d6-4072-91d9-abed4be1a966
C4ITF4SD*.*
- 1.4.0.28
+ 1.4.0.29
true
diff --git a/F4SDM42WebApi/F4SDM42WebApiController.cs b/F4SDM42WebApi/F4SDM42WebApiController.cs
index 148e42c..0d72fe5 100644
--- a/F4SDM42WebApi/F4SDM42WebApiController.cs
+++ b/F4SDM42WebApi/F4SDM42WebApiController.cs
@@ -43,6 +43,8 @@ namespace C4IT.F4SD
private readonly F4SDHelperService _f4stHelperService;
+ private const string TeamsNotificationServiceTypeName = "Matrix42.Contracts.Platform.MsTeams.ITeamsNotificationService";
+ private const string StorageServiceTypeName = "Matrix42.StorageService.Contracts.IStorageService";
public string BaseUrl => Request?.RequestUri == null ? string.Empty : $"{Request.RequestUri.Scheme}://{Request.RequestUri.Host}";
public string EndpointBaseUrl => $"{BaseUrl}/m42Services/api/c4itf4sdwebapi";
@@ -132,9 +134,9 @@ namespace C4IT.F4SD
private object ResolveJournalServiceConstructorParameter(System.Reflection.ParameterInfo parameter)
{
if (parameter.ParameterType == typeof(IDependencyResolver))
- return _resolver;
+ return CreateJournalDependencyResolver(_resolver);
- if (parameter.ParameterType.FullName == "Matrix42.Contracts.Platform.MsTeams.ITeamsNotificationService")
+ if (parameter.ParameterType.FullName == TeamsNotificationServiceTypeName || parameter.ParameterType.FullName == StorageServiceTypeName)
return CreateNoOpInterfaceProxy(parameter.ParameterType);
var service = _resolver.TryGet(parameter.ParameterType);
@@ -144,6 +146,13 @@ namespace C4IT.F4SD
throw new InvalidOperationException($"Required JournalService constructor dependency is not registered: {parameter.ParameterType.FullName} ({parameter.Name}).");
}
+ private static IDependencyResolver CreateJournalDependencyResolver(IDependencyResolver resolver)
+ {
+ var proxy = DispatchProxy.Create();
+ ((JournalDependencyResolverProxy)(object)proxy).Inner = resolver;
+ return proxy;
+ }
+
private static Type FindLoadedType(string fullName)
{
return AppDomain.CurrentDomain
@@ -163,6 +172,57 @@ namespace C4IT.F4SD
.Invoke(null, null);
}
+ public class JournalDependencyResolverProxy : DispatchProxy
+ {
+ public IDependencyResolver Inner { get; set; }
+
+ protected override object Invoke(MethodInfo targetMethod, object[] args)
+ {
+ var requestedType = GetRequestedServiceType(targetMethod, args);
+ if (requestedType?.FullName == StorageServiceTypeName)
+ return CreateResolverResultForStorageService(targetMethod, requestedType);
+
+ try
+ {
+ return targetMethod.Invoke(Inner, args);
+ }
+ catch (TargetInvocationException ex) when (ex.InnerException != null)
+ {
+ throw ex.InnerException;
+ }
+ }
+ }
+
+ private static Type GetRequestedServiceType(MethodInfo targetMethod, object[] args)
+ {
+ if (targetMethod.IsGenericMethod && targetMethod.GetGenericArguments().Length > 0)
+ return targetMethod.GetGenericArguments()[0];
+
+ if (args?.Length > 0 && args[0] is Type type)
+ return type;
+
+ return null;
+ }
+
+ private static object CreateResolverResultForStorageService(MethodInfo targetMethod, Type requestedType)
+ {
+ if (targetMethod.Name.StartsWith("IsRegistered", StringComparison.Ordinal))
+ return true;
+
+ if (targetMethod.Name.Contains("All"))
+ return CreateEmptyEnumerable(targetMethod.ReturnType, requestedType);
+
+ return CreateNoOpInterfaceProxy(requestedType);
+ }
+
+ private static object CreateEmptyEnumerable(Type returnType, Type itemType)
+ {
+ if (returnType.IsGenericType)
+ return Array.CreateInstance(returnType.GetGenericArguments()[0], 0);
+
+ return Array.CreateInstance(itemType ?? typeof(object), 0);
+ }
+
public class NoOpInterfaceProxy : DispatchProxy
{
public NoOpInterfaceProxy()