2009-07-22 44 views
13

Tôi đang xây dựng một ứng dụng gần giống với mẫu kho chứa với một lớp dịch vụ ở trên cùng, tương tự như các phiên bản đầu của Cửa hàng MVC của Conery.Lớp dịch vụ có quyền truy cập vào HttpContext không?

Tôi cần triển khai trang trả về tất cả người dùng ngoại trừ người dùng hiện tại. Tôi đã có GetUsers() phương pháp trên các kho lưu trữ và các lớp dịch vụ, do đó, câu hỏi là nơi để áp dụng "ngoại trừ người dùng hiện tại."

Lớp dịch vụ có nên biết HttpContext không, do đó áp dụng quy tắc này? Tôi chỉ muốn chuyển người dùng hiện tại (id) từ bộ điều khiển đến phương thức dịch vụ này, nhưng nó có vẻ sạch hơn nếu lớp dịch vụ là HttpContext-aware và có thể tự làm điều này.

Một thay thế rõ ràng là áp dụng quy tắc này trực tiếp trong Controller, nhưng tôi chỉ không nóng trên ý tưởng rằng ...


Edit - chỉ bình luận về câu trả lời: Tôi thấy vấn đề với vấn đề phụ thuộc ngược lại, một cái gì đó tôi đã hoàn toàn nhìn ra. Tôi đánh dấu Mehrdad là câu trả lời đúng hạn, nhưng mọi người đã thực sự cung cấp một phản hồi có giá trị đáng đọc!

Trả lời

18

Tuyệt đối không. Suy nghĩ của tôi trong việc thiết kế những thứ như thế này: Tôi cho rằng tôi cần phải viết một ứng dụng dựa trên Windows cùng với ứng dụng Web và cố gắng giảm thiểu sự phụ thuộc vào các công cụ cụ thể trên Web. Việc chuyển trực tiếp HttpContext sẽ trực tiếp tăng khả năng kết nối lớp dịch vụ của bạn với lớp giao diện người dùng web của bạn, điều này không lý tưởng.

4

Bạn nên không tạo phụ thuộc ngược giữa lớp dịch vụ và cấp web. Hãy xem xét điều gì sẽ xảy ra khi bạn muốn mở rộng lớp dịch vụ của mình để làm việc với một ứng dụng dựa trên biểu mẫu hoặc dịch vụ windows. Bây giờ bạn đã phải làm việc xung quanh sự phụ thuộc web để có được các phương pháp tương tự của bạn để làm việc hoặc sao chép một số (có lẽ, nhỏ, nhưng vẫn còn trùng lặp) mã. Bạn sẽ được phục vụ tốt hơn để trích xuất mã định danh của người dùng thành một cái gì đó hữu ích trong ngữ cảnh của lớp dịch vụ và sử dụng giá trị đó với lớp dịch vụ. Việc xử lý lọc trên trang web cũng có thể chấp nhận được, mặc dù nếu bạn làm điều đó nhiều hơn một lần, nó sẽ cần phải được cấu trúc lại thành một nơi phổ biến và lớp dịch vụ là điểm tự nhiên cho nó.

2

Tôi thấy thực tiễn tốt để tạo lớp AppContext tùy chỉnh chứa đối tượng người dùng hiện tại của tôi (cũng như dữ liệu ngữ cảnh khác). Lớp này không có tham chiếu đến System.Web. Bất kỳ phương thức dịch vụ nào cần biết ngữ cảnh đều phải có tham số AppContext (ví dụ: để kiểm tra quyền bảo mật hoặc nhận người dùng hiện tại như trong trường hợp của bạn). Điền vào đối tượng này trong tầng web và giữ nó trong phiên nếu bạn cần. Bằng cách này, lớp dịch vụ của bạn không biết gì về System.Web.

+0

Có gì sai khi chỉ cần chuyển Id người dùng? –

+0

Không có gì sai với nó cả, tôi giống như xử lý tất cả các tình huống nhận thức ngữ cảnh theo cùng một cách. – JonoW

+0

Tôi thích ý tưởng này, JonoW! Tôi chỉ có thể vượt qua các id cho bây giờ, nếu/khi phương pháp dịch vụ của tôi bắt đầu nhận được xấu xí với params và quá tải này sẽ là tuyệt vời. Tôi thậm chí có thể vượt qua AppContext khi instantiating đối tượng dịch vụ, do đó thực hiện mong muốn của tôi để có dịch vụ phần nào "nhận thức" nhưng không phụ thuộc vào System.Web. –

9

Câu trả lời là, no.

Lớp dịch vụ không chỉ phụ thuộc vào Lớp trình bày hiện tại, theo ý kiến ​​của tôi, nó không có sự phụ thuộc vào ứng dụng hiện tại. Ví dụ: tôi sẽ không sử dụng lớp AppContext tùy chỉnh làm JonoW được đề xuất here.

Thay vào đó, hãy chuyển người dùng hiện tại làm tham số đến phương thức GetAllUsersExceptForTheCurrentUser.Đó, dịch vụ có thể được sử dụng bởi bất kỳ ứng dụng nào cần xử lý người dùng, không chỉ ứng dụng hiện tại.

+0

Đồng ý. Cụ thể, bạn sẽ cảm ơn bản thân vì không thêm * context * và * state * vào một lớp dịch vụ vào lúc bạn cần đặt nó đằng sau một bộ cân bằng tải. –

+0

Cảm ơn, John, đây là một điểm tuyệt vời. Làm cho tôi xem xét lại phản ứng của tôi với lời đề nghị của JonoW. –

+0

Tôi nhận được những gì các bạn đang nói, nhưng khi tôi nói một phương pháp dịch vụ cần phải được nhận thức ngữ cảnh, tôi có nghĩa là có một phương pháp dịch vụ cần biết ai đang gọi nó. Ví dụ, các bạn xử lý ủy quyền như thế nào? tức là xác định liệu người gọi phương thức có được phép gọi phương thức không? Tôi là một chút của một newb trong lĩnh vực này, vì vậy quan tâm để nghe như thế nào những người khác làm điều đó/những gì thực hành tốt nhất là. Chúc mừng – JonoW

1

Không. Làm như vậy sẽ làm cho mã của bạn khó kiểm tra và sử dụng lại.

Tôi có xu hướng xây dựng một giao diện cơ sở hạ tầng cho loại điều này (gọi nó là IAuthentication hoặc một cái gì đó) và hiển thị thuộc tính CurrentUser trên đó. Sau đó, tôi muốn tiêm điều này vào dịch vụ của tôi thông qua một nhà xây dựng của nó. tức là MyService công khai (xác thực IAuthentication)

Cuối cùng, bạn có thể xây dựng một triển khai thực hiện nhận thức của HttpContext về IAuthentication (nói WebAuthentication).

Bây giờ khi bạn tạo ra dịch vụ của bạn, bạn tạo ra phụ thuộc của nó cũng như:

var myService = new MyService(new WebAuthentication()); 
var otherUsers = myService.GetAllOtherUsers(); 

Nếu bạn đang sử dụng một container IoC phụ thuộc xấu xí thậm chí có thể đi đi!

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