head.WriteLine()

Samstag, Februar 14, 2009

CSharpCodeProvider and referenced .net 3.5 assemblies

Yesterday I've been working a little with CodeDom and the CSharpCodeProvider to invoke dynamically created code. Because I'm working with some WCF types in the dynamic code, I've added a reference to System.ServiceModel and some other assemblies.

...
CodeDomProvider codeProvider =
    new CSharpCodeProvider(providerOptions);
CompilerParameters
compilerParams =
    new CompilerParameters();
compilerParams.GenerateInMemory = true;
compilerParams.ReferencedAssemblies.Add(
    "System.ServiceModel.dll");
...

CompilerResults results = codeProvider.CompileAssemblyFromDom(
    compilerParams, codeUnit);

At runtime, the following exception was returned via the CompilerResults.Error collection:

Metadata file 'System.ServiceModel.dll' could not be found.

I've been wondering, because all other assembly references works fine and the code executed as expected when I don't use WCF types in the dynamic code.

The answer lies in the CSharpCodeProvider class. By default it uses the .net 2.0 compiler and don't knows about the Reference Assemblies folder (c:\Program Files\Reference Assemblies\Microsoft\Framework\...) where the additional .net 3.0 and .net 3.5 assemblies can be found.
To force CSharpCodeProvider to use the .net 3.5 compiler, a special provider option must be set:

Dictionary<string, string> providerOptions =
    new Dictionary<string, string>();
providerOptions.Add("CompilerVersion", "v3.5");
CSharpCodeProvider provider =
    new CSharpCodeProvider(providerOptions);