Skip to content
Open
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
@@ -0,0 +1,56 @@
using System;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.Loader;
using System.Runtime.InteropServices;

public class CreatePersistedAssemblyExample
{
public static void Main()
{
CreateSaveAndRunAssembly();
CreatePersistedAssemblyBuilderCoreAssemblyWithMetadataLoadContext(RuntimeEnvironment.GetRuntimeDirectory());
}
// <Snippet1>
public static void CreateSaveAndRunAssembly()
{
PersistedAssemblyBuilder ab = new(new AssemblyName("MyAssembly"), typeof(object).Assembly);
ModuleBuilder mob = ab.DefineDynamicModule("MyModule");
TypeBuilder tb = mob.DefineType(
"MyType",
TypeAttributes.Public | TypeAttributes.Class);
MethodBuilder meb = tb.DefineMethod(
"SumMethod",
MethodAttributes.Public | MethodAttributes.Static,
typeof(int), [typeof(int), typeof(int)]);
ILGenerator il = meb.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Add);
il.Emit(OpCodes.Ret);

tb.CreateType();

using var stream = new MemoryStream();
ab.Save(stream); // Or pass filename to save into a file.
stream.Seek(0, SeekOrigin.Begin);
Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(stream);
MethodInfo method = assembly.GetType("MyType").GetMethod("SumMethod");
Console.WriteLine(method.Invoke(null, [5, 10]));
}
// </Snippet1>

// <Snippet2>
public static void CreatePersistedAssemblyBuilderCoreAssemblyWithMetadataLoadContext(string refAssembliesPath)
{
PathAssemblyResolver resolver = new(Directory.GetFiles(refAssembliesPath, "*.dll"));
using MetadataLoadContext context = new(resolver);
Assembly coreAssembly = context.CoreAssembly;
PersistedAssemblyBuilder ab = new(new AssemblyName("MyDynamicAssembly"), coreAssembly);
TypeBuilder typeBuilder = ab.DefineDynamicModule("MyModule").DefineType("Test", TypeAttributes.Public);
MethodBuilder methodBuilder = typeBuilder.DefineMethod("Method", MethodAttributes.Public, coreAssembly.GetType(typeof(int).FullName), Type.EmptyTypes);
// .. add members and save the assembly
}
// </Snippet2>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using System;
using System.Collections;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Resources;

public class SnippetExamples
{
public static void Main()
{
SetEntryPoint();
SetResource();
ReadResource();
}
// <Snippet1>
public static void SetEntryPoint()
{
PersistedAssemblyBuilder ab = new(new AssemblyName("MyAssembly"), typeof(object).Assembly);
TypeBuilder tb = ab.DefineDynamicModule("MyModule").DefineType("MyType", TypeAttributes.Public | TypeAttributes.Class);
// ...
MethodBuilder entryPoint = tb.DefineMethod("Main", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static);
ILGenerator il2 = entryPoint.GetILGenerator();
// ...
il2.Emit(OpCodes.Ret);
tb.CreateType();

MetadataBuilder metadataBuilder = ab.GenerateMetadata(out BlobBuilder ilStream, out BlobBuilder fieldData);

ManagedPEBuilder peBuilder = new(
header: PEHeaderBuilder.CreateExecutableHeader(),
metadataRootBuilder: new MetadataRootBuilder(metadataBuilder),
ilStream: ilStream,
mappedFieldData: fieldData,
entryPoint: MetadataTokens.MethodDefinitionHandle(entryPoint.MetadataToken));

BlobBuilder peBlob = new();
peBuilder.Serialize(peBlob);

// Create the executable:
using FileStream fileStream = new("MyAssembly.exe", FileMode.Create, FileAccess.Write);
peBlob.WriteContentTo(fileStream);
}
// </Snippet1>
// <Snippet2>
public static void SetResource()
{
PersistedAssemblyBuilder ab = new(new AssemblyName("MyAssembly"), typeof(object).Assembly);
ab.DefineDynamicModule("MyModule");
MetadataBuilder metadata = ab.GenerateMetadata(out BlobBuilder ilStream, out _);

using MemoryStream stream = new();
ResourceWriter myResourceWriter = new(stream);
myResourceWriter.AddResource("AddResource 1", "First added resource");
myResourceWriter.AddResource("AddResource 2", "Second added resource");
myResourceWriter.AddResource("AddResource 3", "Third added resource");
myResourceWriter.Close();

byte[] data = stream.ToArray();
BlobBuilder resourceBlob = new();
resourceBlob.WriteInt32(data.Length);
resourceBlob.WriteBytes(data);

metadata.AddManifestResource(
ManifestResourceAttributes.Public,
metadata.GetOrAddString("MyResource.resources"),
implementation: default,
offset: 0);

ManagedPEBuilder peBuilder = new(
header: PEHeaderBuilder.CreateLibraryHeader(),
metadataRootBuilder: new MetadataRootBuilder(metadata),
ilStream: ilStream,
managedResources: resourceBlob);

BlobBuilder blob = new();
peBuilder.Serialize(blob);

// Create the assembly:
using FileStream fileStream = new("MyAssemblyWithResource.dll", FileMode.Create, FileAccess.Write);
blob.WriteContentTo(fileStream);
}
// </Snippet2>
// <Snippet3>
public static void ReadResource()
{
Assembly readAssembly = Assembly.LoadFile(Path.Combine(
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
"MyAssemblyWithResource.dll"));

// Use ResourceManager.GetString() to read the resources.
ResourceManager rm = new("MyResource", readAssembly);
Console.WriteLine("Using ResourceManager.GetString():");
Console.WriteLine($"{rm.GetString("AddResource 1", CultureInfo.InvariantCulture)}");
Console.WriteLine($"{rm.GetString("AddResource 2", CultureInfo.InvariantCulture)}");
Console.WriteLine($"{rm.GetString("AddResource 3", CultureInfo.InvariantCulture)}");

// Use ResourceSet to enumerate the resources.
Console.WriteLine();
Console.WriteLine("Using ResourceSet:");
ResourceSet resourceSet = rm.GetResourceSet(CultureInfo.InvariantCulture, createIfNotExists: true, tryParents: false);
foreach (DictionaryEntry entry in resourceSet)
{
Console.WriteLine($"Key: {entry.Key}, Value: {entry.Value}");
}

// Use ResourceReader to enumerate the resources.
Console.WriteLine();
Console.WriteLine("Using ResourceReader:");
using Stream stream = readAssembly.GetManifestResourceStream("MyResource.resources")!;
using ResourceReader reader = new(stream);
foreach (DictionaryEntry entry in reader)
{
Console.WriteLine($"Key: {entry.Key}, Value: {entry.Value}");
}
}
// </Snippet3>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Reflection.MetadataLoadContext" Version="9.0.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// <Snippet2>
using System;
using System.Globalization;
using System.Resources;
using System.Threading;

[assembly: NeutralResourcesLanguage("en")]

public class ShowDateEx
{
public static void Main()
{
string[] cultureNames = { "en-US", "fr-FR", "ru-RU", "sv-SE" };
ResourceManager rm = new ResourceManager("DateStrings",
typeof(Example).Assembly);

foreach (var cultureName in cultureNames)
{
CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;

Console.WriteLine($"Current UI Culture: {CultureInfo.CurrentUICulture.Name}");
string dateString = rm.GetString("DateStart");
Console.WriteLine($"{dateString} {DateTime.Now:M}.\n");
}
}
}

// The example displays output similar to the following:
// Current UI Culture: en-US
// Today is February 03.
//
// Current UI Culture: fr-FR
// Aujourd'hui, c'est le 3 février
//
// Current UI Culture: ru-RU
// Сегодня февраля 03.
//
// Current UI Culture: sv-SE
// Today is den 3 februari.
// </Snippet2>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// <Snippet2>
using System;
using System.Globalization;
using System.Resources;
using System.Threading;

public class ShowTimeExample
{
public static void Main()
{
string[] cultureNames = [ "en-US", "fr-FR", "ru-RU", "sv-SE" ];
ResourceManager rm = new ResourceManager("DateStrings",
typeof(Example).Assembly);

foreach (var cultureName in cultureNames) {
CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;

Console.WriteLine($"Current UI Culture: {CultureInfo.CurrentUICulture.Name}");
string dateString = rm.GetString("DateStart");
Console.WriteLine($"{dateString} {DateTime.Now:M}.\n");
}
}
}

// The example displays output similar to the following:
// Current UI Culture: en-US
// Today is February 03.
//
// Current UI Culture: fr-FR
// Aujourd'hui, c'est le 3 février
//
// Current UI Culture: ru-RU
// Сегодня февраля 03.
//
// Current UI Culture: sv-SE
// Today is den 3 februari.
// </Snippet2>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// <Snippet3>
using System;
using System.Globalization;
using System.Resources;
using System.Threading;

public class Example2
{
public static void Main()
{
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("ru-RU");
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("ru-RU");

string[] cultureNames = [ "fr-FR", "sv-SE" ];
ResourceManager rm = new ResourceManager("DateStrings",
typeof(Example).Assembly);

foreach (var cultureName in cultureNames)
{
CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
string dateString = rm.GetString("DateStart", culture);
Console.WriteLine($"{culture.DisplayName}: {dateString} {DateTime.Now.ToString("M", culture)}.");
Console.WriteLine();
}
}
}

// The example displays output similar to the following:
// French (France): Aujourd'hui, c'est le 7 février.
//
// Swedish (Sweden): Today is den 7 februari.
// </Snippet3>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// <Snippet1>
using System;
using System.Resources;

public class ShowTimeEx
{
public static void Main()
{
ResourceManager rm = new ResourceManager("Strings",
typeof(Example).Assembly);
string timeString = rm.GetString("TimeHeader");
Console.WriteLine($"{timeString} {DateTime.Now:T}");
}
}

// The example displays output like the following:
// The current time is 2:03:14 PM
// </Snippet1>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// <Snippet1>
using System;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Threading;

[assembly: NeutralResourcesLanguageAttribute("en")]
public class Example
{
public static void Main()
{
// Select the current culture randomly to test resource fallback.
string[] cultures = { "de-DE", "en-us", "fr-FR" };
Random rnd = new Random();
int index = rnd.Next(0, cultures.Length);
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cultures[index]);
Console.WriteLine($"The current culture is {CultureInfo.CurrentUICulture.Name}");

// Retrieve the resource.
ResourceManager rm = new ResourceManager("ExampleResources",
typeof(Example).Assembly);
string greeting = rm.GetString("Greeting");

Console.Write("Enter your name: ");
string name = Console.ReadLine();
Console.WriteLine($"{greeting} {name}!");
}
}
// </Snippet1>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>

</Project>
Loading
Loading