代码之家  ›  专栏  ›  技术社区  ›  Jaxidian

在T4模板中获取引用项目的路径?

  •  14
  • Jaxidian  · 技术社区  · 14 年前

    我有一个解决方案,其中有几个项目。我想在我的一个测试项目中创建一些T4模板,以便根据另一个项目中的代码生成测试。测试项目有一个对另一个项目的项目引用。我遇到的问题是,我不知道如何获取生成代码所需的edmx文件的文件路径。

    示例(假设这是一个基于ASCII的解决方案资源管理器):

    MySolution.sln
    -> MyTests.csproj (C:\a\b\c\)
    ----> GeneratedTests.tt (C:\a\b\c\GeneratedTests.tt)
    -> MyDAL.csproj (C:\x\y\z\)
    ----> MyModel.edmx (C:\x\y\z\MyModel.edmx)
    

    我的朋友会怎么做生成测试.tt能够获取的文件路径我的模型.edmx利用它的项目参考?

    6 回复  |  直到 14 年前
        1
  •  4
  •   Femaref    14 年前

    Host.ResolvePath 使用 VolatileAssembly 从工具箱中添加标签,以便能够在不重新启动(VS)的情况下重新编译它,并使用反射来处理模型。

        2
  •  15
  •   Michael L Perry    14 年前

    设置T4模板的“hostspecific”属性。这使您可以访问主机属性。键入cast Host到IServiceProvider以调用GetService(typeof(DTE))。这样可以遍历解决方案的内容。

    <#@ template language="c#" hostspecific="true"  #>
    <#@ assembly name="EnvDTE" #>
    <#@ import namespace="EnvDTE" #>
    These are the projects in this solution:
    <#
    var serviceProvider = this.Host as IServiceProvider;
    var dte = serviceProvider.GetService(typeof(DTE)) as DTE;
    foreach (Project p in dte.Solution.Projects)
    {
    #>
        <#=p.Name#> at <#=p.FullName#>
    <#
    }
    #>
    

    ITextTemplatingEngineHost interface on MSDN T4 Architecture by Oleg Synch .

        3
  •  11
  •   Community T.Woody    7 年前

    根据James Close的评论,我可以编写以下模板来调试我的文件路径:

    <#@ template language="C#" debug="true" hostspecific="true"#>
    <#@ include file="EF.Utility.CS.ttinclude"#><#@
     output extension=".txt"#><#
    
    /////////Some standard-ish settings, continue reading on
    CodeGenerationTools code = new CodeGenerationTools(this);
    MetadataLoader loader = new MetadataLoader(this);
    CodeRegion region = new CodeRegion(this, 1);
    MetadataTools ef = new MetadataTools(this);
    
    /////////Below are the relevant sections I used for debugging
    
        string solutionsPath = Host.ResolveAssemblyReference("$(SolutionDir)");//Gives you the location of MySolution.sln
        string edmxFile = solutionsPath + "MyDAL/MyDAL/MyModel.edmx"; //Note - VS projects usually have a subdir with the same name as the sln, hence the repetition for MyDAL
    #>
    Does this file exist?
    
    <#
    //
    if (File.Exists(edmxFile))
    {
        //Continue.
        #>
        Yes
        <#
    }
    else
    {
        #>
        No
        <#
    }
    #>
    

    这将生成一个.txt文件,并将很快帮助您调试是否可以找到您的路径。

    作为旁注,在存在相对dir路径的情况下(例如。 ../App.config )找不到,我发现它有助于放置一个文件(例如。 test1.txt )在每一个目录级别,我发现 Host.ResolvePath ../../App.config 可能决定 MySolution\App.config ,但是 ../../MyDal/README.txt 不会解析(因此找不到文件),即使路径正确。就我所见,上面的代码似乎否定了这个问题。

    How to use the poco entity generator

        4
  •  5
  •   Mina W Alphonce    14 年前

    用这些线

    string path = this.Host.ResolvePath("");
    Directory.SetCurrentDirectory(path);
    

    e、 g,字符串inputFile=@“\Modal.edmx";

        5
  •  3
  •   codingdave    7 年前

    根据米娜和其他人的回答,我提出了这个解决方案。它列出当前工作目录、解决方案路径,并使用Mina的技巧更改活动工作目录。

    <#@ template debug="true" hostspecific="true" language="C#" #>
    <#@ output extension=".cs" #>
    <#@ import namespace="System.IO" #>
    <#@ assembly name="EnvDTE" #>
    <#@ import namespace="EnvDTE" #>
    <#
     string cwd1 = System.IO.Directory.GetCurrentDirectory();
     string solutionPath = Host.ResolveAssemblyReference("$(SolutionDir)");
     Directory.SetCurrentDirectory(solutionPath);
     string cwd2 = System.IO.Directory.GetCurrentDirectory();
    #>
    // Solutionpath is:<#= solutionPath #>, old cwd: <#= cwd1 #>, new cwd: <#= cwd2 #>
    
        6
  •  1
  •   Mark H    14 年前

    $(ProjectDir) $(SolutionDir) 从模板中,或者读取.sln或.csproj文件以提取其他项目的目录。