WCF ChannelFactory so với tạo proxy


82

Chỉ cần tự hỏi trong trường hợp nào bạn muốn tạo proxy từ dịch vụ WCF khi bạn chỉ có thể gọi các cuộc gọi bằng ChannelFactory?

Bằng cách này, bạn sẽ không phải tạo proxy và lo lắng về việc tạo lại proxy khi máy chủ được cập nhật?

Cảm ơn


Luôn sử dụng ChannelFactory. Tôi không thể nói điều này đủ mạnh.
tom redfern,

Câu trả lời:


88

Có 3 cách cơ bản để tạo ứng dụng WCF:

  1. Hãy để Visual Studio tạo proxy của bạn. Tự động này tạo mã kết nối với dịch vụ bằng cách đọc WSDL. Nếu dịch vụ thay đổi vì bất kỳ lý do gì, bạn phải tạo lại nó. Ưu điểm lớn của điều này là dễ thiết lập - VS có một trình hướng dẫn và tất cả đều tự động. Điểm bất lợi là bạn đang dựa vào VS để làm mọi công việc khó khăn cho bạn, và vì vậy bạn mất kiểm soát.

  2. Sử dụng ChannelFactoryvới một giao diện đã biết. Điều này phụ thuộc vào việc bạn có các giao diện cục bộ mô tả dịch vụ (hợp đồng dịch vụ). Ưu điểm lớn là có thể quản lý thay đổi dễ dàng hơn nhiều - bạn vẫn phải biên dịch lại và sửa các thay đổi, nhưng bây giờ bạn không tạo lại mã, bạn đang tham khảo các giao diện mới. Thông thường, điều này được sử dụng khi bạn kiểm soát cả máy chủ và máy khách vì cả hai đều có thể dễ bị chế nhạo hơn nhiều để kiểm tra đơn vị. Tuy nhiên, các giao diện có thể được viết cho bất kỳ dịch vụ nào, ngay cả những dịch vụ REST - hãy xem API Twitter này .

  3. Viết proxy của riêng bạn - điều này khá dễ thực hiện, đặc biệt là đối với các dịch vụ REST, sử dụng dấu HttpClienthoặc WebClient. Điều này cung cấp cho bạn khả năng kiểm soát hạt tốt nhất, nhưng với chi phí là rất nhiều API dịch vụ nằm trong chuỗi. Ví dụ: var content = new HttpClient().Get("http://yoursite.com/resource/id").Content;- nếu các chi tiết của API thay đổi, bạn sẽ không gặp lỗi cho đến thời gian chạy.

Cá nhân tôi chưa bao giờ thích tùy chọn 1 - dựa vào mã được tạo tự động là lộn xộn và mất kiểm soát quá nhiều. Thêm vào đó, nó thường tạo ra các vấn đề về tuần tự hóa - tôi kết thúc với hai lớp giống hệt nhau (một trong mã máy chủ, một được tạo tự động) có thể được đánh dấu nhưng rất khó.

Tùy chọn 2 nên hoàn hảo, nhưng các Kênh hơi quá hạn chế - ví dụ: chúng hoàn toàn mất nội dung do lỗi HTTP . Điều đó nói rằng việc có các giao diện mô tả dịch vụ sẽ dễ dàng hơn nhiều để viết mã và bảo trì.


4
@MurHaf Không - câu trả lời này hoàn toàn là công việc của riêng tôi. TÔI LUÔN quy kết những đóng góp của người khác. Tôi đã viết câu trả lời này dựa trên nhiều năm làm việc với các dịch vụ SOAP trong .Net ở nhiều công việc khác nhau. Bài báo mà bạn liên kết đến là từ tháng 3 năm 2013, trong khi câu trả lời của tôi được viết vào tháng 4 năm 2010 - 3 năm trước đó! Nếu đạo văn đã xảy ra, anh ấy đã sao chép tôi. Bạn nên kiểm tra ngày tháng trước khi buộc tội vì điều này rất dễ thực hiện.
Keith

@MurHaf, chúng tôi thậm chí không đi đến cùng kết luận - bài báo đó khuyến nghị tự động tạo proxy (tùy chọn 1) là 'đơn giản'. Tôi mô tả nó là dễ dàng để thiết lập, nhưng lộn xộn và khó duy trì. Anh ấy thậm chí không thảo luận về việc viết proxy của riêng bạn (tùy chọn 3).
Keith

1
Tôi nghĩ SvcUtil cũng nên được đề cập, vì đây là một trong những cách phổ biến nhất để "viết" một ứng dụng khách.
Mare Infinitus

21

Tôi sử dụng ChannelFactory cùng với phương thức MetadataResolver.Resolve. Cấu hình máy khách là một vấn đề phiền toái, vì vậy tôi lấy ServiceEndpoint của mình từ máy chủ.

Khi bạn sử dụng ChannelFactory (Của T), T là hợp đồng gốc mà bạn có thể nhận được từ một tham chiếu trong dự án của bạn hoặc một phiên bản hợp đồng được tạo. Trong một số dự án, tôi đã tạo mã từ Tham chiếu dịch vụ vì tôi không thể thêm tham chiếu vào dll hợp đồng. Bạn thậm chí có thể tạo một hợp đồng không đồng bộ với tham chiếu dịch vụ và sử dụng giao diện hợp đồng đó với ChannelFactory.

Điểm chính của việc sử dụng ChannelFactory đối với tôi là loại bỏ thông tin cấu hình máy khách WCF. Trong đoạn mã mẫu bên dưới, bạn có thể thấy cách đạt được một máy khách WCF mà không cần cấu hình.

Dim fixedAddress = "net.tcp://server/service.svc/mex"
Dim availableBindings = MetadataResolver.Resolve(GetType(ContractAssembly.IContractName), New EndpointAddress(fixedAddress))
factoryService = New ChannelFactory(Of ContractAssembly.IContractName)(availableBindings(0))
accesService = factoryService.CreateChannel()

Trong dự án cuối cùng của tôi, các Liên kết sẵn có được chọn để sử dụng net.tcp hoặc net.pipe nếu có. Bằng cách đó, tôi có thể sử dụng ràng buộc tốt nhất có sẵn cho nhu cầu của mình. Tôi chỉ dựa vào thực tế là một điểm cuối siêu dữ liệu tồn tại trên máy chủ.

Tôi hi vọng cái này giúp được

BTW, điều này được thực hiện bằng cách sử dụng .NET 3.5. Tuy nhiên, nó cũng hoạt động với 4.0.


Những thứ tuyệt vời. Tôi cũng sử dụng MetadataResolver.Resolve cho cấu hình nhưng tôi không nghĩ đến việc giải quyết ràng buộc từ máy chủ. Điểm rất tốt!
Sleeper Smith,

upvote đề cập đếnThe main point of using ChannelFactory to get rid of the WCF client config
Kurubaran

11

Để sử dụng, ChannelFactory<T>bạn phải sẵn sàng chia sẻ các hợp đồng hợp đồng giữa dịch vụ và khách hàng. Nếu điều này là ổn với bạn thì ChannelFactory<T>có thể giúp bạn tiết kiệm thời gian.


@Charles - bạn có thể giải thích tại sao điều này không đúng không?
Aran Mulholland

6
@Aran: Tôi nghĩ điều Andrew muốn nói là đúng - rằng nếu bạn không muốn tạo bản fax của các lớp hợp đồng, thì bạn sẽ cần phải có quyền truy cập vào bản gốc. Đúng là bằng cách này hay cách khác, bạn cần phải có những lớp hợp đồng đó. Bạn có thể tạo chúng, viết chúng bằng tay hoặc lấy mã nguồn của dịch vụ (nếu nó cùng ngôn ngữ). Chia sẻ các tập hợp là cách dễ nhất, nhưng điều đó không phải lúc nào cũng khả thi. (Có thể tôi chỉ coi Andrew quá theo nghĩa đen, nhưng sự rõ ràng là quan trọng ở đây.)
Igby Largeman

2
@Charles ok, vì vậy bạn đang nói rằng bạn có thể sử dụng ChannelFactory <T> ngay cả khi bạn không có quyền truy cập vào các tập hợp bằng cách mã hóa thủ công giao diện của T và sau đó sử dụng nó.
Aran Mulholland

1
@Aran: vâng, viết mã bằng tay hoặc sử dụng công cụ như svcutil (giả sử dịch vụ đang chạy và có thể truy cập được).
Igby Largeman

9

Proxy sẽ xây dựng các chức năng không đồng bộ khá hay.


2
có - đồng thời, cả "Thêm tham chiếu dịch vụ" của Visual Studio cũng như svcutil.exe trên dòng lệnh giết chết cấu hình của bạn ngoài khả năng nhận dạng .... ít nhất với svcutil.exe, bạn có thể xác định chuyển đổi "/ noconfig" .....
marc_s

1
ChannelFactory cũng cung cấp các phương thức không đồng bộ: msdn.microsoft.com/en-us/library/ms731177.aspx Nhưng tôi thích sử dụng mẫu T4 để tạo một lớp không đồng bộ bằng ThreadPool sẽ gọi các phương thức đồng bộ.
SandRock

1
Như một bản cập nhật: Với .NET 4.5 ChannelFactory <T> cũng hỗ trợ các chức năng không đồng bộ dựa trên tác vụ.
gimpf

8

Câu trả lời của tôi là một dạng tóm tắt các câu trả lời của KeithAndrew Hare .

Nếu bạn không điều khiển máy chủ, nhưng chỉ có WSDL / URL, hãy tạo proxy bằng Visual Studio hoặc svcutil. (Lưu ý rằng Visual Studio đôi khi không thành công, khi svcutil hoạt động tốt hơn).

Khi bạn kiểm soát cả máy chủ và máy khách, hãy chia sẻ giao diện / hợp đồng và gọi ChannelFactory
.


2

Nó không chỉ là vấn đề thời gian tiết kiệm. Sử dụng proxy được tạo WSDL rất nguy hiểm vì nếu bạn quên cập nhật tham chiếu dịch vụ, bạn có thể để giải pháp ở trạng thái không nhất quán. Mọi thứ được biên dịch nhưng hợp đồng dịch vụ bị phá vỡ. Tôi thực sự khuyên bạn nên sử dụng ChannelFactory bất cứ khi nào có thể, bạn sẽ làm cho cuộc sống của mình dễ dàng hơn nhiều.

Một giải pháp thay thế khả thi có thể là viết một kịch bản dựng sẵn gọi tiện ích SVCUtil để tạo proxy mỗi khi bạn xây dựng dự án của mình, nhưng dù sao thì ChannelFactory cũng gọn gàng và thanh lịch hơn nhiều.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.