fix: isolate journal storage dependency in sandbox
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<M42ExtensionId>6673a25d-33d6-4072-91d9-abed4be1a966</M42ExtensionId>
|
||||
<M42AssemblyPattern>C4ITF4SD*.*</M42AssemblyPattern>
|
||||
<M42PackageVersion>1.4.0.28</M42PackageVersion>
|
||||
<M42PackageVersion>1.4.0.29</M42PackageVersion>
|
||||
<M42BuildPackage>true</M42BuildPackage>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -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<IDependencyResolver, JournalDependencyResolverProxy>();
|
||||
((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()
|
||||
|
||||
Reference in New Issue
Block a user