2011-06-17 16 views
10

Mục tiêu của tôi là có một ngữ cảnh dữ liệu (MainDbContext) theo yêu cầu HTTP trong ASP.NET MVC và hủy bỏ bối cảnh dữ liệu khi yêu cầu kết thúc.StructureMap không loại bỏ bối cảnh dữ liệu khi sử dụng HttpContextScoped()

Tôi đang sử dụng cấu hình StructureMap sau:

public static class ContainerConfigurer 
{ 
    public static void Configure() 
    { 
     ObjectFactory.Initialize(x => 
     { 
      x.For<MainDbContext>().HttpContextScoped(); 
     }); 
    } 
} 

Bất cứ khi nào tôi cần một MainDbContext, Tôi đang sử dụng mã này:

var dbContext = ObjectFactory.GetInstance<MainDbContext>(); 

này đang làm việc như mong đợi: chỉ có một bối cảnh dữ liệu đang được tạo theo yêu cầu HTTP. Vấn đề là, MainDbContext không được xử lý ở cuối yêu cầu.

Làm cách nào tôi có thể định cấu hình ObjectFactory để xử lý ngữ cảnh dữ liệu khi yêu cầu HTTP kết thúc? Hoặc đây chỉ là một cái gì đó tôi cần phải làm bằng tay bằng cách sử dụng Application_EndRequest() trong Global.asax.

Cập nhật

Tôi chỉ cố gắng thêm mã sau đây để Global.asax:

protected virtual void Application_EndRequest() 
{ 
    ObjectFactory.GetInstance<MainDbContext>().Dispose(); 
} 

Đúng như dự đoán, điều này giải quyết vấn đề. Tôi vẫn tự hỏi nếu có bất kỳ cách nào để làm điều này tự động với StructureMap, tuy nhiên.

Trả lời

10

Thay vì:

x.For<MainDbContext>().HttpContextScoped(); 

Hãy thử:

x.For<MainDbContext>().HttpContextScoped().Use(() => new MainDbContext()); 

Cũng bình thường nó là lớp kho cần một bối cảnh db. Vì vậy, thay vì ObjectFactory.GetInstance<MainDbContext>(); có kho lưu trữ của bạn mất một số bối cảnh giao diện db và cấu hình StructureMap để tiêm MainDbContext vào chúng. Sau đó hãy chắc StructureMap tiêm kho vào bộ điều khiển, ...

Trong Application_EndRequest:

protected void Application_EndRequest() 
{ 
    ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects(); 
} 
+0

không có sự khác biệt. 'Dispose()' vẫn chưa được gọi. – devuxer

+0

Tôi đã tiêm một ngữ cảnh dữ liệu vào kho/dịch vụ của tôi như bạn đề xuất. Vấn đề là, tôi cũng có ActionFilters, Validators, và MembershipProvider yêu cầu bối cảnh dữ liệu, và vì các đối tượng này được tự động hóa bởi ASP.NET MVC (giống như controller), tôi đang sử dụng StructureMap để quản lý toàn bộ thời gian ngữ cảnh dữ liệu. Nếu bạn có giải pháp tốt hơn, vui lòng cho tôi biết. – devuxer

+0

@DanM, bạn là chính xác, tôi đã thử nghiệm nó và có vẻ như 'StructureMap' không tự động vứt bỏ' IDisposable' đối tượng phạm vi HttpContext ở phần cuối của yêu cầu. Gọi 'ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects' trong' Application_EndRequest' có lẽ là cách tốt nhất để đảm bảo rằng điều này xảy ra cho tất cả các đối tượng. –

5

Sử dụng a nested container là cách duy nhất để có được cấu Map để tự động xử lý các đối tượng. Nếu bạn không sử dụng kỹ thuật đó, cách duy nhất là tự vứt bỏ các đối tượng bằng cách mô tả OP (kéo đối tượng ra khỏi thùng chứa và xử lý nó; xem này NHibernate example cho một cách để thực hiện) hoặc phạm vi đối tượng để HttpRequest và gọi ReleaseAndDisposeAllHttpScopedObjects như Darin mô tả.

+0

+1 và cảm ơn, PHeiberg. Thùng chứa lồng nhau trông giống như một giải pháp thú vị, nhưng nếu tôi sử dụng mẫu mã mà bạn đã liên kết với tình huống của mình, tôi tin rằng nó sẽ xử lý ngữ cảnh dữ liệu của tôi vài lần theo yêu cầu. Mục tiêu của tôi là chỉ có một ngữ cảnh dữ liệu cho mỗi yêu cầu. Nó cũng có vẻ như nó sẽ dẫn đến nhiều mã hơn. Vì vậy, tôi nghĩ rằng tôi sẽ gắn bó với giải pháp của Darin. Hãy sửa tôi nếu tôi hiểu lầm. – devuxer

+0

Khi sử dụng một thùng chứa lồng nhau, bạn sẽ tạo một thể hiện của thùng chứa lồng nhau theo yêu cầu và vứt bỏ nó ở cuối yêu cầu. Xử lý một thùng chứa lồng nhau sẽ xử lý tất cả các đối tượng tạm thời được tạo bên trong nó. Tôi đã không nhìn thấy bất kỳ ví dụ về cách sử dụng container lồng nhau với ASP.NET MVC hoặc Webforms. Ví dụ của Jeremy đang sử dụng Fubu và NHibernate (http://codebetter.com/jeremymiller/2010/01/06/how-dovetail-uses-structuremap-with-nhibernate). Đối với kịch bản đơn giản Darin hoặc theo cách của bạn có lẽ là dễ nhất. Tôi đã sử dụng chúng cho tất cả các ứng dụng web của tôi với SM. – PHeiberg

+1

Tôi chỉ cần thêm vào như đã đề cập trong bài báo liên kết rằng thùng chứa lồng nhau “kéo” tất cả các trường hợp như bất cứ điều gì nhưng transients (Singletons, đối tượng phạm vi HttpContext, đối tượng scoped ThreadLocalStorage, v.v.) từ thùng chứa cha. Các đối tượng này không được xử lý từ thùng chứa lồng nhau. Vì vậy, nếu sự hiểu biết của tôi là tốt, các đối tượng HttpContextScoped sẽ không được xử lý anyway. –