2010-08-23 30 views
13

Tôi có một giải pháp có một vài dự án trong đó. Tôi muốn tạo một số mẫu T4 trong một trong các dự án thử nghiệm của tôi để tạo các thử nghiệm dựa trên mã trong một dự án khác. Dự án thử nghiệm có một tham chiếu dự án cho dự án khác. Vấn đề tôi có là tôi không biết làm thế nào để có được một đường dẫn tập tin vào tập tin edmx tôi cần phải tạo mã từ.Nhận đường dẫn của dự án được tham chiếu trong mẫu T4?

Ví dụ (giả vờ đây là một ASCII dựa trên Solution Explorer):

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) 

Làm thế nào sẽ GeneratedTests.tt tôi có thể nhận được một đường dẫn tập tin cho MyModel.edmx sử dụng tài liệu tham khảo dự án của mình với nó?

Trả lời

4

Điều này không hoạt động theo cách đó. Bạn sẽ phải tham khảo dll bằng đường dẫn (bạn có thể thấy rằng với Host.ResolvePath và sử dụng thẻ VolatileAssembly từ hộp công cụ để có thể biên dịch lại nó mà không cần khởi động lại VS) và sử dụng sự phản chiếu để làm việc trên Mô hình.

+0

Tham chiếu DLL theo đường dẫn gây ra sự cố tôi đang cố tránh. Một hộp dev có thể có dự án ở một nơi trong khi một hộp khác có nó ở một nơi khác. Nếu tôi có thể giả định vị trí, thì tôi sẽ không phải có mẫu xác định nó - tôi chỉ có thể mã hóa nó hoặc tiêm nó với các kịch bản xây dựng. Làm việc trên mô hình là không có vấn đề - kịch bản của tôi chạy hoàn hảo nếu tôi hardcode đường dẫn. Tôi chỉ cần một cách để tự động xác định con đường đó. Sử dụng Host.Resolve là tốt nếu tôi cần đường dẫn của mẫu - tôi chỉ cần tìm ra đường dẫn cho nguồn của assembly MyDAL. – Jaxidian

+2

Host.ResolvePath (".") Hoạt động. :) – Jaxidian

1

Bạn có thể sử dụng macro cho các thư mục đặc biệt như $(ProjectDir), $(SolutionDir) từ mẫu và có thể đọc tệp .sln hoặc .csproj để trích xuất thư mục cho dự án khác.

+0

Tôi đã hy vọng tránh đọc tập tin .sln - tôi đoán chủ yếu là bởi vì tôi không hiểu tất cả những gì tốt và tôi không chắc chắn những giả định mà tôi có thể thực hiện về độ tin cậy của con đường trong đó. Bạn có thể cho tôi bất kỳ liên kết nào để hiểu điều này tốt hơn không? – Jaxidian

+0

Thực ra, tôi không nghĩ nó phù hợp. Các macro này chỉ hoạt động trong các chỉ thị T4 như '<# @ assembly #>' và '<#@include #>' –

+6

Nếu bạn cần giải quyết đường dẫn macro bên ngoài chỉ thị T4, bạn có thể thực hiện bằng cách sử dụng: 'strPath = Host.ResolveAssemblyReference ("$ (ProjectDir)") ', ResolvePath không hoạt động với các macro - một sự nâng cao trong tương lai có lẽ? –

15

Câu trả lời này chỉ hoạt động từ bên trong Visual Studio.

Đặt thuộc tính "máy chủ lưu trữ" của mẫu T4. Điều này cho phép bạn truy cập vào thuộc tính Host. Gõ cast Host vào IServiceProvider để gọi GetService (typeof (DTE)). Điều này cho phép bạn duyệt qua nội dung của giải pháp.

<#@ 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#> 
<# 
} 
#> 

Xem thêm ví dụ về ITextTemplatingEngineHost interface on MSDNT4 Architecture by Oleg Synch.

+0

Tôi nghĩ rằng điều này sẽ làm việc độc đáo cho tôi nếu nó hoạt động như nó âm thanh như nó sẽ. Bạn có thể, tuy nhiên, xây dựng trên bình luận của bạn rằng điều này chỉ hoạt động trong Visual Studio? Chúng tôi có kế hoạch để tự động hóa các thế hệ mẫu của chúng tôi kể từ khi chúng tôi bắt đầu đặt chúng trên tất cả các giải pháp của chúng tôi bởi vì nó bắt đầu trở nên đau đớn để tự đi qua và tạo ra tất cả mọi thứ. Chúng tôi không biết chính xác cách chúng tôi sẽ tự động hóa nó, vì vậy câu trả lời của bạn có thể giúp chúng tôi lên kế hoạch. Nant, PS/MSBuild, bất cứ điều gì - chúng tôi đang làm tốt tuy nhiên nó là cần thiết để làm điều đó. – Jaxidian

+0

Khi bạn đặt hostspecific = "true", mẫu sẽ truy cập vào thông số Host. Nhưng mặt trái là máy chủ T4 phải cung cấp nó. Trong trường hợp này, máy chủ T4 được giả định là Visual Studio, thực hiện giao diện DTE. Việc xây dựng dòng lệnh sẽ trả về null. Nếu bạn muốn sử dụng phương pháp này, tôi đề nghị bạn chuyển đổi mẫu của bạn trong Visual Studio, không phải trong bản dựng. Bản dựng tự động có thể sử dụng mã được tạo. –

4

sử dụng những dòng

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

sau đó sử dụng đường dẫn tương đối để có được file edmx bạn ví dụ, chuỗi Inputfile = @ ".. \ Modal.edmx";

10

Dựa tắt của comment James Đóng, tôi đã có thể viết vào bảng dưới đây để gỡ lỗi đường dẫn tập tin của tôi:

<#@ 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 
    <# 
} 
#> 

Điều này sẽ tạo ra một file .txt và sẽ rất nhanh chóng giúp bạn gỡ rối cho dù con đường của bạn có thể được đặt hay không. Là một lưu ý phụ, trong trường hợp có đường dẫn tương đối (ví dụ: ../App.config) không thể định vị được, tôi thấy rằng nó giúp đặt một tệp (ví dụ: test1.txt) ở mỗi cấp thư mục, như tôi đã tìm ra rằng Host.ResolvePath không thể nhìn thấy bên ngoài hội đồng hiện tại với thiết lập của tôi. Thông báo trước này có thể gây nhầm lẫn rất nhanh vì ../../App.config có thể giải quyết thành MySolution\App.config, nhưng ../../MyDal/README.txt sẽ không giải quyết (do đó không tìm thấy tệp), ngay cả khi đó là đường dẫn chính xác. Đoạn mã trên dường như phủ nhận vấn đề này theo như tôi thấy.

Các giải pháp trên cũng có thể là một giải pháp cho vấn đề này - How to use the poco entity generator

0

Dựa trên câu trả lời của Mina và những người khác tôi đã đưa ra giải pháp này. Nó liệt kê thư mục làm việc hiện tại, đường dẫn giải pháp và sử dụng mẹo của Mina để thay đổi thư mục hoạt động đang hoạt động.

<#@ 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 #> 
Các vấn đề liên quan