Skip to content

Instantly share code, notes, and snippets.

@RobinHerbots
Created April 26, 2012 12:42
Show Gist options
  • Save RobinHerbots/2499308 to your computer and use it in GitHub Desktop.
Save RobinHerbots/2499308 to your computer and use it in GitHub Desktop.
Proxy generation template
/*
== DO NOT EDIT THIS GENERATED FILE ==
Generated on <#=DateTime.Now.ToShortDateString()#> at <#=DateTime.Now.ToShortTimeString()#>
*/
<#@ template hostspecific="True" #>
<#@ assembly name="System.ServiceModel.dll" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="EnvDTE" #>
<#@ assembly name="Microsoft.VisualStudio.OLE.Interop" #>
<#@ assembly name="Microsoft.VisualStudio.Shell" #>
<#@ assembly name="Microsoft.VisualStudio.Shell.Interop" #>
<#@ assembly name="Microsoft.VisualStudio.Shell.Interop.8.0" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.ServiceModel" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="Microsoft.VisualStudio.Shell" #>
<#@ import namespace="Microsoft.VisualStudio.Shell.Interop" #>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
<# ReadOutServiceContracts(); #>
<#+
string GenerateProxy(Type serviceType)
{
String indent = "\t";
StringBuilder sb = new StringBuilder();
sb.AppendFormat("/* {0} */\n", serviceType.Name);
string nsExt = serviceType.Namespace.Replace("ServiceLayer.ServiceContracts" , string.Empty);
sb.AppendFormat("namespace PresentationLayer.ServiceProxies{0}\n{{\n", nsExt);
sb.AppendFormat("internal class {0}Proxy : PooledProxyBase<{1}>, {1}", serviceType.Name.Substring(1), serviceType.FullName);
sb.AppendLine("{");
foreach(MethodInfo mi in serviceType.GetMethods()){
string returnType = mi.ReturnType.FullName;
if(mi.ReturnType == typeof(void))
returnType = "void";
else if(mi.ReturnType.IsGenericType && mi.ReturnType.GetGenericTypeDefinition().FullName == "System.Collections.Generic.List`1")
returnType = string.Format("System.Collections.Generic.List<{0}>", mi.ReturnType.GetGenericArguments()[0].FullName);
sb.AppendFormat("public {0} {1}(", returnType, mi.Name);
ParameterInfo[] pis = mi.GetParameters();
for(int i = 0;i < pis.Length; i++){
sb.AppendFormat("{0} {1}", pis[i].ParameterType.FullName, pis[i].Name);
if(i+1 < pis.Length)
sb.Append(", ");
}
sb.AppendLine(") {");
if(mi.ReturnType == typeof(void))
sb.AppendFormat("Channel(\"{0}\"", mi.Name);
else
sb.AppendFormat("return Channel<{0}>(\"{1}\"", returnType, mi.Name);
for(int i = 0;i < pis.Length; i++){
sb.Append(", ");
sb.AppendFormat("{0}", pis[i].Name);
}
sb.AppendLine(");");
sb.AppendLine("}");
}
sb.AppendLine("}");
sb.AppendLine("}");
return sb.ToString();
}
string GenerateController(Type serviceType)
{
String indent = "\t";
StringBuilder sb = new StringBuilder();
sb.AppendFormat("/* {0} */\n", serviceType.Name);
string nsExt = serviceType.Namespace.Replace("ServiceLayer.ServiceContracts" , string.Empty);
sb.AppendFormat("namespace PresentationLayer.ServiceProxies{0}\n{{\n", nsExt);
sb.AppendFormat("public class {0}Controller : ServiceControllerBase, {1}", serviceType.Name.Substring(1), serviceType.FullName);
sb.AppendLine("{");
foreach(MethodInfo mi in serviceType.GetMethods()){
string returnType = mi.ReturnType.FullName;
if(mi.ReturnType == typeof(void))
returnType = "void";
else if(mi.ReturnType.IsGenericType && mi.ReturnType.GetGenericTypeDefinition().FullName == "System.Collections.Generic.List`1")
returnType = string.Format("System.Collections.Generic.List<{0}>", mi.ReturnType.GetGenericArguments()[0].FullName);
sb.AppendFormat("public {0} {1}(", returnType, mi.Name);
ParameterInfo[] pis = mi.GetParameters();
for(int i = 0;i < pis.Length; i++){
sb.AppendFormat("{0} {1}", pis[i].ParameterType.FullName, pis[i].Name);
if(i+1 < pis.Length)
sb.Append(", ");
}
sb.AppendLine(") {");
sb.AppendFormat("using (var proxy = new {0}Proxy())",serviceType.Name.Substring(1));
sb.AppendLine("{");
if(mi.ReturnType == typeof(void))
sb.AppendFormat("proxy.{0}(", mi.Name);
else sb.AppendFormat("return proxy.{0}(", mi.Name);
for(int i = 0;i < pis.Length; i++){
sb.AppendFormat("{0}", pis[i].Name);
if(i+1 < pis.Length)
sb.Append(", ");
}
sb.AppendLine(");");
sb.AppendLine("}\n}");
}
sb.AppendLine("}");
sb.AppendLine("}");
return sb.ToString();
}
void ReadOutServiceContracts(){
DeleteOldOutputs();
IServiceProvider hostServiceProvider = (IServiceProvider)Host;
EnvDTE.DTE dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
string solutionPath = Path.GetDirectoryName(dte.Solution.FullName);
byte[] sasBytes = File.ReadAllBytes(string.Format(@"{0}\Projects\Service Layer\ServiceContracts\bin\Debug\ServiceLayer.ServiceContracts.dll", solutionPath));
byte[] dasBytes = File.ReadAllBytes(string.Format(@"{0}\Projects\Service Layer\ServiceContracts\bin\Debug\ServiceLayer.DataContracts.dll", solutionPath));
byte[] uasBytes = File.ReadAllBytes(string.Format(@"{0}\Projects\Service Layer\ServiceContracts\bin\Debug\Framework.Utilities.dll", solutionPath));
byte[] basBytes = File.ReadAllBytes(string.Format(@"{0}\Projects\Service Layer\ServiceContracts\bin\Debug\BusinessEntities.dll", solutionPath));
Assembly sas = Assembly.Load(sasBytes);
Assembly das = Assembly.Load(dasBytes);
Assembly uas = Assembly.Load(uasBytes);
Assembly bas = Assembly.Load(basBytes);
Type[] servicesTypes = sas.GetTypes();
foreach (Type serviceType in servicesTypes)
{
foreach(Attribute attribute in serviceType.GetCustomAttributes(typeof(ServiceContractAttribute), true)){
SaveOutput(serviceType.Name.Substring(1) + "Proxy.cs", GenerateProxy(serviceType));
SaveOutput(serviceType.Name.Substring(1) + "Controller.cs", GenerateController(serviceType));
}
}
DeleteOldOutputs();
}
List<string> __savedOutputs = new List<string>();
Engine __engine = new Engine();
void DeleteOldOutputs()
{
EnvDTE.ProjectItem templateProjectItem = __getTemplateProjectItem();
foreach (EnvDTE.ProjectItem childProjectItem in templateProjectItem.ProjectItems)
{
if (!__savedOutputs.Contains(childProjectItem.Name))
childProjectItem.Delete();
}
}
void SaveOutput(string outputFileName, string content){
string templateDirectory = Path.GetDirectoryName(Host.TemplateFile);
string outputFilePath = Path.Combine(templateDirectory, outputFileName);
File.WriteAllText(outputFilePath, content);
ProjectItem templateProjectItem = __getTemplateProjectItem();
templateProjectItem.ProjectItems.AddFromFile(outputFilePath);
__savedOutputs.Add(outputFileName);
}
EnvDTE.ProjectItem __getTemplateProjectItem()
{
EnvDTE.Project dteProject = __getTemplateProject();
IVsProject vsProject = __dteProjectToVsProject(dteProject);
int iFound = 0;
uint itemId = 0;
VSDOCUMENTPRIORITY[] pdwPriority = new VSDOCUMENTPRIORITY[1];
int result = vsProject.IsDocumentInProject(Host.TemplateFile, out iFound, pdwPriority, out itemId);
if (result != VSConstants.S_OK)
throw new Exception("Unexpected error calling IVsProject.IsDocumentInProject");
if (iFound == 0)
throw new Exception("Cannot retrieve ProjectItem for template file");
if (itemId == 0)
throw new Exception("Cannot retrieve ProjectItem for template file");
Microsoft.VisualStudio.OLE.Interop.IServiceProvider itemContext = null;
result = vsProject.GetItemContext(itemId, out itemContext);
if (result != VSConstants.S_OK)
throw new Exception("Unexpected error calling IVsProject.GetItemContext");
if (itemContext == null)
throw new Exception("IVsProject.GetItemContext returned null");
ServiceProvider itemContextService = new ServiceProvider(itemContext);
EnvDTE.ProjectItem templateItem = (EnvDTE.ProjectItem)itemContextService.GetService(typeof(EnvDTE.ProjectItem));
return templateItem;
}
EnvDTE.Project __getTemplateProject()
{
IServiceProvider hostServiceProvider = (IServiceProvider)Host;
if (hostServiceProvider == null)
throw new Exception("Host property returned unexpected value (null)");
EnvDTE.DTE dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
if (dte == null)
throw new Exception("Unable to retrieve EnvDTE.DTE");
Array activeSolutionProjects = (Array)dte.ActiveSolutionProjects;
if (activeSolutionProjects == null)
throw new Exception("DTE.ActiveSolutionProjects returned null");
EnvDTE.Project dteProject = (EnvDTE.Project)activeSolutionProjects.GetValue(0);
if (dteProject == null)
throw new Exception("DTE.ActiveSolutionProjects[0] returned null");
return dteProject;
}
static IVsProject __dteProjectToVsProject(EnvDTE.Project project)
{
if (project == null)
throw new ArgumentNullException("project");
string projectGuid = null;
// DTE does not expose the project GUID that exists at in the msbuild project file.
// Cannot use MSBuild object model because it uses a static instance of the Engine,
// and using the Project will cause it to be unloaded from the engine when the
// GC collects the variable that we declare.
using (XmlReader projectReader = XmlReader.Create(project.FileName))
{
projectReader.MoveToContent();
object nodeName = projectReader.NameTable.Add("ProjectGuid");
while (projectReader.Read())
{
if (Object.Equals(projectReader.LocalName, nodeName))
{
projectGuid = (string)projectReader.ReadElementContentAsString();
break;
}
}
}
if (string.IsNullOrEmpty(projectGuid))
throw new Exception("Unable to find ProjectGuid element in the project file");
Microsoft.VisualStudio.OLE.Interop.IServiceProvider dteServiceProvider =
(Microsoft.VisualStudio.OLE.Interop.IServiceProvider)project.DTE;
IServiceProvider serviceProvider = new ServiceProvider(dteServiceProvider);
IVsHierarchy vsHierarchy = VsShellUtilities.GetHierarchy(serviceProvider, new Guid(projectGuid));
IVsProject vsProject = (IVsProject)vsHierarchy;
if (vsProject == null)
throw new ArgumentException("Project is not a VS project.");
return vsProject;
}
#>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment