I am injecting a new data context into each of my repositories with StructureMap. The life cycle is per HTTP context. But I'm having some problems with "invalid cast specified errors" which I've narrowed down to "not disposing data contexts". See my related question.
Where should I dispose of my data context (DB class) without modifying each read/write repository method? Wherever I modify data, I've used a new DB() in a using(...)
, so it's only necessary for the IQueryable<xxx> Getxxx(...)
methods, but some of them are interdependent, so I don't want a dispose to cause DataContext disposed
errors.
Bootstrapping:
public class DBServiceRegistry : Registry
{
public DBServiceRegistry()
{
For&开发者_Go百科lt;DB>().HttpContextScoped().Use(new DB());
}
}
Repository:
This data context is passed to my repositories who accept it like so:
public class SqlProductRepository : IProductRepository //, IDisposable
{
private DB _db;
public SqlProductRepository(DB db)
{
_db = db;
}
...
}
Querying:
public IQueryable<Models.Product> GetProducts()
{
var products =
from p in _db.Products
let images = GetProductImages().WithProductID(p.ProductId)
select new Models.Product
{
ID = p.ProductId,
ProductCode = p.ProductCode,
Name = p.Name,
Description = p.Description,
Price = p.Price,
DateModified = p.Date,
ModelID = p.ModelId,
Images = new LazyList<Models.ProductImage>(images),
EditedBy = p.UserId,
IsTaxable = p.IsTaxable,
Inventory = p.InventoryStatus,
Slug = p.Slug
};
return products;
}
I tried to make SqlProductRepository
IDisposable
, but the error persists. How can I cleanly dispose my data contexes (DB
) without modifying each method (there are a lot)?
One approach is to create an IHttpModule that hooks the EndRequest event (or implement EndRequest in your Global.asax) - have it retrieve the DB context from your container and dispose it.
Solution
Implement IDisposable for repositories and use:
For<DB>().HttpContextScoped().Use(() => new DB());
Instead of
For<DB>().HttpContextScoped().Use(new DB());
精彩评论