Reputation: 8336
I have an interop-class and it's really cumbersome to add functionality to it, because it involves so many lines. Let's say I need to have method to get id by id i gotta do following:
public class MyInterop
{
public class WCFDTypes
{
//....
public delegate int GetInt_Delegate(int id);
//...
}
public class DTypes
{
//....
public delegate int DotNetInterface_GetInt_Delegate(int id);
//...
}
public WCFDTypes.GetInt_Delegate GetInt;
//...
private DTypes.DotNetInterface_GetPlotLabel_Delegate Nat_GetInt;
//...
public MyInterop(string moduleName)
{
DelegateBuilder builder = new DelegateBuilder(moduleName);
//...
Nat_GetInt = Build<DTypes.DotNetInterface_GetInt_Delegate>(builder);
//..
}
//...
GetInt = (int id) =>
{
return NatGetInt(id);
}
public MyInterop(string moduleName)
{
//...
Nat_GetInt = Build<DTypes.DotNetInterface_GetInt_Delegate>(builder);
//..
}
public MyInterop(MyApplication, string address)
{
//...
GetInt = client.GetInt;
//..
}
}
Explaining this is beyond the scope of this question. I would just like to know how to generate something, even without return types or parameters just non-variable parts (of course based on fucntionality name like GetInt) to correct places (to both inner classes, 2 method declarations and to 2 constructors).
I was looking into snippets, but examples I found were very basic.
Upvotes: 0
Views: 408
Reputation: 607
You can read the delegate definition from an assembly using classes in System.Reflection.
Assembly asm = Assembly.LoadFrom(assemblyFile); // path to file
Type[] types = asm.GetTypes();
Here it is suggested you can recognize delegate types with a method like:
public bool IsDelegate(Type type)
{
return type.IsSubClassOf(typeof(Delegate)) || type==typeof(Delegate);
}
Or use GetType(string) to load a type whose name you know.
And here Microsoft notes (emphasis mine):
The common language runtime provides an Invoke method for each delegate type, with the same signature as the delegate. You do not have to call this method explicitly from C#, Visual Basic, or Visual C++, because the compilers call it automatically. The Invoke method is useful in reflection when you want to find the signature of the delegate type.
So use something like this to get a MethodInfo that tells you the param and return type of the delegate:
MethodInfo methodInfo = delegateType.GetMethod("Invoke");
Knowing these I expect you can now generate what you need. It's possible to generate a method at runtime. See here or search for "Emitting Dynamic Methods and Assemblies".
But you could instead write source code (like your snippet) to a file for later compilation, and if you wish you can automate the compilation with System.CodeDom.Compiler, for example:
CodeDomProvider provider = CodeDomProvider.CreateProvider("CS"); // source language
CompilerParameters compParams = new CompilerParameters();
compParams.IncludeDebugInformation = true;
foreach (string refAsm in referencedAssemblies) {
compParams.ReferencedAssemblies.Add(refAsm);
}
// etc
CompilerResults res = provider.CompileAssemblyFromSource(compParams, codeSource);
if (res.Errors.Count > 0) {
// display & throw
}
Note codeSource
here is not the path to a source file, but one or more strings containing the actual source code. So you could even generate and compile the source without the intermediate step of writing it to a file.
Upvotes: 1