如何在Template Codes 中能够加载所在的Project的Assembly,获取所有Type
1.首先要获取Project对象
2.分析得到Project对象生成的bin路径,也就是$(TargetPath)
3.Assembly.LoadFromFile( binpath )
4.asm.GetTypes(),这里要注意处理Reference Project
代码如下:
1.GetProject()
Project GetProject() { var hostServiceProvider = (IServiceProvider)this.Host; var dte = (DTE)hostServiceProvider.GetService(typeof(DTE)); var item = dte.Solution.FindProjectItem(this.Host.TemplateFile); if (item != null && item.ContainingProject != null) { return item.ContainingProject; } return null; }
2.GetAssemblyPath,GetAssemblyDir(获取bin目录)
string GetAssemblyPath(EnvDTE.Project vsProject) { string fullPath = vsProject.Properties.Item("FullPath").Value.ToString(); string outputPath = vsProject.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString(); string outputDir = Path.Combine(fullPath, outputPath); string outputFileName = vsProject.Properties.Item("OutputFileName").Value.ToString(); string assemblyPath = Path.Combine(outputDir, outputFileName); return assemblyPath; } string GetAssemblyDir(EnvDTE.Project vsProject) { string fullPath = vsProject.Properties.Item("FullPath").Value.ToString(); string outputPath = vsProject.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString(); string outputDir = Path.Combine(fullPath, outputPath); return outputDir; }
3.获取asm中所有interface
Type[] GetInterfaces() { var p = GetProject(); string str = GetAssemblyPath(p); var asm = Assembly.LoadFile(str); Type[] tps = new Type[]{}; try { tps = asm.GetTypes(); } catch (ReflectionTypeLoadException ex) { foreach (Exception loaderException in ex.LoaderExceptions) { WriteLine(loaderException.ToString()); } } return tps.ToOtherTypeArrayEx(i=>i.IsInterface,i=>i); }
最后要注意Reference :
<# AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; #> <#+ System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { var strDllDir = GetAssemblyDir(GetProject()); var strs = args.Name.Split(','); var strNeedResolveDllPath = strDllDir + strs[0] + ".dll"; if (System.IO.File.Exists(strNeedResolveDllPath)) return Assembly.LoadFile(strNeedResolveDllPath); return null; } #>
一些参考:
http://msdn.microsoft.com/en-us/library/envdte.dte.aspx
http://msdn.microsoft.com/en-us/library/vstudio/gg604090(v=vs.100).aspx
http://stackoverflow.com/questions/3548026/get-referenced-projects-path-in-t4-template
http://stackoverflow.com/questions/12952110/accessing-projects-via-dte-in-c-sharp-t4-template
http://stackoverflow.com/questions/5486593/getting-the-macro-value-of-projects-targetpath-via-dte
http://social.msdn.microsoft.com/Forums/vstudio/en-US/03d9d23f-e633-4a27-9b77-9029735cfa8d/how-to-get-the-right-output-path-from-envdteproject-by-code-if-show-advanced-build?forum=vsx