I came along later with the same question, found the accepted solution above, and decided to add more info and detail here regarding how I used reflection and other features to generate interfaces in source code programatically. (Skip this first block of code if you don't care for marking your source with custom attributes for code generation)
For flexibility I created custom Attributes named GenerateInterface and GenerateInterfaceMember (simply my own creations) to mark my classes and members for parts I want explicitly exported to interfaces (or you can just export all the public members by default, whatever you like). For example, I apply my attributes like this to a Store class...
[GenerateInterface(InterfaceName="IStore", NamespaceName="Com.Example.GenerationTest")]
class Store : BusinessObject {
string _name;
[GenerateInterfaceMember]
public event EventHandler handler;
internal Store(IDomain domain, string name)
: base(domain) {
_name = name;
}
[GenerateInterfaceMember]
public string GetSomething(int a, int b, Random r, Store s) {
throw new NotImplementedException();
}
//etc...
For info on custom Attributes see MSDN.
The Code Generation Stuff...
Note: You can do all the following without using custom attributes shown above.
I used reflection to iterate over types and members. You'll want to just grab all the public members on your classes as the candidates for creating interfaces from.
After acquiring System.Reflection.PropertyInfo, .MethodInfo, etc. instances on the System.Type's using reflection I then created a Code Compile Unit which is language agnostic and is represented by the class System.CodeDom.CodeCompileUnit, of which MSDN has good example code - see it here.. The code compile unit instance is what you need to build out to describe the source code you want to generate in a language-independent fashion.
Once you have created a CodeCompileUnit instance you can feed it to various FCL methods to meet your needs, like generating source code, emitting MSIL code in memory or to disk etc. To generate source code I used System.CodeDom.Compiler.CodeDomProvider See the MSDN sample in addition to the solution hacked together below...
The CodeDomProvider is where things get language-specific - those languages are nested under the Microsoft namespace, for example:
using Microsoft.CSharp; // for C#
using Microsoft.VisualBasic; // for VB.NET
There are a couple of ways to create a CodeDomProvider instance, like the MSDN code sample here shows a static method '.CreateProvider':
CodeDomProvider provider = null;
// snip...
case "CSharp":
provider = CodeDomProvider.CreateProvider("CSharp");
break;
case "Visual Basic":
provider = CodeDomProvider.CreateProvider("VisualBasic");
break;
Alternatively you can directly instantiate a provider
Microsoft.CSharp.CSharpCodeProvider csProvider = new CSharpCodeProvider();
Microsoft.VisualBasic.VBCodeProvider vbProvider = new VBCodeProvider();
Use methods on the provider instance like provider.GenerateCodeFromCompileUnit(..) and feed your CodeCompileUnit instance to it. This sample code generates C# source code to a StringBuilder instance.
// me setting up string capture for my purposes
StringBuilder szBuilder = new StringBuilder();
StringWriter writer = new StringWriter(szBuilder);
// the key statement - writes c# code to StringBuilder using provider instance and compile unit instance
csProvider.GenerateCodeFromCompileUnit(compileUnit, writer, new CodeGeneratorOptions());
// solidifying the generated C# code into one string
string sourceCode = szBuilder.ToString();
// can write this string to a file, etc....
And there you have generated source code.
I end up with something that looks like this when outputting the sourceCode string. It's nice Microsoft prepends the comments about an auto-generated file - makes it feel more "offical" methinks.
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.4200
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Com.Example.GenerationTest {
using System;
using Com.Example.BusinessCore;
public interface IStore {
string Name {
get;
set;
}
event System.EventHandler handler;
string GetSomething(int a, int b, System.Random r, Store s);
}
}
My little disclaimer: There are many ways to generate and emit code. Shown here is one way to generate source code programmatically. Some methods have overloads and take complex arguments - you'll have to look up intricacies in MSDN. Some methods have changed between 1.1, 2.0 etc. Lastly, some ways of accomplishing code generation are obsolete and have been supplanted by alternate means; MSDN notes all these things.
Hopefully the code shown here acts as a guide to start moving ahead with generating interfaces programmatically, or generating any kind of code for that matter.
Note: This example doesn't show how to integrate the generated source code with existing code, or how to emit it into MSIL or append to existing assembly files - other answers I see posted show samples relating to those kinds of solutions.