2011-10-25 18 views
17

Tôi đã gặp phải một vấn đề nhỏ với việc tạo mã T4 của mình.Cách tắt chỉ thị #line được ghi vào tệp đầu ra thế hệ T4

Tôi đã chia mẫu T4 thành các tệp riêng biệt và đặt chúng trong các thư mục khác nhau, tôi đã làm điều này để các phần của việc tạo mã của tôi có thể được sử dụng lại trong nhiều dự án, ví dụ: tạo mô hình, tạo kho lưu trữ và tạo dịch vụ tất cả bao gồm một tệp EntityGeneration.tt lõi. Thật không may, khi TextTemplating giải quyết lồng nhau của tôi bao gồm, nó xây dựng một chỉ thị tiền xử lý dài #line trong tệp .cs được tạo của nó, kết hợp tất cả các đường dẫn tương đối với tệp được bao gồm ở mức thấp nhất.

Thật không may, vì đường dẫn này được xây dựng với các đường dẫn tương đối, nó kết thúc không cần thiết lâu, do đó, dài trên thực tế là nó vượt quá chiều dài đường dẫn tối đa (Windows 7).

Đây là dòng có lỗi từ mã được tạo trong trường hợp bạn đang quan tâm:

#line 3 "C:\VS2010\AlbatrossTravelGroup\ASC\AlbatrossTravelGroup.ASC.BusinessRules\Services\Contracts\..\..\..\..\AlbatrossTravelGroup.BusinessRules\Services\Contracts\..\..\..\AlbatrossTravelGroup.Models\Repositories\Contracts\..\..\../AlbatrossTravelGroup.Common/CodeGeneration.tt" 

Câu hỏi của tôi là thế này, làm thế nào tôi có thể vô hiệu hóa các chỉ thị được ghi vào file mã được tạo? Nếu không, làm thế nào tôi có thể tránh được vấn đề này mà không thay đổi cấu trúc tập tin của tôi?

+2

Hiện tại, là giải pháp tạm thời, tôi đã tạo thư mục "CodeGeneration", tạo liên kết tượng trưng trong thư mục này cho từng tệp T4 của tôi để bao gồm.Sau đó, thay vì mỗi tệp T4 bao gồm các tệp T4 khác thông qua một đường dẫn tương đối, chúng chỉ sử dụng tên tệp. Sau đó, tại vị trí cuối cùng mà tôi muốn sử dụng các mẫu T4 này, tôi sử dụng một đường dẫn tương đối đến thư mục "CodeGeneration". Điều này dẫn đến độ dài đường dẫn ngắn hơn nhiều vì nó sử dụng nhiều đường dẫn tương đối ít hơn nhiều. Nếu bất cứ ai muốn giải thích đầy đủ, tôi sẽ đăng câu trả lời nếu được yêu cầu :) – Lukazoid

+1

Giải pháp tạm thời của tôi ở trên đã bị hỏng, không biết tại sao studio trực quan chỉ đơn giản là bắt đầu không giải quyết được tệp. Cuối cùng tôi phải sử dụng registry để chỉ định các thư mục bổ sung bao gồm tt, ít hơn lý tưởng, nhưng có vẻ như là thứ duy nhất hoạt động. – Lukazoid

+0

Bạn có thể thử một cái gì đó giống như giải pháp macro VS trình bày [ở đây] (http://stackoverflow.com/questions/3506525/t4-preprocessed-template-debugging-not-working-visual-studio-2010-rtm/7505247#7505247). – BitMask777

Trả lời

0

Tôi không chắc chắn điều này sẽ khắc phục được sự cố của bạn. Tôi không có nhiều kinh nghiệm với T4. Điều đó nói rằng, tôi đang sử dụng nó xây dựng một số tập tin trong dự án của tôi và tôi đã không chạy vào vấn đề bạn đang chạy vào.

Trong trường hợp của tôi, tôi có một loạt tệp .tt riêng lẻ hiển thị từng tệp riêng lẻ trong dự án của tôi.

Con đường tôi đang làm nó như sau: Tôi có một phương pháp SaveOutput (bị đánh cắp từ một nơi nào trên stackoverflow, tôi tin rằng):

void SaveOutput(string outputFileName) 
{ 
    if (!string.IsNullOrEmpty(outputFileName)) 
    { 
     string templateDirectory = Path.GetDirectoryName(Host.TemplateFile); 
     string outputFilePath = Path.Combine(templateDirectory, outputFileName); 
     string output = this.GenerationEnvironment.ToString(); 
     File.WriteAllText(outputFilePath, output); 
    } 

    this.GenerationEnvironment.Remove(0, this.GenerationEnvironment.Length); 
} 

Vì vậy, trong tập tin .tt chính tôi, tôi có < # @ bao gồm ... #> cho các tệp .tt khác nhau của tôi cho các tệp riêng lẻ. Ví dụ: < # @ include file = "DataObjectInterface.tt" #>

<#+ 
    public string GenerateInterfaceDataObject(sqlTable table) 
    { 
     string ifaceName = "I" + table.ObjectName; 
     if (table.GenerateInterfaceObjectAsBase) 
     { 
      ifaceName += "Base"; 
     } 
#> 
using System; 

namespace <#= InterfaceNamespace #> 
{ 
    public interface <#= ifaceName #> 
    { 
<#+ 
     foreach(sqlColumn col in table.Columns) 
     { 
#> 
     <#= GetColumnCSharpDataType(col) #> <#= col.FieldName #> { get; } 
<#+ 
     } 
#> 
    } 
} 
<#+ 
     return RootPath + @"\AutoGenerated\" + ifaceName + ".cs"; 
    } 
#> 

Sau đó, trong lớp .tt chính của tôi, tôi chỉ đơn giản là thực hiện cuộc gọi như thế này:

string filePath = GenerateInterfaceDataObject(table); 
SaveOutput(filePath); 

Không chắc chắn nếu phương pháp này phá vỡ các mẫu của bạn sẽ làm việc cho nhu cầu của bạn, nhưng nó đã làm việc cho tôi và tôi chưa gặp phải bất kỳ vấn đề nào với nó.

Tôi nên làm rõ rằng tệp .tt chính của tôi không thực sự tạo bất kỳ thứ gì từ chính nó. Nó không phải là bản thân nó. Nó đơn giản tải từng mẫu và tạo ra các tệp từ các mẫu khác.

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