2014-05-21 24 views
10

Tôi có một ứng dụng MVC 5 khá chuẩn bao gồm một tầng kho lưu trữ, lớp dịch vụ và một lớp điều khiển. Để giữ cho mỗi lớp được tách rời và có thể kiểm tra, tôi đang sử dụng Ninject để tiêm phụ thuộc.ASP.NET MVC 5 Quản lý ngữ cảnh không đồng bộ

Để đánh dấu kỹ năng mới, tôi đã quyết định sử dụng các tác vụ mới của Bộ điều khiển tác vụ mới với async/await trên các hoạt động liên kết IO cho các phương thức dịch vụ và bộ điều khiển.

Thông thường tôi chỉ tận dụng các InRequestScope ràng buộc như vậy

kernel.Bind<IDbContext>().To<BlogContext>().InRequestScope(); 

Nói chung này đang làm việc tốt bây giờ, tuy nhiên nếu tôi đã chọn để gỡ lỗi ứng dụng của tôi, hoặc tham gia nhiều khuôn khổ thực thể theo dõi các đối tượng với nhau và tiết kiệm, Tôi đang tìm thấy bối cảnh đã được xử lý hoặc tôi đang nhận được các vấn đề theo dõi. Tôi thấy lý do tại sao điều này xảy ra, nó hoàn toàn hợp lý bởi vì các hoạt động không còn diễn ra trên thread IIS, do đó, làm thế nào Ninject sẽ biết rằng nó nên được sử dụng cùng một bối cảnh.

Để giải quyết vấn đề này, tôi có thể chuyển ngữ cảnh của mình vào mỗi cuộc gọi kho từ lớp dịch vụ của tôi hoặc thậm chí từ lớp điều khiển nếu cần. Tuy nhiên tôi cảm thấy điều này có vẻ lộn xộn và tôi muốn Ninject quản lý bối cảnh của đối tượng này nếu có thể.

Các chiến lược tốt nhất để xử lý điều này một cách thanh lịch/tối giản trong khi vẫn giữ mã của tôi tương tự như các ví dụ được đưa ra dưới đây là gì?

Dưới đây là một ví dụ về một trong những phương pháp điều khiển của tôi

public virtual async Task<ActionResult> Edit(int id) 
    { 
     var editViewModel = await BuildDefaultCreateEditViewModel(); 

     var post = await postService.GetNonDeletedPost(id); 
     ... 
     ... 
     return View(MVC.Admin.Post.Views.CreateEdit, editViewModel); 
    } 

phương pháp Dịch vụ

public async Task<PostDTO> GetNonDeletedPost(int postId) 
    { 
     return (await PostRepostiory.GetPost(postId)).ConvertToDTO(); 
    } 

phương pháp Repository

public Task<Post> GetPost(int postId) 
    { 
     return QueryableExtensions.SingleOrDefaultAsync(
       DbSet.Where(post => post.PostId == postId) 
       .Include(post => post.PostVersions) 
       .Include(post => post.Categories) 
       .Include(post => post.Files)); 
    } 
+1

Bạn có sử dụng DbContextFactory không? Tôi có xu hướng sử dụng 'TransientScope' thay vì Request, và tôi không bao giờ gặp bất kỳ vấn đề nào –

+0

Tôi đã thực sự hy vọng rằng tôi có thể sử dụng Ninject theo cách tương tự như một DbContextFactory tương tự như sử dụng InRequestScope. Nếu tôi đã đi xuống con đường của việc sử dụng một DBContextFacotry vấn đề làm thế nào tôi biết được yêu cầu các chủ đề không đồng bộ thuộc về vẫn còn rõ ràng, làm thế nào để tôi phủ nhận điều này? Đối với việc sử dụng phạm vi tạm thời sẽ tạo ngữ cảnh mới cho mỗi kho lưu trữ, nhưng khi tôi đang sử dụng một vài đối tượng ghép (Mặt tiền), và việc lưu sẽ không hoạt động như các đối tượng từ các kho lưu trữ khác nhau. các ngữ cảnh được theo dõi khác nhau. – jps

+0

Thats làm thế nào tôi sử dụng ninject, với DbContextFactory, nó cho phép tôi tiêm bối cảnh vào kho lưu trữ tất cả trong TransientScope. :) –

Trả lời

1

Trong bài viết của bạn và trong các ý kiến ​​có liên quan có một số các ví dụ tuyệt vời về cách thực hiện điều này.

Tuy nhiên, đối với một số độc giả khác có thể vấp ngã ở đây, tôi muốn ném ra một câu hỏi trung thực: Bạn thậm chí có thực sự cần bộ điều khiển không đồng bộ không?

Thao tác điều khiển không đồng bộ giải phóng số lượng chuỗi cần thiết để xử lý yêu cầu; Tuy nhiên, nếu bạn không chạy ra khỏi chủ đề và không có khả năng, thì bạn đang tạo ra sự phức tạp trong khi cố gắng giải quyết một vấn đề mà bạn không có và cũng không mong đợi. Hoặc: "Async có thực sự miễn phí và luôn tốt hơn không?"

Hiệu quả, tôi đang cố gắng thể hiện rằng một giải pháp khả thi (và có lẽ không phải là giải pháp bạn đang tìm kiếm) sẽ đơn giản là không sử dụng bộ điều khiển không đồng bộ - nếu thực sự không cần thiết (tùy thuộc vào hoàn cảnh.)

Giải pháp lập dị cũ tốt đó giải quyết vấn đề bằng cách xóa sự cố. Và đặc biệt, tôi đề xuất nó vì việc loại bỏ sự phức tạp dường như là một trong những mục tiêu.

Cách chọn Chọn sử dụng? có một danh sách dài, nhưng hai trong số những câu hỏi hay nhất là:

  • Are mục của bạn ngắn chạy?
  • Và nếu không, các mục của bạn có bị ràng buộc CPU không?

http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4

Từ liên kết ở trên "Sử dụng phương pháp hành động không đồng bộ về hoạt động CPU-bound cung cấp không có lợi ích và kết quả ở trên không hơn."

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