I am developing a system that uses Roslyn to do runtime compilation of C# code.
I am adding assemblies using this code, passing the fully qualified assembly file name to the method.
public bool AddAssembly(string assemblyDll)
{
if (string.IsNullOrEmpty(assemblyDll)) return false;
var file = Path.GetFullPath(assemblyDll);
if (!File.Exists(file))
{
// check framework or dedicated runtime app folder
var path = Path.GetDirectoryName(typeof(object).Assembly.Location);
file = Path.Combine(path, assemblyDll);
if (!File.Exists(file))
return false;
}
if (References.Any(r => r.FilePath == file))
return true;
try
{
var reference = MetadataReference.CreateFromFile(file);
References.Add(reference);
}
catch
{
return false;
}
return true;
}
All worked well until I wanted to build a Winforms form in the code.
Despite adding System.Windows.Forms.dll to the assembly references I still get the error
Type or namespace name "Forms" does not exist in the namespace ‘System.Windows’
Reading other articles on this error message the solutions all involve Visual Studio and editing the .csproj
file to add
<UseWindowsForms>true</UseWindowsForms>
So, how do I get Roslyn to recognize that I want to use Winforms forms?
2
Answers
I solved my problem and thought it might be useful for someone else.
To summarise. This was part of an R&D exercise we are doing.
Summary of the spec was - Write a program to a read C# source code file, compile it and write the dll to a SQL database. Then write another program to retrieve the dll from SQL and run a method in the dll.
To do this I was using Roslyn APIs (.Net Compiler Platform SDK) and .Net Core.
To get this to work you have to reference any assembly that the code will need when Roslyn compiles it. That is what the code in the question was doing.
In my case these were in
All went well until I picked some code that generated a Winforms Form. Then I got the error above. Eventually I created a "Windows Forms App" project to see what VS 2022 referenced and found that it had another framework in its Dependencies
This refered to files in the following directory
Once I referenced
Roslyn compiled perfectly.
The code you wrote to load the assembly can only run after it has been compiled. Therefore, it cannot load the assemblies which are needed for a successful compilation.
You don’t need any code to load assemblies, unless you are implementing a kind of plug-in/add-in architecture. All you need is to add references to your project.
The compiler will automatically copy the required assemblies into the output folder
binDebugnet8.0-windows
orbinReleasenet8.0-windows
and the Common Language Runtime (CLR) will automatically load the assemblies when you launch the application.When you create a project using the Windows Forms App (.NET Core) template, your *.csproj will look like this:
And your references like this:
And you don’t have to do anything manually. On the other hand, if you started with another project type, you might have to change *.csproj and to add references manually.
And again: Do not attempt to load these assemblies with C# code!