问题
Based on the given answer to my question at Entity Framework in layered architecture, Now I'd like to move my repositories (Which are now only responsible for CRUD abstraction, not business logic stuff) to DAL and reserve BLL for Business Logic.
I've come to the conclusion that the entity context should be considered a unit-of-work and therefore not reused. So I'd like to create an obejctcontext per HttpContext in my repositories to prevent performance/thread [un]safety issues. I'd like to define the objectcontext in repositories as follows:
public MyDBEntities ctx
{
get
{
string ocKey = "ctx_" + HttpContext.Current.GetHashCode().ToString("x");
if (!HttpContext.Current.Items.Contains(ocKey))
HttpContext.Current.Items.Add(ocKey, new MyDBEntities ());
return HttpContext.Current.Items[ocKey] as MyDBEntities ;
}
}
In that case, the DAL project should be aware of HttpContext.Current variable. I'm not sure if this is a good practice and would like to know your opinions.
回答1:
No accessing HttpContext outside of the web application is bad practice because it tightly couples your code to web environment. What you are looking for is probably inversion of control container with per HTTP request object lifetime manager.
Suppose that you define your business logic as:
public class BusinessService : IBusinessService
{
// Constructor with dependency injection
public BusinessService(IObjectContext context)
{ ... }
...
}
Now when you want to use BusinessService you have to create its instance and pass it IObjectContext as parameter. When using inversion of control container you can take advantage of this definition and instead of constructor call something like:
IBusinessService service = container.Resolve<IBusinessService>();
Inversion of control (IoC) container has to be configured to be able to instantiate concrete implementation of IBusinessService and IObjectContext. Moreover this configuration usually allows defining lifetime of instantiated object. When per HTTP lifetime is allowed each call to Resolve within single request returns same instance.
You can go even futher by letting container resolve the class using your business services. It is usually done with ASP.NET MVC. In such case you only define constructors receiving services as parameters in your main classes (controllers) and let IoC container to build whole object hiearchy.
For inversion of control containers check for example Windsor Castle. I'm using MS Unity but it doesn't provide per HTTP lifetime manager out of the box.
来源:https://stackoverflow.com/questions/4612681/accessing-httpcontext-current-in-data-access-layer