Use reflection or a compile-time only shim assembly to reference unexposed corelib...
authorJeremy Koritzinsky <jekoritz@microsoft.com>
Sat, 20 Nov 2021 03:28:42 +0000 (19:28 -0800)
committerGitHub <noreply@github.com>
Sat, 20 Nov 2021 03:28:42 +0000 (19:28 -0800)
Co-authored-by: Aaron Robinson <arobins@microsoft.com>
17 files changed:
docs/workflow/testing/coreclr/test-configuration.md
src/coreclr/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivationContextInternal.cs
src/coreclr/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.PlatformNotSupported.cs
src/coreclr/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs
src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.props
src/tests/Common/override.targets [deleted file]
src/tests/Directory.Build.targets
src/tests/Interop/COM/Activator/Activator.csproj
src/tests/Interop/COM/Activator/ActivatorBuiltInComDisabled.csproj
src/tests/Interop/COM/Activator/ComActivationContext.cs [new file with mode: 0644]
src/tests/Interop/COM/Activator/Program.cs
src/tests/Interop/Directory.Build.targets
src/tests/Interop/ICastable/Castable.cs
src/tests/Interop/ICastable/Castable.csproj
src/tests/Interop/ICastable/ICastable.CoreLib.csproj [new file with mode: 0644]
src/tests/Interop/IJW/LoadIjwFromModuleHandle/LoadIjwFromModuleHandle.cs
src/tests/Interop/IJW/LoadIjwFromModuleHandle/LoadIjwFromModuleHandle.csproj

index 3e0f0d2..a2342d3 100644 (file)
@@ -52,8 +52,6 @@ Therefore the managed portion of each test **must not contain**:
 * Exclude test from JIT stress runs runs by adding the following to the csproj:
     * `<JitOptimizationSensitive>true</JitOptimizationSensitive>`
 * Add NuGet references by updating the following [test project](https://github.com/dotnet/runtime/blob/main/src/tests/Common/test_dependencies/test_dependencies.csproj).
-* Get access to System.Private.CoreLib types and methods that are not exposed via public surface by adding the following to the csproj:
-    * `<ReferenceSystemPrivateCoreLib>true</ReferenceSystemPrivateCoreLib>`
 * Any System.Private.CoreLib types and methods used by tests must be available for building on all platforms.
 This means there must be enough implementation for the C# compiler to find the referenced types and methods. Unsupported target platforms
 should simply `throw new PlatformNotSupportedException()` in its dummy method implementations.
index 1db025e..c16a56e 100644 (file)
@@ -25,7 +25,7 @@ namespace Internal.Runtime.InteropServices
     //
 
     [StructLayout(LayoutKind.Sequential)]
-    public partial struct ComActivationContext
+    internal partial struct ComActivationContext
     {
         public Guid ClassId;
         public Guid InterfaceId;
@@ -38,7 +38,7 @@ namespace Internal.Runtime.InteropServices
     [ComVisible(false)]
     [Guid("00000001-0000-0000-C000-000000000046")]
     [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
-    public interface IClassFactory
+    internal interface IClassFactory
     {
         [RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
         void CreateInstance(
index 6d4ddfa..1bb64cf 100644 (file)
@@ -12,35 +12,24 @@ namespace Internal.Runtime.InteropServices
         /// Internal entry point for unmanaged COM activation API from native code
         /// </summary>
         /// <param name="pCxtInt">Pointer to a <see cref="ComActivationContextInternal"/> instance</param>
-        [CLSCompliant(false)]
         [UnmanagedCallersOnly]
-        public static unsafe int GetClassFactoryForTypeInternal(ComActivationContextInternal* pCxtInt)
+        private static unsafe int GetClassFactoryForTypeInternal(ComActivationContextInternal* pCxtInt)
             => throw new PlatformNotSupportedException();
 
         /// <summary>
         /// Internal entry point for registering a managed COM server API from native code
         /// </summary>
         /// <param name="pCxtInt">Pointer to a <see cref="ComActivationContextInternal"/> instance</param>
-        [CLSCompliant(false)]
         [UnmanagedCallersOnly]
-        public static unsafe int RegisterClassForTypeInternal(ComActivationContextInternal* pCxtInt)
+        private static unsafe int RegisterClassForTypeInternal(ComActivationContextInternal* pCxtInt)
             => throw new PlatformNotSupportedException();
 
         /// <summary>
         /// Internal entry point for unregistering a managed COM server API from native code
         /// </summary>
         /// <param name="pCxtInt">Pointer to a <see cref="ComActivationContextInternal"/> instance</param>
-        [CLSCompliant(false)]
         [UnmanagedCallersOnly]
-        public static unsafe int UnregisterClassForTypeInternal(ComActivationContextInternal* pCxtInt)
-            => throw new PlatformNotSupportedException();
-
-        // Exists here to allow tests to build on any platform.
-        public static object GetClassFactoryForType(ComActivationContext cxt)
-            => throw new PlatformNotSupportedException();
-
-        // Exists here to allow tests to build on any platform.
-        public static void ClassRegistrationScenarioForType(ComActivationContext cxt, bool register)
+        private static unsafe int UnregisterClassForTypeInternal(ComActivationContextInternal* pCxtInt)
             => throw new PlatformNotSupportedException();
     }
 }
index a00ecd1..a78bb67 100644 (file)
@@ -57,10 +57,9 @@ namespace Internal.Runtime.InteropServices
             out IntPtr ppvObject);
     }
 
-    public partial struct ComActivationContext
+    internal partial struct ComActivationContext
     {
         [RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
-        [CLSCompliant(false)]
         public static unsafe ComActivationContext Create(ref ComActivationContextInternal cxtInt)
         {
             if (!Marshal.IsBuiltInComSupported)
@@ -91,7 +90,7 @@ namespace Internal.Runtime.InteropServices
         /// </summary>
         /// <param name="cxt">Reference to a <see cref="ComActivationContext"/> instance</param>
         [RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
-        public static object GetClassFactoryForType(ComActivationContext cxt)
+        private static object GetClassFactoryForType(ComActivationContext cxt)
         {
             if (!Marshal.IsBuiltInComSupported)
             {
@@ -125,7 +124,7 @@ namespace Internal.Runtime.InteropServices
         /// <param name="cxt">Reference to a <see cref="ComActivationContext"/> instance</param>
         /// <param name="register">true if called for register or false to indicate unregister</param>
         [RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
-        public static void ClassRegistrationScenarioForType(ComActivationContext cxt, bool register)
+        private static void ClassRegistrationScenarioForType(ComActivationContext cxt, bool register)
         {
             if (!Marshal.IsBuiltInComSupported)
             {
@@ -219,9 +218,8 @@ namespace Internal.Runtime.InteropServices
         /// </summary>
         /// <param name="pCxtInt">Pointer to a <see cref="ComActivationContextInternal"/> instance</param>
         [RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
-        [CLSCompliant(false)]
         [UnmanagedCallersOnly]
-        public static unsafe int GetClassFactoryForTypeInternal(ComActivationContextInternal* pCxtInt)
+        private static unsafe int GetClassFactoryForTypeInternal(ComActivationContextInternal* pCxtInt)
         {
             if (!Marshal.IsBuiltInComSupported)
             {
@@ -262,9 +260,8 @@ $@"{nameof(GetClassFactoryForTypeInternal)} arguments:
         /// </summary>
         /// <param name="pCxtInt">Pointer to a <see cref="ComActivationContextInternal"/> instance</param>
         [RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
-        [CLSCompliant(false)]
         [UnmanagedCallersOnly]
-        public static unsafe int RegisterClassForTypeInternal(ComActivationContextInternal* pCxtInt)
+        private static unsafe int RegisterClassForTypeInternal(ComActivationContextInternal* pCxtInt)
         {
             if (!Marshal.IsBuiltInComSupported)
             {
@@ -308,9 +305,8 @@ $@"{nameof(RegisterClassForTypeInternal)} arguments:
         /// Internal entry point for unregistering a managed COM server API from native code
         /// </summary>
         [RequiresUnreferencedCode("Built-in COM support is not trim compatible", Url = "https://aka.ms/dotnet-illink/com")]
-        [CLSCompliant(false)]
         [UnmanagedCallersOnly]
-        public static unsafe int UnregisterClassForTypeInternal(ComActivationContextInternal* pCxtInt)
+        private static unsafe int UnregisterClassForTypeInternal(ComActivationContextInternal* pCxtInt)
         {
             if (!Marshal.IsBuiltInComSupported)
             {
index cf35f35..b05866e 100644 (file)
@@ -6,7 +6,6 @@
     <CompilerVisibleProperty Include="TargetArchitecture" />
     <CompilerVisibleProperty Include="Priority" />
     <!-- Properties that influence test harness generation -->
-    <CompilerVisibleProperty Include="ReferenceSystemPrivateCoreLib" />
     <CompilerVisibleProperty Include="IsMergedTestRunnerAssembly" />
     <CompilerVisibleProperty Include="TestFilter" />
     <CompilerVisibleItemMetadata Include="AdditionalFiles" MetadataName="IsOutOfProcessTestAssembly" />
diff --git a/src/tests/Common/override.targets b/src/tests/Common/override.targets
deleted file mode 100644 (file)
index 0586ffe..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <!--
-    Overrides for all other targets (including build tools) can go in this file.
-  -->
-
-  <!-- Override the AddDesignTimeFacadeReferences target to add the ability to reference System.Private.CoreLib.
-       Some tests use functionality not available in the portable reference assemblies.
-       For portability reasons it's generally a good idea to reference the facades instead of the
-       raw implementation assemblies.  However, these tests are useful. -->
-  <Target Name="AddDesignTimeFacadeReferences"
-      Condition="'$(ReferenceSystemPrivateCoreLib)' == 'true'"
-      BeforeTargets="ResolveReferences"
-      DependsOnTargets="GetReferenceAssemblyPaths"
-  >
-
-    <ItemGroup>
-      <ReferencePath Include="$(RepoRoot)\artifacts\bin\$(RuntimeFlavor)\$(TargetOS).$(TargetArchitecture).$(Configuration)\IL\System.Private.CoreLib.dll"/>
-    </ItemGroup>
-  </Target>
-
-  <!-- Remove package references when referencing System.Private.CoreLib from SDK style project --> 
-  <Target Name="CleanResolvedCompileFileDefinitions"  AfterTargets="ResolvePackageAssets" Condition="'$(ReferenceSystemPrivateCoreLib)' == 'true' and '$(UsingMicrosoftNETSdk)' == 'true'" >
-    <ItemGroup>
-      <ResolvedCompileFileDefinitions Remove="@(ResolvedCompileFileDefinitions)" />
-    </ItemGroup>
-  </Target>
-
-</Project>
index 0c52df3..84bb4bd 100644 (file)
@@ -80,7 +80,6 @@
     <_WillCLRTestProjectBuild Condition="'$(BuildAllProjects)' != 'true'">true</_WillCLRTestProjectBuild>
     <_WillCLRTestProjectBuild Condition="'$(BuildAllProjects)' == 'true' And '$(CLRTestPriority)' &lt;= '$(CLRTestPriorityToBuild)'">true</_WillCLRTestProjectBuild>
     <_WillCLRTestProjectBuild Condition="'$(CLRTestBuildAllTargets)' != 'allTargets' And '$(CLRTestTargetUnsupported)' == 'true'">false</_WillCLRTestProjectBuild>
-    <_WillCLRTestProjectBuild Condition="'$(ReferenceSystemPrivateCoreLib)' == 'true' and '$(RuntimeFlavor)' == 'mono'">false</_WillCLRTestProjectBuild>
     <_WillCLRTestProjectBuild Condition="'$(DisableProjectBuild)' == 'true'">false</_WillCLRTestProjectBuild>
   </PropertyGroup>
   <PropertyGroup>
@@ -95,8 +94,6 @@
   <!-- RunOnly projects have a special build for dependent projects -->
   <Import Project="$(MSBuildThisFileDirectory)Common\runonly.targets" Condition="'$(CLRTestKind)' == 'RunOnly'" />
 
-  <Import Project="$(MSBuildThisFileDirectory)Common\override.targets" />
-
   <!-- We enable auto-unification of assembly references after importing the common targets.  Binding redirects are not needed
        for coreclr since it auto-unifies, so the warnings we get without this setting are just noise -->
   <PropertyGroup>
           BeforeTargets="BeforeResolveReferences"
   >
    <MSBuild Projects="$(MSBuildProjectFullPath)"
-            Targets="GetLiveRefAssemblies"
-            Condition="'$(ReferenceSystemPrivateCoreLib)' != 'true'">
+            Targets="GetLiveRefAssemblies">
     <Output TaskParameter="TargetOutputs" ItemName="Reference" />
    </MSBuild>
 
-    <ItemGroup Condition="'$(ReferenceSystemPrivateCoreLib)' != 'true'">
+    <ItemGroup >
       <Reference Include="$(TargetingPackPath)/*.dll" >
         <Private>false</Private>
       </Reference>
     <ProjectAssetsFile>$(BaseOutputPath)\packages\Common\test_dependencies\test_dependencies\project.assets.json</ProjectAssetsFile>
   </PropertyGroup>
 
-  <PropertyGroup Condition="'$(ReferenceSystemPrivateCoreLib)' == 'true' and '$(UsingMicrosoftNETSdk)' != 'true'">
-    <ProjectAssetsFile></ProjectAssetsFile>
-  </PropertyGroup>
-
   <PropertyGroup>
     <DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
   </PropertyGroup>
index 87b0633..6090e01 100644 (file)
@@ -1,14 +1,15 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <OutputType>Exe</OutputType>
-    <!-- Internal.Runtime.InteropServices is CoreCLR-only -->
-    <ReferenceSystemPrivateCoreLib>true</ReferenceSystemPrivateCoreLib>
     <RequiresMockHostPolicy>true</RequiresMockHostPolicy>
     <!-- The test fails casting from ClassFromA from the default ALC to type IGetTypeFromC from a custom ALC -->
     <UnloadabilityIncompatible>true</UnloadabilityIncompatible>
+    <DisableProjectBuild Condition="'$(RuntimeFlavor)' == 'Mono'">true</DisableProjectBuild>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="Program.cs" />
+    <Compile Include="ComActivationContext.cs" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\NETServer\NETServer.csproj" />
index b119bcc..5414a40 100644 (file)
@@ -1,14 +1,15 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <OutputType>Exe</OutputType>
-    <!-- Internal.Runtime.InteropServices is CoreCLR-only -->
-    <ReferenceSystemPrivateCoreLib>true</ReferenceSystemPrivateCoreLib>
     <RequiresMockHostPolicy>true</RequiresMockHostPolicy>
     <!-- The test fails casting from ClassFromA from the default ALC to type IGetTypeFromC from a custom ALC -->
     <UnloadabilityIncompatible>true</UnloadabilityIncompatible>
+    <DisableProjectBuild Condition="'$(RuntimeFlavor)' == 'Mono'">true</DisableProjectBuild>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="Program.cs" />
+    <Compile Include="ComActivationContext.cs" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\NETServer\NETServer.csproj" />
diff --git a/src/tests/Interop/COM/Activator/ComActivationContext.cs b/src/tests/Interop/COM/Activator/ComActivationContext.cs
new file mode 100644 (file)
index 0000000..9864107
--- /dev/null
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+namespace Activator
+{
+    [StructLayout(LayoutKind.Sequential)]
+    public partial struct ComActivationContext
+    {
+        public Guid ClassId;
+        public Guid InterfaceId;
+        public string AssemblyPath;
+        public string AssemblyName;
+        public string TypeName;
+    }
+}
index b16802d..48bd0d5 100644 (file)
@@ -1,21 +1,65 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
+using System;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
 
-namespace Activator
+using Internal.Runtime.InteropServices;
+using TestLibrary;
+using Xunit;
+
+namespace Internal.Runtime.InteropServices
 {
-    using Internal.Runtime.InteropServices;
+    [ComImport]
+    [ComVisible(false)]
+    [Guid("00000001-0000-0000-C000-000000000046")]
+    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+    public interface IClassFactory
+    {
+        void CreateInstance(
+            [MarshalAs(UnmanagedType.Interface)] object pUnkOuter,
+            ref Guid riid,
+            out IntPtr ppvObject);
 
-    using System;
-    using System.IO;
-    using System.Runtime.InteropServices;
+        void LockServer([MarshalAs(UnmanagedType.Bool)] bool fLock);
+    }
+}
 
-    using TestLibrary;
-    using Xunit;
+sealed class ClassFactoryWrapper
+{
+    private static readonly MethodInfo IClassFactory_Create = typeof(object).Assembly.GetType("Internal.Runtime.InteropServices.IClassFactory").GetMethod("CreateInstance");
+    private readonly object _obj;
+
+    public ClassFactoryWrapper(object obj)
+    {
+        _obj = obj;
+    }
 
-    using Console = Internal.Console;
+    public void CreateInstance(
+            object pUnkOuter,
+            ref Guid riid,
+            out IntPtr ppvObject)
+    {
+        object[] args = new object[] { pUnkOuter, riid, null };
+        IClassFactory_Create.Invoke(_obj, BindingFlags.DoNotWrapExceptions, binder: null, args, culture: null);
+        riid = (Guid)args[1];
+        ppvObject = (IntPtr)args[2];
+    }
+}
 
-    class Program
+namespace Activator
+{
+    unsafe class Program
     {
+        private static delegate*<ComActivationContext, object> GetClassFactoryForTypeMethod = (delegate*<ComActivationContext, object>)typeof(object).Assembly.GetType("Internal.Runtime.InteropServices.ComActivator", throwOnError: true).GetMethod("GetClassFactoryForType", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer();
+        private static delegate*<ComActivationContext, bool, void> ClassRegistrationScenarioForType = (delegate*<ComActivationContext, bool, void>)typeof(object).Assembly.GetType("Internal.Runtime.InteropServices.ComActivator", throwOnError: true).GetMethod("ClassRegistrationScenarioForType", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer();
+
+        private static ClassFactoryWrapper GetClassFactoryForType(ComActivationContext context)
+        {
+            return new ClassFactoryWrapper(GetClassFactoryForTypeMethod(context));
+        }
+
         static void InvalidInterfaceRequest()
         {
             Console.WriteLine($"Running {nameof(InvalidInterfaceRequest)}...");
@@ -28,7 +72,7 @@ namespace Activator
                     {
                         InterfaceId = notIClassFactory
                     };
-                    ComActivator.GetClassFactoryForType(cxt);
+                    GetClassFactoryForType(cxt);
                 });
         }
 
@@ -43,7 +87,7 @@ namespace Activator
                         InterfaceId = typeof(IClassFactory).GUID,
                         AssemblyPath = "foo.dll"
                     };
-                    ComActivator.GetClassFactoryForType(cxt);
+                    GetClassFactoryForType(cxt);
                 };
 
             if (!builtInComDisabled)
@@ -69,7 +113,7 @@ namespace Activator
                         InterfaceId = typeof(IClassFactory).GUID,
                         AssemblyPath = @"C:\foo.dll"
                     };
-                    ComActivator.GetClassFactoryForType(cxt);
+                    GetClassFactoryForType(cxt);
                 };
 
             if (!builtInComDisabled)
@@ -119,11 +163,11 @@ namespace Activator
                 if (builtInComDisabled)
                 {
                     Assert.Throws<NotSupportedException>(
-                        () => ComActivator.GetClassFactoryForType(cxt));
+                        () => GetClassFactoryForType(cxt));
                     return;
                 }
 
-                var factory = (IClassFactory)ComActivator.GetClassFactoryForType(cxt);
+                var factory = GetClassFactoryForType(cxt);
 
                 IntPtr svrRaw;
                 factory.CreateInstance(null, ref iid, out svrRaw);
@@ -147,7 +191,7 @@ namespace Activator
                     TypeName = "ClassFromB"
                 };
 
-                var factory = (IClassFactory)ComActivator.GetClassFactoryForType(cxt);
+                var factory = GetClassFactoryForType(cxt);
 
                 IntPtr svrRaw;
                 factory.CreateInstance(null, ref iid, out svrRaw);
@@ -200,7 +244,7 @@ namespace Activator
                         TypeName = typeName
                     };
 
-                    var factory = (IClassFactory)ComActivator.GetClassFactoryForType(cxt);
+                    var factory = GetClassFactoryForType(cxt);
 
                     IntPtr svrRaw;
                     factory.CreateInstance(null, ref iid, out svrRaw);
@@ -212,8 +256,8 @@ namespace Activator
                     Assert.False(inst.DidUnregister());
 
                     cxt.InterfaceId = Guid.Empty;
-                    ComActivator.ClassRegistrationScenarioForType(cxt, register: true);
-                    ComActivator.ClassRegistrationScenarioForType(cxt, register: false);
+                    ClassRegistrationScenarioForType(cxt, true);
+                    ClassRegistrationScenarioForType(cxt, false);
 
                     Assert.True(inst.DidRegister(), $"User-defined register function should have been called.");
                     Assert.True(inst.DidUnregister(), $"User-defined unregister function should have been called.");
@@ -239,7 +283,7 @@ namespace Activator
                         TypeName = typename
                     };
 
-                    var factory = (IClassFactory)ComActivator.GetClassFactoryForType(cxt);
+                    var factory = GetClassFactoryForType(cxt);
 
                     IntPtr svrRaw;
                     factory.CreateInstance(null, ref iid, out svrRaw);
@@ -251,7 +295,7 @@ namespace Activator
                     bool exceptionThrown = false;
                     try
                     {
-                        ComActivator.ClassRegistrationScenarioForType(cxt, register: true);
+                        ClassRegistrationScenarioForType(cxt, true);
                     }
                     catch
                     {
@@ -263,7 +307,7 @@ namespace Activator
                     exceptionThrown = false;
                     try
                     {
-                        ComActivator.ClassRegistrationScenarioForType(cxt, register: false);
+                        ClassRegistrationScenarioForType(cxt, false);
                     }
                     catch
                     {
index 0d5ce0b..12c68c9 100644 (file)
@@ -3,20 +3,11 @@
   <Import Project="..\Directory.Build.targets" />
 
   <!-- Add the CoreCLRTestLibrary dependency -->
-  <ItemGroup Condition="('$(IgnoreCoreCLRTestLibraryDependency)' != 'true') And ('$(ReferenceSystemPrivateCoreLib)' != 'true')">
+  <ItemGroup Condition="'$(IgnoreCoreCLRTestLibraryDependency)' != 'true'">
     <ProjectReference
       Include="$(MSBuildThisFileDirectory)\..\Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj" />
   </ItemGroup>
 
-  <!-- Add the CoreCLRTestLibrary dependency
-       If a target project references System.Private.Corelib, we are unable to reference CoreCLRTestLibrary.
-       Compile in relevant files used for testing interop. -->
-  <ItemGroup Condition="('$(IgnoreCoreCLRTestLibraryDependency)' != 'true') And ('$(ReferenceSystemPrivateCoreLib)' == 'true')">
-    <Compile Include="$(MSBuildThisFileDirectory)\..\Common\CoreCLRTestLibrary\AssertExtensions.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)\..\Common\Assert.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)\..\Common\CoreCLRTestLibrary\HostPolicyMock.cs" Condition="'$(RequiresMockHostPolicy)' == 'true'"/>
-  </ItemGroup>
-
   <Target Name="CopyInteropNativeRuntimeDependencies"
     BeforeTargets="CopyAllNativeProjectReferenceBinaries"
     Condition="'$(TargetsWindows)' == 'true' And ('$(Configuration)' == 'Debug' Or '$(Configuration)' == 'Checked') And '$(CopyDebugCRTDllsToOutputDirectory)' == 'true'" >
index 3a20177..5493d16 100644 (file)
@@ -6,18 +6,6 @@ using System.Diagnostics;
 using System.Runtime.CompilerServices;
 using Xunit;
 
-using Console = Internal.Console;
-
-namespace Xunit
-{
-    // Include an inline definition of the SkipOnMonoAttribute type as tests that reference CoreLib
-    // only reference CoreLib and don't reference any other assemblies.
-    public class SkipOnMonoAttribute : Attribute
-    {
-        public SkipOnMonoAttribute(string reason, int testPlatforms = ~0) { }
-    }
-}
-
 public interface IRetArg<T>
 {
     T ReturnArg(T t);
index 7007b69..76fc602 100644 (file)
@@ -1,9 +1,9 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <!-- Internal.Console is not in the CoreLib reference assemblies.  ICastable is CoreCLR-only  -->
-    <ReferenceSystemPrivateCoreLib>true</ReferenceSystemPrivateCoreLib>
+    <DisableProjectBuild Condition="'$(RuntimeFlavor)' == 'Mono'">true</DisableProjectBuild>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="Castable.cs" />
+    <ProjectReference Include="ICastable.CoreLib.csproj" Private="false" />
   </ItemGroup>
 </Project>
diff --git a/src/tests/Interop/ICastable/ICastable.CoreLib.csproj b/src/tests/Interop/ICastable/ICastable.CoreLib.csproj
new file mode 100644 (file)
index 0000000..482a08e
--- /dev/null
@@ -0,0 +1,17 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <!--
+    ICastable.CoreLib provides a "shim" definition of ICastable in System.Private.CoreLib for the Castable test suite.
+    The Castable test suite references this project at compile time but does not get deployed with the test.
+    As a result, the Castable test suite has a direct reference to System.Private.CoreLib for the ICastable interface,
+    which enables us to avoid using Reflection.Emit to provide the implementations.
+  -->
+  <PropertyGroup>
+    <OutputType>Library</OutputType>
+    <CLRTestKind>SharedLibrary</CLRTestKind>
+    <AssemblyName>System.Private.CoreLib</AssemblyName>
+    <Nullable>annotations</Nullable>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="$(RepoRoot)/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ICastable.cs" />
+  </ItemGroup>
+</Project>
index e7df50e..66232d4 100644 (file)
@@ -5,12 +5,9 @@ using System;
 using System.IO;
 using System.Reflection;
 using System.Runtime.InteropServices;
-using Internal.Runtime.InteropServices;
 using TestLibrary;
 using Xunit;
 
-using Console = Internal.Console;
-
 namespace LoadIjwFromModuleHandle
 {
     class LoadIjwFromModuleHandle
@@ -38,7 +35,15 @@ namespace LoadIjwFromModuleHandle
                     string.Empty))
                 fixed (char* path = ijwModulePath)
                 {
-                    InMemoryAssemblyLoader.LoadInMemoryAssembly(ijwNativeHandle, (IntPtr)path);
+                    typeof(object).Assembly
+                        .GetType("Internal.Runtime.InteropServices.InMemoryAssemblyLoader")
+                        .GetMethod("LoadInMemoryAssembly")
+                        .Invoke(
+                            null,
+                            BindingFlags.DoNotWrapExceptions,
+                            binder: null,
+                            new object[] { ijwNativeHandle, (IntPtr)path },
+                            culture: null);
                 }
 
                 NativeEntryPointDelegate nativeEntryPoint = Marshal.GetDelegateForFunctionPointer<NativeEntryPointDelegate>(NativeLibrary.GetExport(ijwNativeHandle, "NativeEntryPoint"));
index a42c985..f5f12e8 100644 (file)
@@ -1,8 +1,6 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <OutputType>Exe</OutputType>
-    <!-- Internal.Runtime.InteropServices is CoreCLR-only -->
-    <ReferenceSystemPrivateCoreLib>true</ReferenceSystemPrivateCoreLib>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <RequiresMockHostPolicy>true</RequiresMockHostPolicy>
     <!-- IJW is Windows-only -->
@@ -12,6 +10,7 @@
     <CLRTestTargetUnsupported Condition="'$(TargetArchitecture)' == 'arm64'">true</CLRTestTargetUnsupported>
     <!-- Loading IJW assemblies into an unloadable context is not allowed -->
     <UnloadabilityIncompatible>true</UnloadabilityIncompatible>
+    <DisableProjectBuild Condition="'$(RuntimeFlavor)' == 'Mono'">true</DisableProjectBuild>
   </PropertyGroup>
   <PropertyGroup>
     <CopyDebugCRTDllsToOutputDirectory>true</CopyDebugCRTDllsToOutputDirectory>