2012-07-31 14 views
5

Có cách nào để tải tệp .txt làm lớp, chương trình chính của tôi có thể gọi hàm từ đó không? Về cơ bản, tôi đang cố gắng thêm hỗ trợ mod vào ứng dụng đơn giản của mình, nơi người dùng có thể chọn các tùy chọn từ mỗi tệp. Tệp này tuân theo định dạng tương tự (nhưng không giống nhau), với một loạt các khoảng trống (hàm) được gọi trong chương trình chính.C# - Tải tệp văn bản dưới dạng lớp

Tôi làm cách nào để thực hiện việc này? Điều đó thậm chí có thể làm được (có lẽ không, trả lời câu hỏi của riêng tôi?), Xem xét nó sẽ không được biên dịch cùng với phần còn lại của chương trình?

Cảm ơn!

+0

Có thể, nhưng bạn phải gọi trình biên dịch C# .. không tầm thường. Dễ dàng hơn để yêu cầu các mod của bạn được biên dịch thành các dll, mà sau đó bạn có thể tải và gọi vào với sự phản chiếu. – Blorgbeard

+0

Có lẽ phải xem xét sử dụng Roslyn – Prescott

Trả lời

6

Xem tôi trả lời cho câu hỏi này: Compile a C# Array at runtime and use it in code?

Về cơ bản, bạn sẽ muốn kéo tập tin văn bản của bạn vào CodeDOM và biên dịch nó. Sau đó, có thể sẽ hữu ích khi tạo một vài phương thức động như những người trợ giúp thực thi.

  • Nhận được tải lên tập tin
  • Thực hiện bất kỳ xác nhận cần thiết vào file
  • đọc các tập tin như là một chuỗi vào CodeDOM
  • Deal với bất kỳ lỗi biên dịch/cấu trúc
  • Tạo phương pháp helper sử dụng biểu LINQ cây hoặc phương pháp động để liên kết giữa lớp mới và mã hiện có được bắc cầu với đối tượng được biên dịch (nếu không, tất cả các phương thức mới sẽ cần được gọi bằng cách sử dụng phản chiếu)

var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v4.0" } }); 
var cp = new CompilerParameters() { 
    GenerateExecutable = false, 
    OutputAssembly = outputAssemblyName, 
    GenerateInMemory = true 
}; 

cp.ReferencedAssemblies.Add("mscorlib.dll"); 
cp.ReferencedAssemblies.Add("System.dll"); 

StringBuilder sb = new StringBuilder(); 

// The string can contain any valid c# code 

sb.Append("namespace Foo{"); 
sb.Append("using System;"); 
sb.Append("public static class MyClass{"); 
sb.Append("}}"); 

// "results" will usually contain very detailed error messages 
var results = csc.CompileAssemblyFromSource(cp, sb.ToString()); 

Ngoài ra, xem chủ đề này: Implementing a scripting language in C#. IronPython với DLR có thể phù hợp với nhu cầu của bạn.

+0

Đó là điều - tôi không nhất thiết muốn biên dịch nó, tôi chỉ cần nó để chạy như một kịch bản. – Scott

+1

Tôi hiểu. FYI, kịch bản được biên soạn quá, chỉ trên bay. Tùy thuộc vào nhu cầu hiệu suất của bạn, biên dịch động có thể phù hợp, mặc dù biên dịch C# có thể ít được tối ưu hóa cho các hoạt động bay. –

+0

Điều này thực sự tuyệt vời, tôi sẽ thêm nó! Cảm ơn bạn! – Scott

1

Sử dụng một khung mà Xử lý Plugins

Managed Khả năng mở rộng khung được chỉ là những gì bạn đang tìm kiếm

http://mef.codeplex.com/

Managed Khả năng mở rộng khung (MEF) là một lớp thành phần cho .NET giúp cải thiện tính linh hoạt, khả năng bảo trì và khả năng thử nghiệm của các ứng dụng lớn. MEF có thể được sử dụng cho khả năng mở rộng plugin của bên thứ ba, hoặc nó có thể mang lại những lợi ích của kiến ​​trúc giống như một plugin lỏng lẻo cho các ứng dụng thông thường.

MEF cung cấp kiến ​​trúc được xác định rõ ràng để hỗ trợ các plugin trong ứng dụng của bạn.

chữ DLL vs (Source Code)

Các nhà phát triển plugin được dự kiến ​​sẽ cung cấp một DLL chứa mã plugin. Tuy nhiên, nếu cần, bạn có thể biên dịch mã nguồn thành một DLL cho chúng bằng cách sử dụng Roslyn. Hãy nhớ rằng nếu bạn muốn hỗ trợ nhận mã nguồn của plugin, bạn cũng sẽ phải cung cấp hỗ trợ để giúp người dùng xử lý các lỗi trình biên dịch và gỡ lỗi các plugin trong khung công tác của bạn. Nó có thể khôn ngoan hơn để yêu cầu họ cung cấp một DLL.

+1

Điều này có hoạt động với tệp .txt dưới dạng lớp không? Tôi nghĩ anh ấy cần phải biên dịch về cơ bản nó – Prescott

+0

@Prescott: Cập nhật câu trả lời của tôi để giải quyết vấn đề đó. –

+0

Mọi cập nhật liên quan đến điều này? –

3

Bạn có thể tải tệp văn bản và sau đó sử dụng một số Trình biên dịch dưới dạng dịch vụ (hoặc Microsoft's pre-release Roslyn project hoặc Mono.CSharp). Sau đó, bạn có thể lấy các kết quả đầu ra đã biên dịch và chạy chúng trong chương trình của bạn.

Nếu có thể để người dùng giao cho bạn một hội đồng được biên dịch thay vì tệp nguồn chưa được biên soạn, bạn nên xem xét Managed Extensibility Framework hoặc Mono.Addins.

Cách tiếp cận thứ hai (cụm mở rộng) có vẻ tốt hơn với ít nhất hai lý do: 1) người dùng của bạn có thể sử dụng bất kỳ môi trường phát triển nào họ muốn đảm bảo mã của họ biên dịch chính xác trước khi giao cho bạn và 2) bạn có ít việc phải làm để xác thực đầu vào và xử lý lỗi.

+0

Cảm ơn bạn! Tôi sẽ kiểm tra Roslyn, có một vài ý kiến ​​nói về điều đó. – Scott

+2

Đừng đánh giá thấp Mono.CSharp - đó là "sản phẩm hoàn chỉnh" có giao diện mà bạn có thể mong đợi không thay đổi. Giao diện của Roslyn hoàn toàn có thể thay đổi giữa trạng thái CTP hiện tại và RTM cuối cùng của nó. Khi nó gần gũi hơn với vận chuyển, Roslyn có thể là một sự lựa chọn thích hợp hơn cho một dự án .NET điển hình, nhưng hãy nhớ rằng các hội đồng Mono chạy trên CLR của Microsoft cũng như bất kỳ hội đồng nào khác làm. – sblom