2012-06-22 28 views
5

Tôi mới vào cả EF và Ninject nên tha thứ cho tôi nếu điều này không có ý nghĩa :)DbContext vứt bỏ sau khi yêu cầu đầu tiên khi sử dụng InRequestScope Ninject của()

Tôi có một ứng dụng MVC3 với Ninject và Ninject.Web. Tham khảo chung. Tôi đang cố gắng để tiêm một DbContext vào kho của tôi. Những gì tôi nhìn thấy là trên yêu cầu đầu tiên, mọi thứ hoạt động tuyệt vời nhưng yêu cầu tiếp theo trở lại:

System.InvalidOperationException: The operation cannot be completed because the DbContext has been disposed. 
    at System.Data.Entity.Internal.LazyInternalContext.InitializeContext() 
    at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression) 
    at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source, Expression`1 predicate) 

bindings của tôi:

kernel.Bind<ISiteDataContext>().To<SiteDataContext>().InRequestScope(); 
kernel.Bind<IProductRepository>().To<ProductRepository>(); 
kernel.Bind<IProductService>().To<ProductService>(); 

lớp dịch vụ của tôi:

public class ProductService : IProductService { 
    [Inject] 
    public IProductRepository repository {get; set;} 

    ... 
} 

Repository của tôi lớp học:

public class ProductRepository : IProductRepository { 
    [Inject] 
    public ISiteDataContext context {get; set;} 

    ... 
} 

lớp SiteDataContext của tôi:

public class SiteDataContext : DbContext, ISiteDataContext 
{ 
    static SiteDataContext() 
    { 
     Database.SetInitializer<SiteDataContext >(null); 
    } 

    public DbSet<Product> Products{ get; set; } 


    protected override void Dispose(bool disposing) 
    { 
     base.Dispose(disposing); 
    } 
} 

điều khiển của tôi:

public class ProductController { 
    [Inject] 
    public IProductService productService {get; set;} 

    ... 
} 

Nếu tôi loại bỏ .InRequestScope(), sau đó nó hoạt động tốt - nhưng sau đó gây ra vấn đề với Entity Framework từ các đối tượng được sửa đổi trong nhiều riêng các trường hợp của ngữ cảnh dữ liệu.

Trả lời

5

Đương nhiên, ngay sau khi đăng nội dung nào đó được nhấp vào trong tâm trí của tôi và tôi đã có thể giải quyết vấn đề này.

Vấn đề nằm ở thực tế là hành vi của ActionFilters đã được thay đổi trong MVC3 và tôi đã có bộ lọc có ProductService được tiêm.

Tôi cho rằng bộ lọc đã xử lý dịch vụ và cuối cùng đã xử lý DbContext.

Trong trường hợp của tôi, giải pháp thật dễ dàng. Tôi tạo ra một DbContext thứ hai được sử dụng đặc biệt cho bộ lọc của tôi. Vì bộ lọc không có gì khác ngoài truy vấn một vài bảng được chọn để xác minh ủy quyền cho các tài nguyên cụ thể, tôi không cần bối cảnh Đơn vị công việc mà DbContext cung cấp trên một yêu cầu duy nhất. Tôi đã tạo một dịch vụ mới sử dụng DbContext mới. Trong trường hợp này, nó là đủ để được cấu hình với InTransientScope()

6

Đặt kho lưu trữ của bạn thành InRequestScope. Họ nên thải bỏ sau mỗi yêu cầu.

Ngoài ra với MVC, bạn nên sử dụng hàm tạo constructor để chèn kho lưu trữ của bạn vào cá thể bộ điều khiển của bạn.

+0

Có lợi ích gì cho việc xây dựng tiêm vs tiêm thuộc tính? –

+1

Tuyệt đối, nó tuân thủ gốc thành phần. Sử dụng các thuộc tính cho mẫu này không thích hợp vì nhiều lý do. Việc sử dụng hàm tạo constructor hoạt động tốt ở đây và nó cho phép các phụ thuộc được biết đến trong thời gian sớm nhất có thể và vì không có lý do để có điều này như là một phụ thuộc tùy chọn với mặc định ở đây. Xem http://www.manning.com/seemann/ là cuốn sách hay nhất về chủ đề này. –

+1

Tôi đang sử dụng DependencyResolver.Current.GetService <... thay vì tiêm costructor. Có thể điều này đang gây ra cùng một vấn đề? (Thao tác không thể hoàn thành vì DbContext đã được xử lý) –

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