Skip to content

Custom DLL (CommandGathering.dll) Fails Compile-Time Namespace Resolution with //css_ref #406

@jeff-h64

Description

@jeff-h64

I built a minimalistic custom DLL from CommandGathering.cs that defines the namespace CommandPlugin and a class CommandGather with a public method Execute. When referencing this DLL in a separate program (Main.cs) using the conventional //css_ref CommandGathering.dll directive, the compiler fails to resolve the CommandPlugin namespace (error CS0246).

However, if I dynamically load the assembly using Assembly.LoadFrom, the namespace and its types are correctly discovered and usable. Other third-party DLLs referenced in the same manner compile and work as expected. I've verified the DLL is in the correct folder, built as a proper class library with public types, and targeted to the correct framework. Any guidance or fixes to resolve this discrepancy would be greatly appreciated.

Using cscs.exe version 4.9.3.0 and dotnet engine

Issue can be duplicated using these 2 files;
CommandGathering.cs (for the dll)
Main.cs (which uses css_ref/using and generates error CS0246)

CommandGathering.cs

// CommandGathering.cs
//css_engine dotnet
// build: cscs -cd CommandGathering.cs

using System;

namespace CommandPlugin
{
    public class CommandGather
    {		
        public void Execute(string[] args)
        {
            Console.WriteLine("CommandGathering executed!");
        }
    }
}

Main.cs

// Main.cs
//css_engine dotnet
// build/run: cscs -verbose Main.cs
//css_ref CommandGathering.dll

using CommandPlugin;

class Program
{
    static void Main()
    {
        var cmd = new CommandGathering();
        cmd.Execute(null);
    }
}

Build and Run - css_ref does not seem to resolve

C:\000\Test01>cscs Main.cs
Error: Specified file could not be compiled.

C:\000\Test01\Main.cs(6,7): error CS0246:  The type or namespace name 'CommandPlugin' could not be found (are you missing a using directive or an assembly reference?)
C:\000\Test01\Main.cs(6,7): error CS0246:  The type or namespace name 'CommandPlugin' could not be found (are you missing a using directive or an assembly reference?)


C:\000\Test01>

Build and Run - with verbose on

Note that build of Main shows under References that it located C:\000\Test01\CommandGathering.dll

C:\000\Test01>
C:\000\Test01>cscs -verbose -cd CommandGathering.cs
> ----------------
  Provider:
  Script engine: C:\000\Test01\cscs.dll
  Compiler engine: dotnet (C:\Program Files\dotnet\dotnet.exe)
  Console Encoding: Codepage - 437 (Codepage - 437) - system default
  CurrentDirectory: C:\000\Test01
  CurrentProcess: 10772
  NuGet manager: dotnet
  NuGet cache: C:\Users\jeff.hansen\.nuget\packages
  Script cache: C:\Users\jeff.hansen\AppData\Local\Temp\csscript.core\cache
  Executing: C:\000\Test01\CommandGathering.cs
  Hosting: InProcess
  Script arguments:
  SearchDirectories:
    0 - C:\000\Test01
    ------- (local dirs) -------
    ------- (dirs from cmd args) -------
    ------- (dirs from code) -------
    ------- (dirs from config) -------
    1 - C:\000\Test01\lib
    2 - C:\ProgramData\cs-script\commands
    3 - C:\ProgramData\cs-script\inc
    ------- (cs-script special dirs) -------
    4 - C:\Users\jeff.hansen\AppData\Local\Temp\csscript.core\cache\-1986072933
> ----------------

Compiling script...

  Precompilers:
   0 - CommandGathering.cs -> csscript.DefaultPrecompiler
           from C:\000\Test01\cscs.dll

  Output file:
       C:\000\Test01\CommandGathering.dll

  Files to compile:
   0 - C:\000\Test01\CommandGathering.cs
   1 - C:\Users\jeff.hansen\AppData\Local\Temp\csscript.core\cache\-1986072933\CommandGathering.attr.g.cs

  References:
   0 - System
   1 - System.Core
> ----------------
> ----------------
> ----------------
Building with dotnet engine...
Initialization time: 62.7517 msec
Compilation time:    2257.6338 msec
Total load time:     2372.4822 msec
> ----------------

Created: C:\000\Test01\CommandGathering.dll

C:\000\Test01>
C:\000\Test01>cscs -verbose Main.cs
> ----------------
  Provider:
  Script engine: C:\000\Test01\cscs.dll
  Compiler engine: dotnet (C:\Program Files\dotnet\dotnet.exe)
  Console Encoding: Codepage - 437 (Codepage - 437) - system default
  CurrentDirectory: C:\000\Test01
  CurrentProcess: 4236
  NuGet manager: dotnet
  NuGet cache: C:\Users\jeff.hansen\.nuget\packages
  Script cache: C:\Users\jeff.hansen\AppData\Local\Temp\csscript.core\cache
  Executing: C:\000\Test01\Main.cs
  Hosting: InProcess
  Script arguments:
  SearchDirectories:
    0 - C:\000\Test01
    ------- (local dirs) -------
    ------- (dirs from cmd args) -------
    ------- (dirs from code) -------
    ------- (dirs from config) -------
    1 - C:\000\Test01\lib
    2 - C:\ProgramData\cs-script\commands
    3 - C:\ProgramData\cs-script\inc
    ------- (cs-script special dirs) -------
    4 - C:\Users\jeff.hansen\AppData\Local\Temp\csscript.core\cache\-1986072933
> ----------------

Compiling script...

  Precompilers:
   0 - Main.cs -> csscript.DefaultPrecompiler
           from C:\000\Test01\cscs.dll

  Output file:
       C:\Users\jeff.hansen\AppData\Local\Temp\csscript.core\cache\-1986072933\Main.cs.dll

  Files to compile:
   0 - C:\000\Test01\Main.cs
   1 - C:\Users\jeff.hansen\AppData\Local\Temp\csscript.core\cache\-1986072933\Main.attr.g.cs

  References:
   0 - System.Core
   1 - C:\000\Test01\CommandGathering.dll
   2 - System
> ----------------
Error: Specified file could not be compiled.

C:\000\Test01\Main.cs(6,7): error CS0246:  The type or namespace name 'CommandPlugin' could not be found (are you missing a using directive or an assembly reference?)
C:\000\Test01\Main.cs(6,7): error CS0246:  The type or namespace name 'CommandPlugin' could not be found (are you missing a using directive or an assembly reference?)

C:\000\Test01>
C:\000\Test01>

For comparison the functioning of the dll can be verified using;
MainLoad.cs (which uses Assembly.LoadFrom)

MainLoad.cs

// MainLoad.cs
//css_engine dotnet
// build/run: cscs -verbose MainLoad.cs

using System.Reflection;

class Program
{
    static void Main(string[] args)
    {
        // Load the assembly from file.
        var asm = Assembly.LoadFrom("CommandGathering.dll");

        Console.WriteLine("Loaded: " + asm.FullName);
        var type = asm.GetType("CommandPlugin.CommandGather");
        var cmd = Activator.CreateInstance(type);
        type.GetMethod("Execute").Invoke(cmd, new object[] { null });

        // Optional
        DisplayAssemblyInfo(asm);
    } // Main

    static void DisplayAssemblyInfo(Assembly asm)
    {
		Console.WriteLine("============================================================");
		Console.WriteLine("Assembly Information");
        Console.WriteLine($"Full Name : {asm.FullName}");
        Console.WriteLine($"Version   : {asm.GetName().Version}");
        Console.WriteLine($"Location  : {asm.Location}");

        // List all defined types and methods.
 		Console.WriteLine();
		Console.WriteLine("\nDefined Types:");
        foreach (var type in asm.GetTypes())
        {
            Console.WriteLine(" - " + type.FullName);
			ListMethods(type);
        }

        // List all referenced assemblies.
  		Console.WriteLine();
		Console.WriteLine("Referenced Assemblies:");
        foreach (var refAsm in asm.GetReferencedAssemblies())
        {
            Console.WriteLine(" - " + refAsm.FullName);
        }

        // List manifest resource names.
		Console.WriteLine();
		Console.WriteLine("Manifest Resources:");
        foreach (var resource in asm.GetManifestResourceNames())
        {
            Console.WriteLine($" - {resource}");
        }

        // List any custom attributes at the assembly level.
 		Console.WriteLine();
		Console.WriteLine("Custom Attributes:");
        foreach (var attribute in asm.GetCustomAttributes(false))
        {
            Console.WriteLine($" - {attribute.GetType().Name}");
        }
 		Console.WriteLine("============================================================");
   } // DisplayAssemblyInfo
	
	static void ListMethods(Type type)
    {
        Console.WriteLine($"   Methods in {type.FullName}:");

        // Get all public instance and static methods.
///        MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
        MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
      
        foreach (var method in methods)
        {
            Console.WriteLine($"    - {method.Name}");
        }
    } // ListMethods
}

Dynamic loading of dll can access namespace/class

C:\000\Test01>
C:\000\Test01>cscs MainLoad.cs
Loaded: CommandGathering, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
CommandGathering executed!
============================================================
Assembly Information
Full Name : CommandGathering, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Version   : 1.0.0.0
Location  : C:\000\Test01\CommandGathering.dll


Defined Types:
 - CommandPlugin.CommandGather
   Methods in CommandPlugin.CommandGather:
    - Execute

Referenced Assemblies:
 - System.Runtime, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 - System.Console, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

Manifest Resources:

Custom Attributes:
 - CompilationRelaxationsAttribute
 - RuntimeCompatibilityAttribute
 - DebuggableAttribute
 - AssemblyDescriptionAttribute
 - TargetFrameworkAttribute
 - AssemblyCompanyAttribute
 - AssemblyConfigurationAttribute
 - AssemblyFileVersionAttribute
 - AssemblyInformationalVersionAttribute
 - AssemblyProductAttribute
 - AssemblyTitleAttribute
============================================================
C:\000\Test01>

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions