Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,22 @@ public void SetUp ()

_currentDirectory = Environment.CurrentDirectory;
}

[TearDown]
public void TearDown ()
{
var assemblyPath = Path.Combine (_currentDirectory, c_assemblyFileName);
if (File.Exists (assemblyPath))
File.Delete (assemblyPath);
}

[Test]
public void CreateModuleBuilder ()
{
var result = _factory.CreateModuleBuilder (c_assemblyName, assemblyDirectoryOrNull: null, strongNamed: false, keyFilePathOrNull: null);

CheckAdapterBehavior (result);
#if FEATURE_ASSEMBLYBUILDER_SAVE
#if NETFRAMEWORK || NET9_0_OR_GREATER
CheckSaveToDiskBehavior (result, _currentDirectory);
#endif
}
Expand All @@ -62,7 +71,7 @@ public void CreateModuleBuilder ()
public void CreateModuleBuilder_AppliesTypePipeAssemblyAttribute ()
{
var assemblyName = c_assemblyName + Guid.NewGuid();
_factory.CreateModuleBuilder (assemblyName, assemblyDirectoryOrNull: null, strongNamed: false, keyFilePathOrNull: null);
var moduleBuilder = _factory.CreateModuleBuilder (assemblyName, assemblyDirectoryOrNull: null, strongNamed: false, keyFilePathOrNull: null);

var assembly = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault(a => a.GetName().Name == assemblyName);
Assert.That (assembly, Is.Not.Null);
Expand All @@ -79,26 +88,18 @@ public void CreateModuleBuilder_CustomDirectory ()
var result = _factory.CreateModuleBuilder (c_assemblyName, tempDirectory, false, null);

CheckAdapterBehavior (result);
#if FEATURE_ASSEMBLYBUILDER_SAVE
#if NETFRAMEWORK || NET9_0_OR_GREATER
CheckSaveToDiskBehavior (result, tempDirectory);
#endif
}

[Test]
#if !FEATURE_STRONGNAMESIGNING
[Ignore("Platform does not support strong named assembly signing.")]
#endif
public void CreateModuleBuilder_StrongNamed_FallbackKey ()
{
try
{
Dev.Null = FallbackKey.KeyPair.PublicKey;
}
catch (PlatformNotSupportedException)
{
#if FEATURE_ASSEMBLYBUILDER_SAVE
throw;
#else
Assert.Ignore (".NET does not support assembly persistence.");
#endif
}
Dev.Null = FallbackKey.KeyPair.PublicKey;

var result1 = _factory.CreateModuleBuilder (c_assemblyName, assemblyDirectoryOrNull: null, strongNamed: true, keyFilePathOrNull: null);
var result2 = _factory.CreateModuleBuilder (c_assemblyName, assemblyDirectoryOrNull: null, strongNamed: true, keyFilePathOrNull: string.Empty);
Expand All @@ -113,20 +114,12 @@ public void CreateModuleBuilder_StrongNamed_FallbackKey ()
}

[Test]
#if !FEATURE_STRONGNAMESIGNING
[Ignore("Platform does not support strong named assembly signing.")]
#endif
public void CreateModuleBuilder_StrongNamed_ProvidedKey ()
{
try
{
Dev.Null = FallbackKey.KeyPair.PublicKey;
}
catch (PlatformNotSupportedException)
{
#if FEATURE_ASSEMBLYBUILDER_SAVE
throw;
#else
Assert.Ignore (".NET does not support assembly persistence.");
#endif
}
Dev.Null = FallbackKey.KeyPair.PublicKey;

var otherKeyPath = Path.Combine (AppDomain.CurrentDomain.BaseDirectory, @"CodeGeneration\ReflectionEmit\OtherKey.snk");
var result = _factory.CreateModuleBuilder (
Expand All @@ -142,7 +135,7 @@ private void CheckAdapterBehavior (IModuleBuilder moduleBuilder, byte[] expected
{
Assert.That (moduleBuilder, Is.TypeOf<ModuleBuilderAdapter>());
var moduleBuilderAdapter = (ModuleBuilderAdapter) moduleBuilder;
#if FEATURE_ASSEMBLYBUILDER_SAVE
#if NETFRAMEWORK || NET9_0_OR_GREATER
Assert.That (moduleBuilderAdapter.ScopeName, Is.EqualTo (c_assemblyFileName));
#else
// .NET5 as a hardcoded module name since it does not support AssemblyBuilder.Save().
Expand All @@ -152,20 +145,26 @@ private void CheckAdapterBehavior (IModuleBuilder moduleBuilder, byte[] expected
var assemblyBuilderAdapter = (AssemblyBuilderAdapter) moduleBuilder.AssemblyBuilder;

Assert.That (assemblyBuilderAdapter.AssemblyName, Is.EqualTo (c_assemblyName));
#if NET9_0_OR_GREATER
Assert.That (assemblyBuilderAdapter.PublicKey, Is.EqualTo (expectedPublicKey));
#else
Assert.That (assemblyBuilderAdapter.PublicKey, Is.EqualTo (expectedPublicKey ?? new byte[0]));
#endif
}

private void CheckSaveToDiskBehavior (IModuleBuilder moduleBuilder, string assemblyDirectory)
{
var assemblyPath = Path.Combine (assemblyDirectory, c_assemblyFileName);
var pdbPath = Path.Combine (assemblyDirectory, c_pdbFileName);
Assert.That (File.Exists (assemblyPath), Is.False);
Assert.That (File.Exists (pdbPath), Is.False);
Assert.That (File.Exists (assemblyPath), Is.False, assemblyPath);
Assert.That (File.Exists (pdbPath), Is.False, pdbPath);

var result = moduleBuilder.AssemblyBuilder.SaveToDisk();

Assert.That (File.Exists (assemblyPath), Is.True);
Assert.That (File.Exists (pdbPath), Is.True);
Assert.That (File.Exists (assemblyPath), Is.True, assemblyPath);
#if FEATURE_PDBEMIT
Assert.That (File.Exists (pdbPath), Is.True, pdbPath);
#endif
Assert.That (result, Is.EqualTo (assemblyPath));

FileUtility.DeleteAndWaitForCompletion (Path.Combine (assemblyDirectory, c_assemblyFileName));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,48 @@
// under the License.
//
using System;
using System.IO;
using System.Reflection.Emit;
using Remotion.Utilities;

namespace Remotion.TypePipe.CodeGeneration.ReflectionEmit.Abstractions
{
#if NET9_0_OR_GREATER
/// <summary>
/// Adapts <see cref="PersistedAssemblyBuilder"/> with the <see cref="IAssemblyBuilder"/> interface.
/// </summary>
#else
/// <summary>
/// Adapts <see cref="AssemblyBuilder"/> with the <see cref="IAssemblyBuilder"/> interface.
/// </summary>
#endif
public class AssemblyBuilderAdapter : BuilderAdapterBase, IAssemblyBuilder
{
#if NET9_0_OR_GREATER
private readonly PersistedAssemblyBuilder _assemblyBuilder;
private readonly string _assemblyDirectory;
#else
private readonly AssemblyBuilder _assemblyBuilder;
#endif
private readonly ModuleBuilder _moduleBuilder;

#if NET9_0_OR_GREATER
public AssemblyBuilderAdapter (PersistedAssemblyBuilder assemblyBuilder, ModuleBuilder moduleBuilder, string assemblyDirectory)
#else
public AssemblyBuilderAdapter (AssemblyBuilder assemblyBuilder, ModuleBuilder moduleBuilder)
#endif
: base (ArgumentUtility.CheckNotNull ("assemblyBuilder", assemblyBuilder).SetCustomAttribute)
{
ArgumentUtility.CheckNotNull ("moduleBuilder", moduleBuilder);
#if NET9_0_OR_GREATER
ArgumentUtility.CheckNotNullOrEmpty ("assemblyDirectory", assemblyDirectory);
#endif

_assemblyBuilder = assemblyBuilder;
_moduleBuilder = moduleBuilder;
#if NET9_0_OR_GREATER
_assemblyDirectory = assemblyDirectory;
#endif
}

public string AssemblyName
Expand All @@ -47,14 +69,30 @@ public byte[] PublicKey
get { return _assemblyBuilder.GetName ().GetPublicKey (); }
}

#if NET9_0_OR_GREATER
public string AssemblyDirectory
{
get { return _assemblyDirectory; }
}
#endif

public string SaveToDisk ()
{
#if FEATURE_ASSEMBLYBUILDER_SAVE
#if NETFRAMEWORK
// Scope name is the module name or file name, i.e., assembly name + '.dll'.
_assemblyBuilder.Save (_moduleBuilder.ScopeName);

// This is the absolute path to the module, which is also the assembly file path for single-module assemblies.
return _moduleBuilder.FullyQualifiedName;
#elif NET9_0_OR_GREATER
// Scope name is the module name or file name, i.e., assembly name + '.dll'.
var modulePath = Path.Combine (_assemblyDirectory, _moduleBuilder.ScopeName);
using (var stream = new FileStream (modulePath, FileMode.Create, FileAccess.Write, FileShare.Read))
{
_assemblyBuilder.Save (stream);
}

return modulePath;
#else
throw new PlatformNotSupportedException ("Assembly persistence is not supported.");
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,26 @@ public IAssemblyBuilder AssemblyBuilder
get { return _assemblyBuilder; }
}

#if NET9_0_OR_GREATER
public ModuleBuilderAdapter (ModuleBuilder moduleBuilder, string assemblyDirectory)
#else
public ModuleBuilderAdapter (ModuleBuilder moduleBuilder)
#endif
: base (ArgumentUtility.CheckNotNull ("moduleBuilder", moduleBuilder).SetCustomAttribute)
{
#if NET9_0_OR_GREATER
ArgumentUtility.CheckNotNullOrEmpty ("assemblyDirectory", assemblyDirectory);
Assertion.IsTrue (moduleBuilder.Assembly is PersistedAssemblyBuilder);
#else
Assertion.IsTrue (moduleBuilder.Assembly is AssemblyBuilder);
#endif

_moduleBuilder = moduleBuilder;
_assemblyBuilder = new AssemblyBuilderAdapter (((AssemblyBuilder) moduleBuilder.Assembly), moduleBuilder);
#if NET9_0_OR_GREATER
_assemblyBuilder = new AssemblyBuilderAdapter ((PersistedAssemblyBuilder) moduleBuilder.Assembly, moduleBuilder, assemblyDirectory);
#else
_assemblyBuilder = new AssemblyBuilderAdapter ((AssemblyBuilder) moduleBuilder.Assembly, moduleBuilder);
#endif
}

[CLSCompliant (false)]
Expand Down
20 changes: 17 additions & 3 deletions Core/CodeGeneration/ReflectionEmit/ModuleBuilderFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,22 @@

namespace Remotion.TypePipe.CodeGeneration.ReflectionEmit
{
#if FEATURE_ASSEMBLYBUILDER_SAVE
#if NETFRAMEWORK
/// <summary>
/// This class creates instances of <see cref="IModuleBuilder"/>.
/// </summary>
/// <remarks> The module will be created with <see cref="AssemblyBuilderAccess.RunAndSave"/> and the <c>emitSymbolInfo</c> flag set to
/// <see langword="true"/>.
/// </remarks>
/// <threadsafety static="true" instance="true"/>
#elif NET9_0_OR_GREATER
/// <summary>
/// This class creates instances of <see cref="IModuleBuilder"/>.
/// </summary>
/// <remarks> The module will be created with <see cref="PersistedAssemblyBuilder"/> and the <c>emitSymbolInfo</c> flag set to
/// <see langword="true"/>.
/// </remarks>
/// <threadsafety static="true" instance="true"/>
#else
/// <summary>
/// This class creates instances of <see cref="IModuleBuilder"/>.
Expand Down Expand Up @@ -70,8 +78,10 @@ public IModuleBuilder CreateModuleBuilder (string assemblyName, string assemblyD
#endif
}

#if FEATURE_ASSEMBLYBUILDER_SAVE
#if NETFRAMEWORK
var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (assemName, AssemblyBuilderAccess.RunAndSave, assemblyDirectoryOrNull);
#elif NET9_0_OR_GREATER
var assemblyBuilder = new PersistedAssemblyBuilder (new AssemblyName(assemblyName), typeof(object).Assembly);
#else
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly (assemName, AssemblyBuilderAccess.Run);
#endif
Expand All @@ -84,8 +94,12 @@ public IModuleBuilder CreateModuleBuilder (string assemblyName, string assemblyD
var moduleBuilder = assemblyBuilder.DefineDynamicModule (moduleName);
#endif

#if NET9_0_OR_GREATER
var assmeblyDirectory = assemblyDirectoryOrNull ?? Environment.CurrentDirectory;
var moduleBuilderAdapter = new ModuleBuilderAdapter (moduleBuilder, assmeblyDirectory);
#else
var moduleBuilderAdapter = new ModuleBuilderAdapter (moduleBuilder);

#endif
var typePipeAttribute = new CustomAttributeDeclaration (s_typePipeAssemblyAttributeCtor, new object[] { _participantConfigurationID });
moduleBuilderAdapter.AssemblyBuilder.SetCustomAttribute (typePipeAttribute);

Expand Down
4 changes: 2 additions & 2 deletions Core/Dlr/Compiler/AssemblyGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ private AssemblyGen() {

_myAssembly = AssemblyBuilder.DefineDynamicAssembly (name, AssemblyBuilderAccess.Run, attributes);

#if FEATURE_PDBEMIT
#if NETFRAMEWORK
_myModule = _myAssembly.DefineDynamicModule (name.Name, false);
#else
_myModule = _myAssembly.DefineDynamicModule (name.Name);
#endif

#if FEATURE_ASSEMBLYBUILDER_SAVE
#if NETFRAMEWORK
_myAssembly.DefineVersionInfoResource();
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// License for the specific language governing permissions and limitations
// under the License.
//
#if FEATURE_ASSEMBLYBUILDER_SAVE
#if NETFRAMEWORK
using System;
using System.Diagnostics;
using System.Reflection;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// License for the specific language governing permissions and limitations
// under the License.
//
#if FEATURE_ASSEMBLYBUILDER_SAVE
#if NETFRAMEWORK
using System;
using System.IO;
using Microsoft.Win32;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// License for the specific language governing permissions and limitations
// under the License.
//
#if FEATURE_ASSEMBLYBUILDER_SAVE
#if NETFRAMEWORK
using System;
using System.IO;
using Microsoft.Win32;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// License for the specific language governing permissions and limitations
// under the License.
//
#if FEATURE_ASSEMBLYBUILDER_SAVE
#if NETFRAMEWORK
using System;
using System.IO;
using Microsoft.Win32;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// License for the specific language governing permissions and limitations
// under the License.
//
#if FEATURE_ASSEMBLYBUILDER_SAVE
#if NETFRAMEWORK
using System;
using System.IO;
using Microsoft.Win32;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// License for the specific language governing permissions and limitations
// under the License.
//
#if FEATURE_ASSEMBLYBUILDER_SAVE
#if NETFRAMEWORK
using System;
using System.IO;
using Microsoft.Win32;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// License for the specific language governing permissions and limitations
// under the License.
//
#if FEATURE_ASSEMBLYBUILDER_SAVE
#if NETFRAMEWORK
using System;
using System.IO;
using Microsoft.Win32;
Expand Down
Loading