2010-02-21 58 views
20

Chúng tôi đang xây dựng một ứng dụng trong nhà cần tạo các tệp HTML để tải lên danh sách eBay. Chúng tôi đang tìm cách sử dụng một công cụ mẫu để tạo các tệp HTML dựa trên cơ sở dữ liệu và các trường tĩnh mà chúng tôi đã xác định trước. Mẫu cũng cần phải có khả năng logic (nếu-sau đó, foreach, vv).Tạo mẫu T4 khi chạy (thời gian xây dựng)?

Chúng tôi đã xem xét T4 và nó trông hoàn hảo, nhưng chúng tôi không thấy bất cứ điều gì về việc nó có khả năng được sử dụng khi chạy, để người dùng có thể tạo mẫu T4, và sau đó ứng dụng có thể "biên dịch "nó và tạo tệp HTML cuối cùng. Đây có phải là có thể, và như thế nào?

Nếu không, có các khung công tác khác mà chúng ta nên xem xét có tất cả các khả năng này không?

Trả lời

16

Tôi có một nhóm lớp tương tự mà tôi sử dụng cho việc này, nhúng văn bản tạo mẫu vào phần mềm.

Về cơ bản, nó hoạt động như ASP kiểu cũ, bạn bao quanh mã C# trong khối <%...%> và bạn có thể phát ra kết quả bằng cách sử dụng <%= expression %>.

Bạn có thể chuyển một đối tượng vào mã mẫu, tất nhiên có thể là bất kỳ loại đối tượng nào bạn thích hoặc đơn giản là một mảng tham số. Bạn cũng có thể tham khảo các hội đồng của riêng bạn nếu bạn muốn thực thi mã tùy chỉnh.

Sau đây là cách phát ra một lớp sẽ nhìn:

<% 
var parameters = (string[])data; 
var namespaceName = parameters[0]; 
var className = parameters[1]; 
%> 
namespace <%= namespaceName %> 
{ 
    public class <%= className %> 
    { 
    } 
} 

Bạn có thể của vòng lặp nhiên qua điều:

<% foreach (var parameter in parameters) { %> 
<%= parameter %> 
<% } %> 

và đặt mã trong if-khối, vv

Thư viện lớp được phát hành trên CodePlex tại đây:

cũng như trên NuGet.

Dự án đi kèm với các ví dụ, tải xuống nguồn hoặc browse it online.

Để trả lời câu hỏi qua email cũng ở đây, đối với những người khác để xem:

  1. Tất cả các loại mã C# đó phù hợp với một phương pháp gọi thể được biên dịch trong mẫu. Nó chạy mã C# 3.5 bình thường, với mọi thứ có nghĩa là, không có giới hạn nhân tạo. Chỉ có những điều cần biết là bất kỳ nếu, trong khi, cho, foreach, vv mã có chứa mã mẫu để phát ra phải sử dụng niềng răng, bạn không thể làm một dòng nếu-sau đó loại khối. Xem bên dưới để biết giới hạn cuộc gọi phương thức.
  2. Thông số data tương ứng với bất kỳ thông tin nào được chuyển vào làm tham số cho phương thức .Generate(x) từ ứng dụng của bạn và có cùng loại. Nếu bạn chuyển vào một đối tượng mà bạn đã định nghĩa trong các thư viện lớp của riêng mình, bạn cần phải thêm một tham chiếu tới mã mẫu để truy cập đúng nó.(<%@ reference your.class.library.dll %>)
  3. Nếu bạn sử dụng lại mẫu đã biên dịch, bản chất sẽ chỉ là một cuộc gọi phương thức cho một lớp, không thực hiện thêm phí trên thực tế cuộc gọi đến .Generate(). Nếu bạn không tự gọi số .Compile(), cuộc gọi đầu tiên đến .Generate() sẽ tự xử lý. Cũng lưu ý rằng mã chạy trong một appdomain riêng biệt, do đó, có một chút marshalling overhead liên quan đến việc sao chép các tham số và kết quả qua lại. Mã, tuy nhiên, chạy ở tốc độ mã JITted .NET bình thường.

Ví dụ về if-block:

<% if (a == b) { %> 
This will only be output if a==b. 
<% } %> 

Không có giới hạn nhân tạo về định dạng mã hoặc, chọn phong cách phù hợp với bạn nhất:

<% 
    if (a == b) 
    { 
%> 
This will only be output if a==b. 
<% 
    } 
%> 

Chỉ lưu ý rằng tất cả các phi các phần mã của mẫu sẽ xuất hiện khá nhiều, tức là các tab và các khối %> sau cũng sẽ được xuất ra.

Có một giới hạn, tất cả mã bạn viết phải vừa với một cuộc gọi phương thức duy nhất.

Hãy để tôi giải thích.

Cách template engine hoạt động là nó tạo ra một file .cs và thức ăn nó vào biên dịch C#, nộp cs này roughyly trông như thế này:

using directives 

namespace SomeNamespace 
{ 
    public class SomeClass 
    { 
     public string Render(object data) 
     { 
      ... all your code goes here 
     } 
    } 
} 

Điều này có nghĩa rằng bạn không thể xác định các lớp học mới , các phương thức mới, trường cấp lớp, v.v.

Tuy nhiên, bạn có thể sử dụng các đại biểu ẩn danh để tạo các hàm nội bộ. Ví dụ, nếu bạn muốn có một cách thống nhất của ngày định dạng:

Func<DateTime, string> date2str = delegate(DateTime dt) 
{ 
    return dt.ToString("G"); 
}; 

sau đó bạn chỉ có thể sử dụng trong phần còn lại của mẫu mã:

<%= date2str(DateTime.Now) %> 

Chỉ yêu cầu tôi phải là bạn don' t tải các tệp lên web và yêu cầu bạn đã viết mã, ngoài việc bạn tự do làm những gì bạn muốn với nó.

Chỉnh sửa 23.04.2011: Cố định liên kết đến dự án CodePlex.

+0

Wooow O.o Tôi đang tải xuống ngay bây giờ và tôi sẽ cho bạn biết cách thức hoạt động. Nếu nó làm mọi thứ bạn nói, bạn sẽ là một người bảo vệ cuộc sống tuyệt đối! – Amberite

+0

Đã chỉnh sửa câu trả lời ngay bây giờ, như bạn đã nói trong email, biến "Dữ liệu" không tồn tại, vì nó được đặt tên là "dữ liệu". Đó là một tham số phương thức, do đó chữ thường "d". –

+0

"Cách mà công cụ tạo mẫu hoạt động là nó tạo ra tệp .cs và nạp nó vào trình biên dịch C#": Điều đó có nghĩa là máy chạy VisStudio này hay ít nhất một cái gì đó khác được cài đặt? Hoặc là có một cách mà chương trình của bạn gọi trình biên dịch C#? Tôi không nghĩ rằng trình biên dịch đã được vận chuyển với thời gian chạy .net ... Mặc dù kể từ khi IIS có thể biên dịch ASP.NET trên bay, tôi đoán nó phải được ra khỏi một nơi nào đó ... – CodingWithSpike

3

Mẫu T4 có thể được biên dịch bằng công cụ dòng lệnh TextTransform.exe. Bạn có thể ứng dụng của bạn tạo tệp .tt, sau đó gọi TextTransform.exe để tạo đầu ra.

+0

Không phải Visual Studio cần được cài đặt trên máy của người dùng bằng giải pháp này? Đây là một hạn chế đối với chúng tôi. – Amberite

+0

Mono có khả năng thực thi chuyển đổi văn bản khá có khả năng. Tôi sẽ xem xét rằng nếu phụ thuộc là một vấn đề. –

+2

Có, cho đến bây giờ, đó là một depedency trên Visual Studio. Điều này sẽ thay đổi với VS2010/.NET 4 và cái gọi là mẫu T4 được biên dịch trước. Xem ở đây để biết thông tin: http://www.olegsych.com/2009/09/t4-preprocessed-text-templates/ –

6

Lắp ráp thực hiện chuyển đổi văn bản T4 là Microsoft.VisualStudio.TextTemplating.dll, được giao với Visual Studio.

Nếu bạn muốn bắt đầu từ nguyên tắc đầu tiên, bạn cần triển khai Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost và chuyển việc triển khai của bạn làm đối số cho Microsoft.VisualStudio.TextTemplating.Engine.ProcessTemplate(), sẽ thực hiện chuyển đổi.

Điều này mang lại cho bạn sự linh hoạt hơn khi gọi ra TextTransform.exe.

Tuy nhiên, nếu mã của bạn là sản phẩm giao hàng thì không rõ giấy phép của hội đồng này là gì và liệu bạn có quyền phân phối lại nó với đơn đăng ký của bạn không.

Phân phối lại phiên bản này sẽ tránh sự cần thiết phải cài đặt Visual Studio.

+0

Thật không may điều này không đáp ứng nhu cầu của chúng tôi vì vấn đề cấp phép, vì sản phẩm này S be được chuyển đến người dùng cuối. Thanks anyways :) – Amberite

+1

Ngoài ra còn có một triển khai mã nguồn mở bởi dự án Mono. http://anonsvn.mono-project.com/viewvc/trunk/monodevelop/main/src/addins/TextTemplating/ –

3

Hoàn toàn có thể sử dụng T4 khi chạy.

Microsoft không thực sự hỗ trợ kịch bản này theo bất kỳ cách nào hợp lý trong .NET 3.5. Có vẻ như .NET 4.0 sẽ có sự hỗ trợ tốt hơn từ Microsoft.

Mono cung cấp một số hỗ trợ cho trường hợp này trong .NET 3.5. Tôi đã chứng minh khái niệm này thành công với .NET 3.5 với sự trợ giúp từ việc thực hiện Mono T4, nhưng một giải pháp ngoài kệ cho vấn đề này cho .NET 3.5 sẽ đòi hỏi nhiều nỗ lực hơn tôi đã đầu tư từ trước đến nay.

Bạn có thể tìm thấy việc thực hiện Mono T4 ở đây:

https://github.com/mono/monodevelop/tree/master/main/src/addins/TextTemplating

tôi đã ghi nhận một số vấn đề tôi gặp phải cố gắng chạy T4 mẫu từ NET mã ở đây:

Options for running T4 templates from .NET code

14

Nếu bạn có thể sử dụng Visual Studio 2010 để tạo và chỉnh sửa mẫu, thì bạn có thể sử dụng các mẫu biên dịch sẵn, được thiết kế cho chính xác trường hợp này và là tùy chọn được hỗ trợ từ Microsoft.

Bạn thiết kế mẫu trong Visual Studio, biên dịch trước nó và triển khai một assembly không phụ thuộc vào Visual Studio cùng với ứng dụng của bạn.

http://www.olegsych.com/2009/09/t4-preprocessed-text-templates/

0

Một lỗi mà tôi tạo là tôi đã thêm tệp "Mẫu văn bản". Để tạo văn bản tại số thời gian chạy, hãy chọn "Mẫu văn bản được xử lý trước" thay thế. Nếu ban đầu bạn chọn "Mẫu văn bản", đó là một thay đổi dễ dàng để đặt Công cụ tùy chỉnh thành "TextTemplatingFilePreprocessor" trong thuộc tính tệp trong VS.

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