2008-09-15 34 views
11

Tôi đang lập trình WCF bằng cách sử dụng ChannelFactory, dự kiến ​​một loại để gọi phương thức CreateChannel. Ví dụ:Tự động Tạo một kiểu chung cho mẫu

IProxy proxy = ChannelFactory<IProxy>.CreateChannel(...); 

Trong trường hợp của tôi Tôi định tuyến nên tôi không biết loại nhà máy kênh của tôi sẽ sử dụng. Tôi có thể phân tích cú pháp tiêu đề thư để xác định loại nhưng tôi nhấn vào một bức tường gạch ở đó bởi vì ngay cả khi tôi có một thể hiện của Loại tôi không thể vượt qua điều đó mà ChannelFactory mong đợi một loại chung chung.

Một cách khác để tái khẳng định vấn đề này trong điều kiện rất đơn giản sẽ là tôi đang cố gắng làm một cái gì đó như thế này:

string listtype = Console.ReadLine(); // say "System.Int32" 
Type t = Type.GetType(listtype); 
List<t> myIntegers = new List<>(); // does not compile, expects a "type" 
List<typeof(t)> myIntegers = new List<typeof(t)>(); // interesting - type must resolve at compile time? 

Có một cách tiếp cận này tôi có thể tận dụng trong C#?

+0

có thể trùng lặp của [Truyền An instantiated System.Type như một tham số kiểu cho lớp chung] (http://stackoverflow.com/questions/266115/pass-an-instantiated-system -type-as-a-type-tham số-cho-một-chung-class) – nawfal

Trả lời

22

gì bạn đang tìm kiếm là MakeGenericType

string elementTypeName = Console.ReadLine(); 
Type elementType = Type.GetType(elementTypeName); 
Type[] types = new Type[] { elementType }; 

Type listType = typeof(List<>); 
Type genericType = listType.MakeGenericType(types); 
IProxy proxy = (IProxy)Activator.CreateInstance(genericType); 

Vì vậy, những gì bạn đang làm là nhận được các loại nét của lớp "mẫu" chung chung, sau đó xây dựng một chuyên môn hóa của các loại sử dụng các loại runtime-lái xe của bạn .

4

Đây là câu hỏi: Bạn có thực sự cần tạo kênh có loại hợp đồng chính xác trong trường hợp cụ thể của bạn không?

Vì bạn đang định tuyến, có một cơ hội rất tốt bạn có thể chỉ cần xử lý các hình dạng kênh chung. Ví dụ: nếu bạn đang định tuyến thư chỉ một chiều thì bạn có thể tạo kênh để gửi thư như sau:

ChannelFactory<IOutputChannel> factory = new ChannelFactory<IOutputChannel>(binding, endpoint); 
IOutputChannel channel = factory.CreateChannel(); 
... 
channel.SendMessage(myRawMessage); 

Nếu bạn cần gửi dịch vụ hai chiều, chỉ cần sử dụng IRequestChannel thay thế.

Nếu bạn đang định tuyến, nói chung, dễ dàng hơn nhiều để xử lý các hình dạng kênh chung (với một hợp đồng dịch vụ toàn phần bắt buộc ở bên ngoài) và chỉ đảm bảo thư bạn đang gửi có tất cả các tiêu đề và thuộc tính phù hợp.

+1

Tôi đã có một tiến thoái lưỡng nan đánh dấu "câu trả lời" cho câu hỏi của tôi. Về việc sử dụng WCF, tôi đã có thể sử dụng kỹ thuật này bạn đề cập đến và nó hoạt động như một sự quyến rũ (cảm ơn bạn!). Tôi đã chọn ở trên vì nó về mặt kỹ thuật trả lời câu hỏi tôi đã hỏi (ngay cả khi đây là một cách tốt hơn). – t3rse

8

Bạn nên xem bài đăng này từ Ayende: WCF, Mocking and IoC: Oh MY!. Một nơi nào đó gần phía dưới là một phương pháp gọi là GetCreationDelegate sẽ giúp bạn. Về cơ bản, điều này thực hiện:

string typeName = ...; 
Type proxyType = Type.GetType(typeName); 

Type type = typeof (ChannelFactory<>).MakeGenericType(proxyType); 

object target = Activator.CreateInstance(type); 

MethodInfo methodInfo = type.GetMethod("CreateChannel", new Type[] {}); 

return methodInfo.Invoke(target, new object[0]); 
Các vấn đề liên quan