Skip to content

Commit

Permalink
Make System.Transactions.Local trimmable on Windows
Browse files Browse the repository at this point in the history
Add the necessary DynamicDependency attributes to System.Transaction.Local in order for it to work with trimming on Windows. Also fix the UnconditionalSuppressMessage attribute to have a valid justification for suppressing, now that we are preserving the necessary interfaces for COM Interop.

Fix dotnet#75031
  • Loading branch information
eerhardt committed Sep 8, 2022
1 parent 21a0ff3 commit 0f7ce68
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)</TargetFrameworks>
<NoWarn>CA1805;IDE0059;CS1591</NoWarn>
<TargetPlatformIdentifier>$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)'))</TargetPlatformIdentifier>
<IsTrimmable Condition="'$(TargetPlatformIdentifier)' == 'windows'">false</IsTrimmable>
</PropertyGroup>
<ItemGroup>
<Compile Include="System\Transactions\CommittableTransaction.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,28 @@ private static extern void DtcGetTransactionManagerExW(
object? pvConfigPararms,
[MarshalAs(UnmanagedType.Interface)] out ITransactionDispenser ppvObject);

[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2050:COMMarshalling",
Justification = "The DynamicDependency attributes ensure the necessary IL is preserved.")]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransactionDispenser))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransactionOptions))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransaction))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITmNodeName))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransactionImportWhereabouts))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(IResourceManagerFactory2))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(IResourceManagerSink))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(IResourceManager))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransactionResourceAsync))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransactionEnlistmentAsync))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransactionImport))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransactionExportFactory))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransactionExport))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransactionVoterFactory2))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransactionVoterNotifyAsync2))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransactionVoterBallotAsync2))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransactionTransmitterFactory))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransactionTransmitter))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransactionReceiverFactory))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ITransactionReceiver))]
public void ConnectToProxy(
string? nodeName,
Guid resourceManagerIdentifier,
Expand All @@ -62,7 +84,7 @@ public void ConnectToProxy(

lock (_proxyInitLock)
{
DtcGetTransactionManagerExWLocal(nodeName, null, Guids.IID_ITransactionDispenser_Guid, 0, null, out ITransactionDispenser? localDispenser);
DtcGetTransactionManagerExW(nodeName, null, Guids.IID_ITransactionDispenser_Guid, 0, null, out ITransactionDispenser? localDispenser);

// Check to make sure the node name matches.
if (nodeName is not null)
Expand Down Expand Up @@ -116,13 +138,6 @@ public void ConnectToProxy(
resourceManagerShim = rmShim;
_transactionDispenser = localDispenser;
whereabouts = tmpWhereabouts;

[UnconditionalSuppressMessage("Trimming", "IL2050",
Justification = "The PInvoke has object/interface typed parameters which are potentially trim incompatible, but in this case they're OK")]
static void DtcGetTransactionManagerExWLocal(string? pszHost, string? pszTmName, in Guid riid, int grfOptions, object? pvConfigPararms, out ITransactionDispenser ppvObject)
{
DtcGetTransactionManagerExW(pszHost, pszTmName, riid, grfOptions, pvConfigPararms, out ppvObject);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -573,15 +573,15 @@ internal void EnlistmentCreated(TraceSourceType traceSource, EnlistmentTraceIden
}

[Event(ENLISTMENT_CREATED_LTM_EVENTID, Keywords = Keywords.TraceLtm, Level = EventLevel.Informational, Task = Tasks.Enlistment, Opcode = Opcodes.Create, Message = "Enlistment Created (LTM). ID is {0}, type is {1}, options is {2}")]
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026", Justification = "Only string/int are passed")]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Only string/int are passed")]
private void EnlistmentCreatedLtm(int enlistmentIdentifier, string enlistmentType, string enlistmentOptions)
{
SetActivityId(string.Empty);
WriteEvent(ENLISTMENT_CREATED_LTM_EVENTID, enlistmentIdentifier, enlistmentType, enlistmentOptions);
}

[Event(ENLISTMENT_CREATED_OLETX_EVENTID, Keywords = Keywords.TraceOleTx, Level = EventLevel.Informational, Task = Tasks.Enlistment, Opcode = Opcodes.Create, Message = "Enlistment Created (OLETX). ID is {0}, type is {1}, options is {2}")]
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026", Justification = "Only string/int are passed")]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Only string/int are passed")]
private void EnlistmentCreatedOleTx(int enlistmentIdentifier, string enlistmentType, string enlistmentOptions)
{
SetActivityId(string.Empty);
Expand Down

0 comments on commit 0f7ce68

Please sign in to comment.