welsonjs/WelsonJS.Toolkit/Catswords.Phantomizer
2025-12-08 10:37:37 +09:00
..
AssemblyLoader.cs Introduce new package Catswords.Phantomizer 2025-12-08 00:49:10 +09:00
Catswords.Phantomizer.csproj Update Catswords.Phantomizer.csproj 2025-12-08 01:20:37 +09:00
LICENSE Introduce new package Catswords.Phantomizer 2025-12-08 00:49:10 +09:00
README.md Update README.md 2025-12-08 10:37:37 +09:00

Catswords.Phantomizer

Catswords.Phantomizer is an HTTP-based dynamic-link library (DLL) loader designed for .NET applications. It allows your application to fetch and load assemblies directly from your CDN (Azure Blob, S3, Cloudflare R2, etc.) at runtime, with optional GZip compression support.


🚀 Features

  • Load managed (*.dll) and native (*.dll) assemblies over HTTP
  • Optional .dll.gz decompression for faster network delivery
  • CDN-friendly URL structure
  • Easy bootstrap through a small embedded loader
  • Loader is implemented using pure .NET BCL only, ensuring stable operation without external dependencies
  • Built-in code-signing verification support to ensure assemblies are trusted and tamper-free

📦 How to Use

1. Embed Phantomizer into your project

You can include Catswords.Phantomizer in your project using one of the following methods:

Method Description When to Use Setup Steps
Resources.resx Embedded File Stores Catswords.Phantomizer.dll.gz inside Resources.resx and loads it at runtime. Recommended when you want the loader fully self-contained inside your executable. Add file to Resources.resx → Access via Properties.Resources.Phantomizer.
Embedded Resource Embeds Catswords.Phantomizer.dll.gz directly into the assembly manifest (outside of resx). Useful when you prefer not to maintain .resx files but still want Phantomizer embedded. Add file to project → Set Build Action = Embedded Resource → Load via GetManifestResourceStream().
Normal Assembly Reference (no embedding) References Catswords.Phantomizer.dll normally through project references. Use this when you distribute Phantomizer as a standalone DLL instead of embedding it. Add Phantomizer DLL to your project references → using Catswords.Phantomizer;.

2. Initialize Phantomizer at application startup

Place the following code inside your Main method, static constructor, or any early entry point:

static Program() {
    InitializeAssemblyLoader();
}

private static void InitializeAssemblyLoader()
{
    /*
    // if use the Embedded Resource
    var asm = Assembly.GetExecutingAssembly();
    using (var stream = asm.GetManifestResourceStream("MyApp.Resources.Catswords.Phantomizer.dll.gz"))
    {
        // decompress and load...
    }
    */

    byte[] gzBytes = Properties.Resources.Phantomizer;

    byte[] dllBytes;
    using (var input = new MemoryStream(gzBytes))
    using (var gz = new GZipStream(input, CompressionMode.Decompress))
    using (var output = new MemoryStream())
    {
        gz.CopyTo(output);
        dllBytes = output.ToArray();
    }

    Assembly phantomAsm = Assembly.Load(dllBytes);
    Type loaderType = phantomAsm.GetType("Catswords.Phantomizer.AssemblyLoader", true);

    loaderType.GetProperty("BaseUrl")?.SetValue(null, GetAppConfig("AssemblyBaseUrl"));  // Set the CDN base URL
    loaderType.GetProperty("LoaderNamespace")?.SetValue(null, typeof(Program).Namespace);
    loaderType.GetProperty("AppName")?.SetValue(null, "WelsonJS");                       // Application name
    loaderType.GetMethod("Register")?.Invoke(null, null);

    var loadNativeModulesMethod = loaderType.GetMethod(
        "LoadNativeModules",
        BindingFlags.Public | BindingFlags.Static,
        binder: null,
        types: new[] { typeof(string), typeof(Version), typeof(string[]) },
        modifiers: null
    );

    if (loadNativeModulesMethod == null)
        throw new InvalidOperationException("LoadNativeModules(string, Version, string[]) method not found.");

    loadNativeModulesMethod.Invoke(null, new object[]
    {
        "ChakraCore",
        new Version(1, 13, 0, 0),
        new[] { "ChakraCore.dll" }
    });
}

If you prefer not to embed, you can reference Phantomizer directly with a normal using statement:

using Catswords.Phantomizer;

static void Main(string[] args)
{
    AssemblyLoader.BaseUrl = GetAppConfig("AssemblyBaseUrl");   // Configure CDN base URL
    AssemblyLoader.LoaderNamespace = typeof(Program).Namespace;
    AssemblyLoader.AppName = "WelsonJS";
    AssemblyLoader.Register();

    AssemblyLoader.LoadNativeModules(
        "ChakraCore",
        new Version(1, 13, 0, 0),
        new[] { "ChakraCore.dll" }
    );
}

3. Upload your DLL files to a CDN

Upload your managed and native assemblies to your CDN following the URL pattern below.

📁 URL Rules

Type Example URL Description
Managed DLL https://example.cdn.tld/packages/managed/MyManagedLib/1.0.0.0/MyManagedLib.dll Normal .NET assembly
Managed DLL (GZip) https://example.cdn.tld/packages/managed/MyManagedLib/1.0.0.0/MyManagedLib.dll.gz GZip-compressed .NET assembly
Native DLL https://example.cdn.tld/packages/native/MyNativeLib/1.0.0.0/MyNativeLib.dll Native assembly
Native DLL (GZip) https://example.cdn.tld/packages/native/MyNativeLib/1.0.0.0/MyNativeLib.dll.gz GZip-compressed native assembly

4. 🎉 Start loading assemblies over HTTP

Once Phantomizer is initialized, your application will automatically fetch missing assemblies from your CDN.


Download the pre-compiled file


Report abuse

Join the community

I am always open. Collaboration, opportunities, and community activities are all welcome.