如何在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



posted on 2014-02-08 18:47  norsd  阅读(152)  评论(0编辑  收藏  举报

导航