public Assembly GetContractAssembly()
{
// Namespace creation
var ns = new CodeNamespace(ConfigurationManager.AppSettings["NamespaceToGenerate"]);
// Add useful "using"
ns.Imports.AddRange(
(from String s in ConfigurationManager.AppSettings["UsefulUsings"].Split(";".ToCharArray())
select new CodeNamespaceImport(s)).ToArray()
);
// Create the facade Service Contract
var inter = new System.CodeDom.CodeTypeDeclaration(ConfigurationManager.AppSettings["FacadeName"]);
inter.IsInterface = true;
inter.CustomAttributes.Add(new CodeAttributeDeclaration("System.ServiceModel.ServiceContract"));
// Add the facade service contract to the namespace
ns.Types.Add(inter);
// Build Fake Facade Service
var cls = new System.CodeDom.CodeTypeDeclaration(ConfigurationManager.AppSettings["ServiceName"]);
cls.BaseTypes.Add(inter.Name);
cls.IsClass = true;
ns.Types.Add(cls);
// Create Operation Contracts on the facade
foreach (String f in Directory.GetFiles(ConfigurationManager.AppSettings["DirectoryToMonitor"]))
CreateOperationContractAndImplementation(f, inter, cls);
}
method.Name = m.Name;
method.CustomAttributes.Add(
new CodeAttributeDeclaration(
"System.ServiceModel.OperationContract",
new CodeAttributeArgument(
new CodeSnippetExpression(
String.Format("Action=\"{0}/{1}/{2}/{3}\"",
t.Assembly.GetName().Name, t.FullName, m.Name, method.Name)
)
methodForService.Name = m.Name;
methodForService.Attributes = MemberAttributes.Public | MemberAttributes.Final;
private static void GenerateReturnValueIfNeeded(
MethodInfo m, CodeMemberMethod method, CodeMemberMethod methodForService)
if ("void" == m.ReturnType.Name.ToLower())
method.ReturnType = null;
methodForService.ReturnType = null;
else
if (!m.ReturnType.IsGenericType)
method.ReturnType = new CodeTypeReference(m.ReturnType.FullName);
methodForService.ReturnType = new CodeTypeReference(m.ReturnType.FullName);
CodeTypeReference[] typeArguments
= (from Type arg in m.ReturnType.GetGenericArguments()
select new CodeTypeReference(arg.FullName)).ToArray();
CodeTypeReference genericType = new CodeTypeReference(
m.ReturnType.GetGenericTypeDefinition().FullName.Split('`')[0], typeArguments);
method.ReturnType = genericType;
methodForService.ReturnType = genericType;
// Generate return
if (m.ReturnType.IsValueType)
methodForService.Statements.Add(new CodeMethodReturnStatement(
new CodeArgumentReferenceExpression(String.Format("default({0})", m.ReturnType.Name))));
methodForService.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null)));
private static void GenerateParameters(MethodInfo m, CodeMemberMethod method,
CodeMemberMethod methodForService)
foreach (ParameterInfo p in m.GetParameters())
CodeParameterDeclarationExpression exp = new CodeParameterDeclarationExpression(
p.ParameterType, p.Name);
method.Parameters.Add(exp);
methodForService.Parameters.Add(exp);
// Code management
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
StringBuilder CSharpCode = new StringBuilder();
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.IndentString = "\t";
provider.GenerateCodeFromNamespace(ns, new StringWriter(CSharpCode), options);
// Compiler options
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = false;
parameters.IncludeDebugInformation = false;
parameters.GenerateInMemory = true;
// Add useful References
parameters.ReferencedAssemblies.AddRange(
ConfigurationManager.AppSettings["AssembliesToReference"].Split(";".ToCharArray()));
// Tip to add specific reference to WCF since simple name (System.ServiceModel.dll) is not sufficient
parameters.ReferencedAssemblies.Add(typeof(ServiceHost).Assembly.Location);
// Parametrize generated Assembly
parameters.OutputAssembly = String.Format("{0}\\{1}.dll",
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
ConfigurationManager.AppSettings["NamespaceToGenerate"]);
// Launch compilation
CompilerResults results = provider.CompileAssemblyFromSource(parameters, CSharpCode.ToString());
if (results.Errors.Count != 0)
System.Console.WriteLine("Compilation errors!");
foreach (CompilerError error in results.Errors)
System.Console.WriteLine(error.ErrorText);
throw new Exception("Errors during compilation!");
provider.Dispose();
return results.CompiledAssembly;
namespace THB.Sample.ServiceContracts
using System;
using System.Reflection;
using System.ServiceModel;
using THB.Sample.ServiceModel.Extensions;
[System.ServiceModel.ServiceContract()]
public interface IFacade
[System.ServiceModel.OperationContract(
Action = "THB.Sample.Services/THB.Sample.Services.Service1/DoNothing/DoNothing")]
[THB.Sample.ServiceModel.Extensions.FacadeOperationBehavior()]
void DoNothing();
[System.ServiceModel.OperationContract(Action = "THB.Sample.Services/THB.Sample.Services.Service1/Add/Add")]
int Add(int i, int j);
[System.ServiceModel.OperationContract(Name = "Add1",
Action = "THB.Sample.Services/THB.Sample.Services.Service1/Add/Add1")]
int Add(int i, int j, int k);
[System.ServiceModel.OperationContract(Name = "Add2",
Action = "THB.Sample.Services/THB.Sample.Services.Service1/Add/Add2")]
int Add(int i, int j, int k, int l);
Action = "THB.Sample.Services/THB.Sample.Services.Service1/AddWithConstant/AddWithConstant")]
int AddWithConstant(int i);
Action = "THB.Sample.Services/THB.Sample.Services.Service1/Minus/Minus")]
int Minus(int i, int j);
[System.ServiceModel.OperationContract(Action = "THB.Sample.Services/THB.Sample.Services.Service1/Mult/Mult")]
int Mult(int i, int j);
[System.ServiceModel.OperationContract(Action = "THB.Sample.Services/THB.Sample.Services.Service1/Div/Div")]
int Div(int i, int j);
Action = "THB.Sample.Services2/THB.Sample.Services2.CustomerService/GetAll/GetAll")]
System.Collections.Generic.List<THB.Sample.DataContracts.Customer> GetAll();
Action = "THB.Sample.Services2/THB.Sample.Services2.CustomerService/GetOrders/GetOrders")]
System.Collections.Generic.List<THB.Sample.DataContracts.Order> GetOrders(int customerID);
[System.ServiceModel.OperationContract(Name = "Add3",
Action = "THB.Sample.Services2/THB.Sample.Services2.CustomerService/Add/Add3")]
void Add(THB.Sample.DataContracts.Customer c);
[System.ServiceModel.OperationContract(Name = "Add4",
Action = "THB.Sample.Services2/THB.Sample.Services2.CustomerService/Add/Add4")]
void Add(THB.Sample.DataContracts.Customer[] c);
Action = "THB.Sample.Services2/THB.Sample.Services2.CustomerService/GetArray/GetArray")]
THB.Sample.DataContracts.Customer[] GetArray();
public class Facade : IFacade
public void DoNothing()
public int Add(int i, int j)
return default(Int32);
public int Add(int i, int j, int k)
public int Add(int i, int j, int k, int l)
public int AddWithConstant(int i)
public int Minus(int i, int j)
public int Mult(int i, int j)
public int Div(int i, int j)
public System.Collections.Generic.List<THB.Sample.DataContracts.Customer> GetAll()
return null;
public System.Collections.Generic.List<THB.Sample.DataContracts.Order> GetOrders(int customerID)
public void Add(THB.Sample.DataContracts.Customer c)
public void Add(THB.Sample.DataContracts.Customer[] c)
public THB.Sample.DataContracts.Customer[] GetArray()