2014-09-23 18 views
13

Tôi có một tập lệnh .tt cần tham khảo một vài cụm ngoài.Sử dụng tham chiếu dự án làm đường dẫn lắp ráp trong T4

Máy chủ T4 có thể tự động bao gồm các cụm được tham chiếu trong dự án - chứ không phải là tôi thêm thủ công chỉ thị lắp ráp cho từng dự án?

Ví dụ: Việc tham chiếu một assembly từ một nuget là một mục tiêu di chuyển khi sử dụng một đường dẫn tương ứng với $(ProjecDir).

Sử dụng đường dẫn lắp ráp như $(Project)\bin\Debug\Example.dll cũng có vẻ ít hơn tối ưu - vì nó đòi hỏi phải xây dựng như đã thành công trước đó - mà có lẽ không phải là trường hợp nếu bạn có một tập tin .tt tạo ra các "ErrorGeneratingOutput" trong một cs nộp! ?

Cập nhật 1:

Vì vậy, tôi đã có một đâm thứ hai tại đây nhưng lần này cố gắng để giải quyết vấn đề xung quanh "TransformOnBuild" (như một mặt lưu ý Tôi rất có thể giới thiệu dự án tuyệt vời @ kzu của: https://github.com/clariuslabs/TransformOnBuild) và không có $ (SolutionDir) có sẵn khi không chạy TextTransform thông qua trực tiếp từ msbuild. Dù sao - tôi đã đưa ra một giải pháp 2 bước.

  1. Mục tiêu msbuild sử dụng danh sách mới tập hợp chỉ thị dựa trên các tham chiếu được tìm thấy trong tệp csproj.

  2. Bất kỳ tệp .tt nào khác trong dự án đều có thể bao gồm tệp được tạo tự động để đăng ký hội đồng dự án.

Dưới đây là một ví dụ về mục tiêu:

<Target Name="Write_AssemblyRefs_TT" BeforeTargets="TransformOnBuild"> 
    <!-- A message for all to enjoy! --> 
    <WriteLinesToFile File="@(MyTextFile)" 
    Lines="&lt;# /* AUTOGENERATED BY MSBUILD and Kern Herskind Nightingale */ #&gt;" 
    Overwrite="true" 
    Encoding="Unicode" /> 
    <!-- Output all assembly references with a HintPath --> 
    <WriteLinesToFile File="@(MyTextFile)" 
    Lines="&lt;#@ assembly name=&quot;$(ProjectDir)%(Reference.HintPath)&quot; #&gt;" 
    Overwrite="false" 
    Encoding="Unicode" 
    Condition="'%(Reference.HintPath)' != ''" /> 
    <!-- Output all project references - this could fail with custom nameing/build output dirs --> 
    <WriteLinesToFile File="@(MyTextFile)" 
    Lines="&lt;#@ assembly name=&quot;$(ProjectDir)%(ProjectReference.RelativeDir)bin\$(Configuration)\%(ProjectReference.Name).dll&quot; #&gt;" 
    Overwrite="false" 
    Encoding="Unicode" /> 
</Target> 
<ItemGroup> 
    <MyTextFile Include="AssemblyRefs.tt" /> 
</ItemGroup> 

Và làm thế nào để đưa nó vào trong file T4 (tầm thường):

<#@ include file="AssemblyRefs.tt" #> 

thế hệ Mã cho máy phát điện mã :)

Cập nhật 2:

Tôi đã tạo gói Nuget để dễ dàng thêm mục tiêu xây dựng thế hệ chỉ thị lắp ráp ở trên: https://www.nuget.org/packages/AssemblyReferencesTT/1.0.12

+0

Wonder nếu $ (libDir) kỹ thuật được mô tả ở đây có thể là một phần của giải pháp: http : //blogs.msdn.com/b/t4/archive/2013/08/29/what-s-new-in-t4-for-visual-studio-2013.aspx – herskinduk

+0

herskinduk, tôi không thể tìm thấy cách nào để làm điều đó, tuy nhiên nó sẽ không thể tạo ra một tập tin tt với đường dẫn chính xác, sau đó xây dựng thứ được tạo ra tập tin tt? – samy

+0

@samy Tôi cho rằng điều đó là có thể. Về cơ bản điều này xuất phát từ sự cần thiết phải phân phối một tập tin .tt thông qua nuget. Nó sẽ là siêu slick nếu tôi chỉ có thể sử dụng Nuget để quản lý các phụ thuộc - điều này sẽ yêu cầu T4 để có thể tải các tài liệu tham khảo dự án mặc dù. Có lẽ MEF là câu trả lời? – herskinduk

Trả lời

3

tôi đã đăng nhận xét này nếu tôi có thể.

cho câu hỏi: không thể bao gồm các hội đồng được tham chiếu trong dự án tự động, nhưng bạn có thể giới hạn công việc bạn phải làm.

nếu bạn thấy bên dưới liên kết trong đề xuất số 1, bạn có thể sử dụng C# để xác định mã assembly trước khi nó được đọc bởi t4. mà làm cho nó có thể đọc một thư mục với sự phản ánh và tải mỗi lắp ráp ở đó.so câu hỏi là nơi lắp ráp của bạn sẽ được?

List<Assembly> allAssemblies = new List<Assembly>(); 
string path = Assembly.GetExecutingAssembly().Location; 

foreach (string dll in Directory.GetFiles(path, "*.dll")) 
    allAssemblies.Add(Assembly.LoadFile(dll)); 
    <#@ assembly name=dll #> 

điều này chưa được kiểm tra nhưng sẽ giúp bạn bắt đầu ít nhất. để tham khảo ->how to load all assemblies from within your /bin directory

cho phần thứ hai:

  1. sử dụng $(SolutionDir) nhưng đây là giống như $ (Dự án) ai ngoại trừ một mức độ thấp hơn. ->How do I use custom library/project in T4 text template?
  2. sử dụng tiện ích đường dẫn C# để điều hướng đến đường dẫn mong muốn trong thời gian chạy, nhưng một lần nữa điều này có thể yêu cầu lắp ráp để biên dịch trước.
  3. Đăng ký Thư viện bên ngoài trong GAC. đường nối này để giải quyết vấn đề của bạn nhiều nhất vì bạn sẽ không phải đặt đường dẫn nào cả. xem ->How to register a .Net dll in GAC?

Chỉnh sửa: đây là một động lực hoạt động bao gồm. chỉ cần tham khảo kết quả của .ttinclude được tạo bởi điều này trong bất kỳ tệp .tt

tôi đã thử nghiệm nó với trình gỡ lỗi và có vẻ như nó hoạt động.

và thay đổi bản địa hóa lắp ráp để trỏ đến nơi bạn cần.

<#@ template debug="false" hostspecific="false" language="C#" #> 
<#@ assembly name="System.Core" #> 
<#@ assembly name="System.Net.Http" #> 
<#@ import namespace="System.Linq" #> 
<#@ import namespace="System.Text" #> 
<#@ import namespace="System.Collections.Generic" #> 
<#@ import namespace="System.Reflection" #> 
<#@ import namespace="System.IO" #> 
<#@ output extension=".ttinclude" #><# 

List<Assembly> allAssemblies = new List<Assembly>(); 
string file = Assembly.GetExecutingAssembly().Location; 
if(file!= "") 
{ 
    string path = Path.GetDirectoryName(file).TrimEnd(); 
    if(path != "") 
     foreach (string dll in Directory.GetFiles(path, "*.dll")) 
     { 
      if(dll != "") 
      { 
       allAssemblies.Add(Assembly.LoadFile(dll)); 
       #>\<#<#= "@ assembly name=\""+ dll +"\" "#>\#><#="\n"#><# 
      } 
     } 
} 

#> 

đầu ra:

<#@ assembly name="C:\TEMP\3mo0m0mq.dll" #> 
<#@ assembly name="C:\TEMP\4ybsqre3.dll" #> 
<#@ assembly name="C:\TEMP\ao0bzedf.dll" #> 
<#@ assembly name="C:\TEMP\bo2w102t.dll" #> 
<#@ assembly name="C:\TEMP\c5o2syvv.dll" #> 
<#@ assembly name="C:\TEMP\dz1fin10.dll" #> 
<#@ assembly name="C:\TEMP\giym0gef.dll" #> 
<#@ assembly name="C:\TEMP\hjfgqkov.dll" #> 
<#@ assembly name="C:\TEMP\ibuz4wvb.dll" #> 
<#@ assembly name="C:\TEMP\ilrcwa2y.dll" #> 
<#@ assembly name="C:\TEMP\k0yeumhb.dll" #> 
<#@ assembly name="C:\TEMP\kirzdsqp.dll" #> 
<#@ assembly name="C:\TEMP\ksxl4f2z.dll" #> 
<#@ assembly name="C:\TEMP\l4kja4ts.dll" #> 
<#@ assembly name="C:\TEMP\ljgxkpo0.dll" #> 
<#@ assembly name="C:\TEMP\lkvkmlct.dll" #> 
<#@ assembly name="C:\TEMP\lnofhhlq.dll" #> 
<#@ assembly name="C:\TEMP\nbqhmjqd.dll" #> 
<#@ assembly name="C:\TEMP\oc3pxhmq.dll" #> 
<#@ assembly name="C:\TEMP\qb43ntcu.dll" #> 
<#@ assembly name="C:\TEMP\qlyoyhyr.dll" #> 
<#@ assembly name="C:\TEMP\snwvtb00.dll" #> 
<#@ assembly name="C:\TEMP\umhhb2wb.dll" #> 
<#@ assembly name="C:\TEMP\xsyfel0b.dll" #> 
<#@ assembly name="C:\TEMP\z1weyhko.dll" #> 

bạn có thể thoát khỏi < # nhân vật với \ < # thấy this.

+0

Tôi không nghĩ đây là câu trả lời đúng. Tìm đường dẫn tham chiếu dự án có thể được thực hiện như sau: https://gist.github.com/herskinduk/4528231150d13439e325 Nhưng <# @ assembly #> không thể xuất động theo cách bạn đề xuất. Đó là vấn đề lớn. – herskinduk

+0

Trên ba điểm của bạn: 1 + 2) Xem bình luận trước đó của tôi về một cách hiệu quả để xác định vị trí tài liệu tham khảo dự án. Việc tìm kiếm các hội đồng không phải là vấn đề. Có máy chủ T4 thêm chúng như là tài liệu tham khảo lắp ráp là kẻ giết người thực sự. 3) Thêm các hội đồng vào GAC có thể có một số milage nhưng tôi không nghĩ rằng nó tạo thành một giải pháp cho vấn đề ban đầu được mô tả. – herskinduk

+0

@herskinduk có cách GAC là xa để có vấn đề vì bạn cần phải nhớ để làm điều đó trên mỗi máy sẽ xây dựng. ive đi lên với một mô hình làm việc có thể có một cách để làm cho nó hoạt động trực tiếp, im vẫn cố gắng tìm ra cái này. – Rugdr

Các vấn đề liên quan