2009-12-11 43 views
6

Tôi có một ứng dụng WPF cho đến nay đã được khách hàng chỉ, nhưng bây giờ tôi đang làm việc trên chia nó thành một khách hàng và phía máy chủ. Trong công việc này tôi giới thiệu WCF cho giao tiếp client-server. Ứng dụng của tôi có một số dự án và cần có các tham chiếu dịch vụ từ nhiều hơn một trong số các dự án này.Cấu trúc ứng dụng sử dụng WCF

Nỗ lực ban đầu trong việc phân tách là làm mọi thứ "thẳng về phía trước". Tất cả các dự án cần phải giao tiếp với một dịch vụ được tham khảo dịch vụ, và do đó, làm dự án ứng dụng WPF chính - để có được app.config đó. Tôi tìm thấy điều này để biến thành một mớ hỗn độn khá nhanh chóng, và tôi không thể tưởng tượng đây là những kiến ​​trúc tiêu biểu mà mọi người sử dụng? Tôi cũng đã thấy các vấn đề với thực tế là mỗi tài liệu tham khảo dịch vụ tạo ra một triển khai mới của các lớp DataContract - do đó không có sự hiểu biết chung về các lớp DataContract trên các dự án. Tôi có một số lớp ViewModel trong một dự án, và một dự án khác instanciating một số ViewModel. Tôi muốn truyền đối tượng nhận được từ dịch vụ, nhưng tôi không thể làm đại diện phía máy khách được tạo ra của đối tượng nhận được khác nhau trong mỗi dự án.

Vì vậy, - có cách nào được khuyến nghị để cấu trúc các tách máy khách/máy chủ đó bằng WCF không? Hoặc nguyên tắc để làm theo? Tôi đang suy nghĩ một dự án Proxy phổ biến được sử dụng ở phía máy khách mà giao tiếp với các dịch vụ, kết thúc dữ liệu nhận được và trả về dữ liệu trên một biểu mẫu được biết đến với các thư viện máy khách. Chỉ nên cung cấp một tham chiếu dịch vụ, và tôi đoán tôi chỉ cần App.config trong dự án wpfApp? Điều này có nghĩa không?

Trả lời

16

Tôi thích cấu trúc giải pháp WCF của tôi như thế này:

Hợp đồng (thư viện lớp)
Chứa tất cả các hợp đồng dịch vụ, hoạt động, lỗi, và dữ liệu.Có thể được chia sẻ giữa máy chủ và máy khách trong một tinh khiết kịch bản NET-to-NET

thực hiện dịch vụ (lớp thư viện)
Chứa các mã để thực hiện các dịch vụ, và bất kỳ phương pháp hỗ trợ/trợ giúp cần thiết để đạt được điều này . Không có gì khác.

máy chủ dịch vụ (s) (không bắt buộc - có thể Winforms, Console App, dịch vụ NT)
Có máy chủ dịch vụ (s) để gỡ lỗi/thử nghiệm, hoặc có thể cũng phục vụ sản xuất.

Điều này về cơ bản mang lại cho tôi phía máy chủ của sự vật.

Về phía khách hàng:

Khách hàng proxy (thư viện lớp)
Tôi muốn gói proxy client của tôi vào một thư viện lớp riêng biệt, để họ có thể được tái sử dụng bởi nhiều ứng dụng khách hàng thực tế. Điều này có thể được thực hiện bằng cách sử dụng svcutil hoặc "Thêm dịch vụ tham khảo" và tự tinh chỉnh kết quả app.config khủng khiếp, hoặc bằng cách thực hiện thủ công proxy của khách hàng (khi chia sẻ hợp đồng) bằng cách sử dụng các cấu trúc ClientBase<T> hoặc ChannelFactory<T>.

1-n khách hàng thực tế (bất kỳ loại ứng dụng)
sẽ thường chỉ tham khảo lắp ráp proxy client, hoặc có thể lắp ráp các hợp đồng cũng vậy, nếu nó được chia sẻ. Điều này có thể là ASP.NET, WPF, Winforms, giao diện điều khiển ứng dụng, các dịch vụ khác - bạn đặt tên cho nó.

Bằng cách đó; Tôi có một bố cục đẹp và sạch sẽ, tôi thường xuyên sử dụng nó, và tôi thực sự nghĩ rằng điều này đã làm cho mã của tôi sạch hơn và dễ bảo trì hơn.

Điều này được lấy cảm hứng từ số Extreme WCF screen cast của Miguel Castro trên TV DotNet Rocks với Carl Franklin - được giới thiệu trên màn hình rất khuyến khích!

+0

Cảm ơn câu trả lời rất hay!Một vài câu hỏi sau: Có một máy chủ dịch vụ, bạn cần phải khởi động cả máy chủ và ứng dụng khách khi khởi động ứng dụng của mình? Hay có cách nào để giải quyết vấn đề này? Về Client Proxies - bạn muốn dùng cái nào? Hướng dẫn sử dụng impl âm thanh phù hợp hơn khi bạn không phải đối phó với các tài liệu tham khảo dịch vụ đi ra khỏi ngày .. – stiank81

+0

@ bambuska: chắc chắn, bạn phải khởi động cả máy chủ dịch vụ và khách hàng để kiểm tra; chọn "khởi chạy nhiều dự án" trong Visual Studio để đạt được điều này - bạn có thể khởi chạy cả máy chủ dịch vụ và ứng dụng khách khi nhấn F5. –

+1

Proxy của khách hàng: Tôi thích toàn quyền kiểm soát tôi có khi thực hiện thủ công proxy của khách hàng - điều này ** yêu cầu ** mặc dù tôi có thể chia sẻ hợp đồng giữa máy chủ và ứng dụng khách (kể từ khi sử dụng proxy của proxy khách hàng phải có quyền truy cập đối với các hợp đồng thực tế) –

1

Điều đó tùy thuộc. WCF là một khuôn khổ lớn và nó có nghĩa là để span rất nhiều kịch bản khác nhau.

Nhưng đối với một ứng dụng đơn giản như của bạn, khi bạn không quan tâm đến những thứ như Java interop hoặc các dịch vụ web generic interop, đây là những gì tôi làm:

lớp Tất cả DataContract và giao diện ServiceContract đi vào một thư viện (hoặc thư viện) được chia sẻ giữa máy khách và máy chủ. Lưu ý rằng bạn có lẽ không nên trang trí dịch vụ của bạn Thực hiện với ServiceContract, bạn sẽ tạo một giao diện riêng biệt với các thuộc tính ServiceContract mà bạn có thể đặt trong một assembly chung.

Vì vậy, bạn dường như đang làm mọi thứ đúng đắn. Những gì bạn có thể KHÔNG cần là tự động tạo proxy ở tất cả trong trường hợp này. Điều đó chỉ gây đau cho bạn. Vì vậy, không sử dụng hộp thoại Thêm dịch vụ tham khảo cho những gì bạn đang làm. Chỉ cần bao gồm các hội đồng DataContract được chia sẻ của bạn và sử dụng ChannelFactory để nhận proxy đến giao diện dịch vụ của bạn được định nghĩa trong thư viện được chia sẻ. Điều này cũng giúp bạn không phải tiếp tục tạo lại proxy trong Visual Studio, trong đó, đối với bất kỳ dự án có kích thước phù hợp nào, đều cũ VERY FAST.

Nếu bạn đang đi tuyến đường này, bạn cũng có thể thoát khỏi điểm cuối MetaDataExchange, vì đó chỉ là cần thiết để mô tả dịch vụ cho khách hàng. Vì bạn làm mọi thứ trong một assembly chung, bạn không cần mô tả dịch vụ, vì bạn đã có mô tả dịch vụ ở dạng mã.

+0

Cảm ơn! Điều này nghe rất hấp dẫn. Các proxy được tạo tự động thực sự đã gây ra sự đau đớn ... Tôi thực sự đang thử triển khai tương tự với mô tả bạn đã mô tả, nhưng nó dừng lại khi tôi muốn các dịch vụ không đồng bộ. Tôi có thể dễ dàng sử dụng ChannelFactory để tạo các dịch vụ async không? – stiank81

+0

Ồ, và JavaInterop vv không liên quan gì cả. Đây sẽ là tất cả .net to .net! Có DataContracts trong một thư viện được chia sẻ, tôi thực sự có thể trở lại ví dụ: một đối tượng MyClass từ một dịch vụ, và nó sẽ là cùng một loại chính xác nhận được? – stiank81

+0

Có: http://msdn.microsoft.com/en-us/library/bb885132.aspx –

1

Cấu trúc thông thường tôi sử dụng là:

Thông thường - chứa giao diện, hợp đồng dữ liệu, hợp đồng dịch vụ, lớp trừu tượng v.v ...; Khách hàng - tài liệu tham khảo Chung, chứa lớp proxy máy chủ; Máy chủ - tham chiếu Chung, chứa các lớp thực hiện thực tế;

+1

Đồng ý. Mặc dù tôi thường sẽ làm cho các thư viện phổ biến bao gồm DTO's có thể được sử dụng trên cả hai mặt của dịch vụ và sau đó không sử dụng các lớp proxy được tạo ra. – asgerhallas

+0

Có vẻ như tôi cần có một dự án chung cho nội dung được chia sẻ ..! Bạn đang sử dụng proxy được tạo tự động hay bỏ qua những proxy đó - như @asgerhallas? Chắc chắn tôi muốn bỏ qua việc sử dụng chúng nếu tôi có thể. Họ đã gây ra quá nhiều đau đớn rồi .. – stiank81

+1

Tôi lấy được lớp proxy từ ClientBase và triển khai giao diện để chuyển tiếp cuộc gọi đến Kênh. – Goran

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