It is possible to solve you problem with usage of Reflection:
a) Use Reflection to enumerate all public methods from classes of your interests, for example:
var methods = typeof(SomeClass).GetMethods(BindingFlags.Instance | BindingFlags.Public);
b) Use this list to generate a source code for your service into a string
StringBuilder source = new StringBuilder();
source.AppendLine("using System;");
source.AppendLine("using System.ServiceModel;");
source.AppendLine("[ServiceContract]");
source.AppendLine("public class DynamicService {");
// Here for each MethodInfo from list generate a method source like
foreach (var method in methods)
{
if (method.ReturnType == typeof(void))
continue;
string parameters = string.Join(", ", method.GetParameters().Select(pi => string.Format("{0} {1}", pi.ParameterType.Name, pi.Name)));
string arguments = string.Join(", ", method.GetParameters().Select(pi => pi.Name));
source.AppendFormat("[OperationContract]");
source.AppendFormat("public {0} {1}({2})", method.ReturnType.Name, method.Name, parameters);
source.AppendFormat("{{ return ConsoleApplication.Helpers.{0}({1}); }}", method.Name, arguments);
}
source.AppendLine("}");
Note: You will need some filtering here, for example to filter out ToString
etc. As a example I bypass all void methods.
c) use CSharpCodeProvider
to compile service source:
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
System.CodeDom.Compiler.CompilerParameters param = new CompilerParameters();
param.GenerateExecutable = false;
param.GenerateInMemory = true;
param.ReferencedAssemblies.Add("System.Runtime.Serialization.dll");
param.ReferencedAssemblies.Add("System.ServiceModel.dll");
param.ReferencedAssemblies.Add("System.dll");
param.ReferencedAssemblies.Add("ConsoleApplication.exe");
CompilerResults result = codeProvider.CompileAssemblyFromSource(param, source.ToString());
Note: Here you can add reference to assemblies containing your helper classes, ConsoleApplication.exe
in my example.
d) use your dynamic service as a normal one. For example you can self-host it:
if (!result.Errors.HasErrors)
{
Type type = result.CompiledAssembly.GetType("DynamicService");
var instance = Activator.CreateInstance(type);
Uri baseAddress = new Uri("http://localhost:80/hello");
using (ServiceHost host = new ServiceHost(type, baseAddress))
{
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
host.Open();
Console.WriteLine("The service is ready at {0}", baseAddress);
Console.WriteLine("Press <Enter> to stop the service.");
Console.ReadLine();
// Close the ServiceHost.
host.Close();
}
}
e) and then you have it:

f) if you want to host this service in IIS, you will have to provide your own custom ServiceHostFactory