Class generation from XSD during runtime - c#

How do I generate a C# class from XSD at runtime?
Additionally, how do it list the properties that are contained by the type?

It definitely is possible.. and not too complicated. You just have to add some differen techniques.
You can use the "Description Importer" to import Service descriptions in runtime. Link
What I did was basically creating following steps:
1) Get the WSDL file with a reader (locally or remote, different approaches)
XmlTextReader myXmlReader;
myWebService = new WebServiceImporterCompiler(WSDLPath, soapVersion);
if (useLocalWSDL)
{
FileWebRequest wr = (FileWebRequest)FileWebRequest.Create(WSDLPath);
FileWebResponse wres = (FileWebResponse)wr.GetResponse();
myXmlReader = new XmlTextReader(wres.GetResponseStream());
}
else
{
Uri uri = new Uri(WSDLPath); //WEBSERVICE URI
HttpWebRequest wr = (HttpWebRequest)HttpWebRequest.Create(uri.OriginalString + "?wsdl");
wr.Credentials = wr.Credentials = new NetworkCredential(userName, password ?? "");
HttpWebResponse wres = (HttpWebResponse)wr.GetResponse();
myXmlReader = new XmlTextReader(wres.GetResponseStream());
}
2) Build an assembly from the definition / myXmlReader
Check if the xml is readable
if (!System.Web.Services.Description.ServiceDescription.CanRead(myXmlReader))
{
throw new IOException("WSDL not readable");
}
Load importer with some basic options (you might add / change something here)
I create an assembly (dll) but with the switch parameters.GenerateInMemory you will be able to generate an in memory class.
ServiceDescriptionImporter descriptionImporter = new ServiceDescriptionImporter();
ServiceDescription serviceDescription = ServiceDescription.Read(myXmlReader);
descriptionImporter.ProtocolName = soapVersion.ToString(); // EITHER SOAP OR SOAP12
descriptionImporter.AddServiceDescription(serviceDescription, null, null);
descriptionImporter.Style = ServiceDescriptionImportStyle.Client;
descriptionImporter.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;
Compile assembly with CodeDomProvider
CodeCompileUnit codeUnit = new CodeCompileUnit();
CodeNamespace codeNamespace = new CodeNamespace();
codeUnit.Namespaces.Add(codeNamespace); // Add additional Namespaces
ServiceDescriptionImportWarnings importWarnings = descriptionImporter.Import(codeNamespace, codeUnit);
if (importWarnings == 0)
{
using (CodeDomProvider compiler = CodeDomProvider.CreateProvider("CSharp"))
{
string[] references = { "System.dll", "System.Web.Services.dll", "System.Xml.dll" };
CompilerParameters parameters = new CompilerParameters(references);
parameters.GenerateExecutable = false;
parameters.GenerateInMemory = false;
parameters.IncludeDebugInformation = false;
parameters.CompilerOptions = "/optimize";
parameters.TempFiles = new TempFileCollection(System.IO.Path.GetTempPath() + "xxx", false);
parameters.ReferencedAssemblies.Add("System.dll");
results = compiler.CompileAssemblyFromSource(parameters, CSharpCode);
foreach (CompilerError cError in results.Errors)
{
// log errors
}
if (results.Errors.Count > 0 || results.CompiledAssembly == null) throw new Exception("Kompilierfehler bei Assemblyerstellung");
}
}
3) Use the generated asssembly object to invoke methods for example for calling the service
public T InvokeMethod <T>(Assembly assembly, string serviceNameToCall, MethodInfo methodToCall)
{
SoapHttpClientProtocol mySoapProtocoll;
try
{
object serviceInstance = myAssembly.CreateInstance(serviceNameToCall);
mySoapProtocoll = (SoapHttpClientProtocol)serviceInstance;
mySoapProtocoll.Credentials = CredentialCache.DefaultCredentials; // or use your own
object myObject = (T)ServiceType.InvokeMember(methodToCall, BindingFlags.InvokeMethod, null, mySoapProtocoll, args);
}
}
To get the methodInfo object / available methods use reflections to iterate over the assembly / classes.
A complete guide on reflections can be found here

Related

Dynamic Compilation NullReferenceException error

I'll try to define as mush as possible my problem and forget nothing.
For my project, which use a webRequest, I would like to compile dynamically my webRequest.
For this I used the CodeDomProvider in a Private Assembly and a public MethodInfo who gives me back a " method" that I can use in my main program.
So the main problem is that in my CompileCode, my MethodInfo method = type.getMethod(functionname); gives me a NullReferenceException error. I know it's because my type.getMethod(functionname) can't work on a type which is null. I tried to modify the fact that my object instance and Type type are not null, but I can't give them values because of their gender and I get stuck in the fact that they stay null and gives me no values...
I also saw that lot of people used Linq, but as I am compiling a whole .cs file, I can't write it all like this with the #"using System.Linq;";
So here are the partial code were the problem is :
Thank you
namespace testCodeCompiler
{
public class CodeCompiler
{
public CodeCompiler()
{
}
public MethodInfo CompileCode(string code, string namespacename, string classname,string functionname, bool isstatic, params object[] args)
{
Assembly asm = BuildAssembly(code);
object instance = null;
Type type = null;
if (isstatic)
{
type = asm.GetType(namespacename + "." + classname);
}
else
{
instance = asm.CreateInstance(namespacename + "." + classname);
type = instance.GetType();
}
MethodInfo method = type.GetMethod(functionname); // here is the error
return method;
}
private Assembly BuildAssembly(string code)
{
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters compilerparams = new CompilerParameters();
compilerparams.GenerateExecutable = false;
compilerparams.GenerateInMemory = true;
compilerparams.ReferencedAssemblies.Add("System.dll");
compilerparams.ReferencedAssemblies.Add("System.Xml.dll");
System.Reflection.Assembly currentAssembly = System.Reflection.Assembly.GetExecutingAssembly();
compilerparams.ReferencedAssemblies.Add(currentAssembly.Location);
CompilerResults results = provider.CompileAssemblyFromSource(compilerparams, code);
if (results.Errors.HasErrors)
{
StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");
foreach (CompilerError error in results.Errors )
{
errors.AppendFormat("Line {0},{1}\t: {2}\n", error.Line, error.Column, error.ErrorText);
}
throw new Exception(errors.ToString());
}
else
{
return results.CompiledAssembly;
}
}
}
And a little part of the Main() :
static void Main(string[] args)
{
MethodInfo method;
[// Little bit of code ]
StreamReader sr = new StreamReader(#"c:\pathtothefileIwant\File.cs", System.Text.Encoding.Default);
string file = sr.ReadToEnd();
sr.Close();
CodeCompiler cc = new CodeCompiler();
object[] arguments = { popup }; // here are the args which are in another class
[...little bit of code...]
method = cc.CompileCode(file, "testNamespace", "Class1", "webRequest", true, arguments);
List<Test> li = (List<Test>)method.Invoke(null, arguments); // Here I invoke the method to put it in a List<Compte> I made before.
}
The problem was in the class Program
Main(){ method = cc.CompileCode(file, "testNamespace", "Class1", "webRequest", true, arguments);}
The string classname was not the good one and didn't pointed to the real document I wanted to compile. The good path was method = cc.CompileCode(file,"testNamespace", "WebRequest","webRequest", true, arguments);}
That's why the Type type; couldn't get something instead of null.

Dynamic Invocation of WCF Service Using Reflection

I'm having a problem passing a generic collection to a WCF service method when invoked using reflection. Specifically, the collection is of type List<KeyValuePair<string,string>>.
My goal is to be able to execute methods of a WCF service dynamically during runtime without adding any references to the service whatsoever in my client app. A user should be able to add a service during runtime and the app should just magically be able to handle it.
Service Interface
[ServiceContract]
public interface ITestService
{
[OperationContract]
string ProcessSimpleType(string value);
[OperationContract]
string ProcessGenericCollection(List<KeyValuePair<string, string>> genericCol);
}
Service Implementation
public class TestService : ITestService
{
public string ProcessSimpleType(string value)
{
return value;
}
public string ProcessGenericCollection(List<KeyValuePair<string, string>> genericCol)
{
return "Hello World!";
}
}
Client Code
try
{
Uri mexAddress = new Uri("http://localhost:8732/TestService/?wsdl");
MetadataExchangeClientMode mexMode = MetadataExchangeClientMode.HttpGet;
string contractName = "ITestService";
string operationName = "ProcessGenericCollection";
List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
list.Add(new KeyValuePair<string, string>("key", "value"));
object[] operationParameters = new object[] { list };
MetadataExchangeClient mexClient = new MetadataExchangeClient(mexAddress, mexMode);
mexClient.ResolveMetadataReferences = true;
MetadataSet metaSet = mexClient.GetMetadata();
WsdlImporter importer = new WsdlImporter(metaSet);
Collection<ContractDescription> contracts = importer.ImportAllContracts();
ServiceEndpointCollection allEndpoints = importer.ImportAllEndpoints();
ServiceContractGenerator generator = new ServiceContractGenerator();
var endpointsForContracts = new Dictionary<string, IEnumerable<ServiceEndpoint>>();
foreach (ContractDescription contract in contracts)
{
generator.GenerateServiceContractType(contract);
endpointsForContracts[contract.Name] = allEndpoints.Where(
se => se.Contract.Name == contract.Name).ToList();
}
if (generator.Errors.Count != 0)
throw new Exception("There were errors during code compilation.");
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BracingStyle = "C";
CodeDomProvider codeDomProvider = CodeDomProvider.CreateProvider("C#");
CompilerParameters compilerParameters = new CompilerParameters(
new string[] {
"System.dll", "System.ServiceModel.dll",
"System.Runtime.Serialization.dll" });
compilerParameters.GenerateInMemory = true;
CompilerResults results = codeDomProvider.CompileAssemblyFromDom(
compilerParameters, generator.TargetCompileUnit);
if (results.Errors.Count > 0)
{
throw new Exception("There were errors during generated code compilation");
}
else
{
Type clientProxyType = results.CompiledAssembly.GetTypes().First(
t => t.IsClass &&
t.GetInterface(contractName) != null &&
t.GetInterface(typeof(ICommunicationObject).Name) != null);
ServiceEndpoint se = endpointsForContracts[contractName].First();
object instance = results.CompiledAssembly.CreateInstance(
clientProxyType.Name,
false,
System.Reflection.BindingFlags.CreateInstance,
null,
new object[] { se.Binding, se.Address },
CultureInfo.CurrentCulture, null);
var methodInfo = instance.GetType().GetMethod(operationName);
//Invoking the ProcessGenericCollection via reflection will throw an exception
object retVal = methodInfo.Invoke(instance, BindingFlags.InvokeMethod, null, operationParameters, null);
Console.WriteLine(retVal.ToString());
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
The error that is thrown is:
{"Object of type
'System.Collections.Generic.List1[System.Collections.Generic.KeyValuePair2[System.String,System.String]]'
cannot be converted to type
'System.Collections.Generic.KeyValuePairOfstringstring[]'."}
Keep in mind, this works gloriously when testing against the ProcessSimpleType(...) method and passing in a simple type. My issue is only with ProcessGenericCollection(...). Has anyone ever encountered this issue, and if so, how did you overcome it?
Thanks to a colleague for providing the solution. For those of you with a similar issue, I inserted the following:
...
...
WsdlImporter importer = new WsdlImporter(metaSet);
//BEGIN INSERT
XsdDataContractImporter xsd = new XsdDataContractImporter();
xsd.Options = new ImportOptions();
xsd.Options.ImportXmlType = true;
xsd.Options.GenerateSerializable = true;
xsd.Options.ReferencedTypes.Add(typeof(KeyValuePair<string, string>));
xsd.Options.ReferencedTypes.Add(typeof(System.Collections.Generic.List<KeyValuePair<string, string>>));
importer.State.Add(typeof(XsdDataContractImporter), xsd);
//END INSERT
Collection<ContractDescription> contracts = importer.ImportAllContracts();
...
...

WF 4.5 WCF Workflow Service Application calling with REST

Want a way to call a WCF Workflow Service Application using REST instead of SOAP. I've defined a REST endpoint with custom webhttpbehavior and from that call I am trying to load the XAMLX and run it.
My first attempt fails with
Expression Activity type 'CSharpReference`1' requires compilation in order to run. Please ensure that the workflow has been compiled
I​ found code to compile the Expression before invoking the workflow and then I get errors like.
The type or namespace name 'Activities' does not exist in the namespace 'System'
I found some other code to set
AttachableMemberIdentifier and AttachablePropertyServices
then I got
The type or namespace name 'Activities' does not exist in the namespace 'System.ServiceModel'
​
E​ven though I'm adding the assemblyreferences for all 3 namespaces (my local solution, System.ServiceModel and System.Activities)​
The xamlx is the simple out of box one that it generates with GetData passing in an int and returns the int.ToString()
​What am I missing?
Code Following:
namespace WFStarterSolution
{
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class RestService
{
static void CompileExpressions(DynamicActivity activity)
{
var activityName = activity.Name;
// Split activityName into Namespace and Type.Append _CompiledExpressionRoot to the type name
// to represent the new type that represents the compiled expressions.
// Take everything after the last . for the type name.
var activityType = activityName.Split('.').Last() + "_CompiledExpressionRoot";
// Take everything before the last . for the namespace.
var activityNamespace = string.Join(".", activityName.Split('.').Reverse().Skip(1).Reverse());
// Create a TextExpressionCompilerSettings.
var settings = new TextExpressionCompilerSettings
{
Activity = activity,
Language = "C#",
ActivityName = activityType,
ActivityNamespace = activityNamespace,
RootNamespace = null,//"CSharpExpression",
GenerateAsPartialClass = false,
AlwaysGenerateSource = true,
ForImplementation = true
};
// Compile the C# expression.
var results = new TextExpressionCompiler(settings).Compile();
// Any compilation errors are contained in the CompilerMessages.
if (results.HasErrors)
{
var cm = results.CompilerMessages.Aggregate(" ", (current, e) => current + (e.Number + " - "+e.Message + " : Line Number "+e.SourceLineNumber + ""));
throw new Exception("Compilation failed."+cm);
}
// Create an instance of the new compiled expression type.
var compiledExpressionRoot =
Activator.CreateInstance(results.ResultType,
new object[] { activity }) as ICompiledExpressionRoot;
// Attach it to the activity.
CompiledExpressionInvoker.SetCompiledExpressionRoot(
activity, compiledExpressionRoot);
}
[OperationContract]
public string DoWork()
{
// call WFService XAMLX somehow
var filepath = AppDomain.CurrentDomain.BaseDirectory;
try
{
var serviceImplementation = XamlServices.Load(filepath + "WFService.xamlx");
var service = serviceImplementation as WorkflowService;
if (service == null)
{
return "Failed";
}
else
{
var activity = service.Body;
var operand1 = new InArgument();
var dyanamicActivity = new DynamicActivity { Name = "WFServiceName", Implementation = () => activity};
var p = new DynamicActivityProperty
{
Name = "data",
Type = typeof(InArgument),
Value = operand1
};
dyanamicActivity.Properties.Add(p);
var impl = new AttachableMemberIdentifier(typeof(TextExpression), "NamespacesForImplementation");
var namespaces = new List { "WFStarterSolution" };
var ar = new[]
{
new AssemblyReference
{
Assembly = typeof (DynamicActivity).Assembly
},
new AssemblyReference
{
Assembly = typeof (RestService).Assembly
},
new AssemblyReference
{
Assembly = typeof (ServiceContractAttribute).Assembly
}
};
TextExpression.SetReferencesForImplementation(dyanamicActivity, ar);
AttachablePropertyServices.SetProperty(dyanamicActivity, impl, namespaces);
CompileExpressions(dyanamicActivity);
var iDict = new Dictionary() { { "data", 45} };
var output = WorkflowInvoker.Invoke(dyanamicActivity, iDict);
return "success";
}
}
catch (Exception ex)
{
return ex.Message+""+ex.StackTrace;
}
}
}
}
UPDATE *
If I add the following in to the AssemblyReference array
,new AssemblyReference
{
Assembly = typeof (WorkflowService).Assembly
}
, it compiles fine... but still gives the me original error of
Expression Activity type 'CSharpReference`1' requires compilation in order to run. Please ensure that the workflow has been compiled

ICSharpCode.Decompiler + Mono.Cecil -> How to generate code for a single method?

I'm able to use Mono.Cecil and ICSharpCode.Decompiler to generate the code for a type or an assembly.
But if I try to generate the code for a single method I'll get an error "Object reference not set to an instance of an object."
Can you guys give me any hints about this? Thanks ahead for all the help.
Code to generate code for all the types inside an assembly:
DirectoryInfo di = new DirectoryInfo(appPath);
FileInfo[] allAssemblies = di.GetFiles("*.dll");
foreach (var assemblyFile in allAssemblies)
{
string pathToAssembly = assemblyFile.FullName;
System.Reflection.Assembly assembly = System.Reflection.Assembly.ReflectionOnlyLoadFrom(pathToAssembly);
Mono.Cecil.AssemblyDefinition assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(pathToAssembly,parameters);
AstBuilder astBuilder = null;
foreach (var typeInAssembly in assemblyDefinition.MainModule.Types)
{
if (typeInAssembly.IsPublic)
{
Console.WriteLine("T:{0}", typeInAssembly.Name);
//just reset the builder to include only code for a single type
astBuilder = new AstBuilder(new ICSharpCode.Decompiler.DecompilerContext(assemblyDefinition.MainModule));
astBuilder.AddType(typeInAssembly);
StringWriter output = new StringWriter();
astBuilder.GenerateCode(new PlainTextOutput(output));
string result = output.ToString();
output.Dispose();
}
}
}
Code to generate code for all the public methods inside an assembly:
DirectoryInfo di = new DirectoryInfo(appPath);
FileInfo[] allAssemblies = di.GetFiles("*.dll");
foreach (var assemblyFile in allAssemblies)
{
string pathToAssembly = assemblyFile.FullName;
System.Reflection.Assembly assembly = System.Reflection.Assembly.ReflectionOnlyLoadFrom(pathToAssembly);
Mono.Cecil.AssemblyDefinition assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(pathToAssembly,parameters);
AstBuilder astBuilder = null;
foreach (var typeInAssembly in assemblyDefinition.MainModule.Types)
{
if (typeInAssembly.IsPublic)
{
Console.WriteLine("T:{0}", typeInAssembly.Name);
foreach (var method in typeInAssembly.Methods)
{
//just reset the builder to include only code for a single method
astBuilder = new AstBuilder(new ICSharpCode.Decompiler.DecompilerContext(assemblyDefinition.MainModule));
astBuilder.AddMethod(method);
if (method.IsPublic && !method.IsGetter && !method.IsSetter && !method.IsConstructor)
{
Console.WriteLine("M:{0}", method.Name);
StringWriter output = new StringWriter();
astBuilder.GenerateCode(new PlainTextOutput(output));
string result = output.ToString();
output.Dispose();
}
}
}
}
}
I had the same problem. You should set the property CurrentType of the DecompilerContext. Change your code to
astBuilder = new AstBuilder(new ICSharpCode.Decompiler.DecompilerContext(assemblyDefinition.MainModule) { CurrentType = typeInAssembly } );
When I recently implemented a quick C# decompiler (MonoDecompiler based), I used the ILSpy methods :)
public string getSourceCode(MethodDefinition methodDefinition)
{
try
{
var csharpLanguage = new CSharpLanguage();
var textOutput = new PlainTextOutput();
var decompilationOptions = new DecompilationOptions();
decompilationOptions.FullDecompilation = true;
csharpLanguage.DecompileMethod(methodDefinition, textOutput, decompilationOptions);
return textOutput.ToString();
}
catch (Exception exception)
{
PublicDI.log.error("in getSourceCode: {0}", new object[] { exception.Message });
return ("Error in creating source code from IL: " + exception.Message);
}
}
For this and other examples see:
https://github.com/o2platform/O2.Platform.Scripts/blob/master/3rdParty/MonoCecil/CecilDecompiler/CecilDecompiler.cs
The stand-alone mini C# decompilation tool is created by this script https://github.com/o2platform/O2.Platform.Scripts/blob/master/3rdParty/MonoCecil/Utils/Tool%20-%20C%23%20Quick%20Decompiler.h2

Missing assembly references in dynamically compiled code

Thanks for the messages about my first post about this problem. I will do a repost and try to be more clear this time. I guess this may be a trivial problem but I'm really stuck and need some help. This is my first time posting here.
using System;
using System.CodeDom.Compiler;
using System.Reflection;
using Microsoft.CSharp;
namespace DynamicCode
{
public class DynaCore
{
string WorkingCode =
"using System;"+
"using System.Collections.Generic;"+
"namespace DynaCore"+
"{"+
" public class DynaCore"+
" {"+
" static public string DynamicResult()"+
" {"+
" return \"I'm compiled\";"+
" }"+
" }"+
"}";
string PredicateTemplCode =
"using System;"+
"using System.Linq;"+
"using System.Collections.Generic;"+
"namespace DynaCore"+
"{"+
" public class DynaCore"+
" {"+
" static public Func<{1}, bool> DynamicResult()"+
" {"+
" return new Func<{1}, bool>({2});"+
" }"+
" }"+
"}";
public DynaCore()
{
string compiledString = WorkingCompilation(WorkingCode);
Func<bool, bool> compiladePredicate = NotWorkingCompilation<bool>(PredicateTemplCode, "(o)=> true");
}
string WorkingCompilation(string code)
{
var cParams = new CompilerParameters();
cParams.GenerateInMemory = true;
cParams.TreatWarningsAsErrors = false;
cParams.GenerateExecutable = false;
cParams.CompilerOptions = "/optimize /target:library";
var curAss = Assembly.GetExecutingAssembly();
cParams.ReferencedAssemblies.Add("System.dll");
cParams.ReferencedAssemblies.Add("mscorlib.dll");
cParams.ReferencedAssemblies.Add("System.dll");
cParams.ReferencedAssemblies.Add("System.Data.dll");
cParams.ReferencedAssemblies.Add(curAss.Location);
var provider = new CSharpCodeProvider();
var compalerResult = provider.CompileAssemblyFromSource(cParams, code);
if (compalerResult.Errors.HasErrors)
{
var complieError = "";
foreach (CompilerError ce in compalerResult.Errors)
complieError += ce + " ";
throw new Exception(complieError.Trim());
}
Module module = compalerResult.CompiledAssembly.GetModules()[0];
Type mt = null;
MethodInfo methInfo = null;
return (string)module.GetType("DynaCore.DynaCore").GetMethod("DynamicResult").Invoke(null, null);
}
Func<T, bool> NotWorkingCompilation<T>(string code, string predicateString)
{
var cParams = new CompilerParameters();
cParams.GenerateInMemory = true;
cParams.TreatWarningsAsErrors = false;
cParams.GenerateExecutable = false;
cParams.CompilerOptions = "/optimize /target:library";
var curAss = Assembly.GetExecutingAssembly();
cParams.ReferencedAssemblies.Add("System.dll");
cParams.ReferencedAssemblies.Add("mscorlib.dll");
cParams.ReferencedAssemblies.Add("System.dll");
cParams.ReferencedAssemblies.Add("System.Data.dll");
cParams.ReferencedAssemblies.Add("System.Core.dll");
cParams.ReferencedAssemblies.Add(curAss.Location);
var provider = new CSharpCodeProvider();
var codeToRun = code.Replace("{1}", typeof(T).Name).Replace("{2}", predicateString);
var compalerResult = provider.CompileAssemblyFromSource(cParams, codeToRun);
if (compalerResult.Errors.HasErrors)
{
var complieError = "";
foreach (CompilerError ce in compalerResult.Errors)
complieError += ce + " ";
throw new Exception(complieError.Trim());
}
Module module = compalerResult.CompiledAssembly.GetModules()[0];
Type mt = null;
MethodInfo methInfo = null;
return (Func<T, bool>)module.GetType("DynaCore.DynaCore").GetMethod("DynamicResult").Invoke(null, null);
}
}
}
The problem is that when I reference System.Core.dll in ReferencedAssemblies.Add("System.Core.dll"), it gives me a compiler error:
error CS0006: Metadata file 'System.Core.dll' could not be found
I'm using v3.5 and VS 2008.
Thanks for all the answers!
It turns out that CSharpCodeProvider defaults to version 2.0 that have no support for generics or linq. The following fixed the problem:
var provider = new CSharpCodeProvider(
new Dictionary<String, String>{{ "CompilerVersion","v3.5" }});
I thought I'd update this thread since it was never properly answered. I just came across the same issue (CS0006), having to include a WPF library that was in the WPF directory, and wound up fixing it with the following:
string ver = string.Format("{0}.{1}.{2}", Environment.Version.Major, Environment.Version.MajorRevision, Environment.Version.Build);
string exWpfDir = string.Format(#"C:\WINDOWS\Microsoft.NET\Framework\v{0}\WPF", ver);
string exDir = string.Format(#"C:\WINDOWS\Microsoft.NET\Framework\v{0}", ver);
CSharpCodeProvider provider = new CSharpCodeProvider();
ICodeCompiler compiler = provider.CreateCompiler();
CompilerParameters compilerparams = new CompilerParameters();
compilerparams.GenerateExecutable = false;
compilerparams.GenerateInMemory = true;
compilerparams.IncludeDebugInformation = false;
compilerparams.TreatWarningsAsErrors = false;
compilerparams.CompilerOptions = string.Format("/lib:{0}", exWpfDir);
compilerparams.CompilerOptions = string.Format("/lib:{0}", exDir);
Another issue may be that System.Core.dll is actually in a different location than the other dlls mentioned.
On my machine, System.Core.dll is located in %ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll, whereas the other dlls are in the GAC.
Sometimes you need to add the referenced assembly to the CSharpCodeProvider parameters.
parameters.ReferencedAssemblies.Add("System.dll");
Hope this helps.
The resulting code
using System;
using System.Linq;
using System.Collections.Generic;
namespace DynaCore
{
public class DynaCore
{
static public Func<Boolean, bool> Main()
{
Func<Boolean, bool> retur = (o) => true;
}
}
}
does not compile itself when pasted into a new file. First compilation error is
'DynaCore.DynaCore.Main()': not all code paths return a value
First you need to generate code thats compiling when pasted into a empty .cs file.
The first obvious thing is to fix the func-statement into something like
return new Func<Boolean, bool>(o => true);
Edit:
And don't call the method Main.

Categories

Resources