Unity with HierarchicalLifetimeManager. Do I need a 'Using' Statement with Entity Framework - entity-framework

I am using Unity and Entity Framework in a Web API 2 application. I register types with the HierarchicalLifetimeManager.
var container = new UnityContainer();
container.RegisterType<IService, Service>(new HierarchicalLifetimeManager());
Do I need to wrap all my dbContext calls in a using statement like this? Is this needed? I thought Unity will dispose the context for me.
using (var client = new dbContext())
{
var result = client.Customers.toList();
}
Or can I just use dbContext without the using statement?

Do I need to wrap all my dbContext calls in a using statement like
this?
I would say that it depends on how you use your context. Take this example:
public class Service : IService, IDisposable
{
private DbContext _context;
public Service(DbContext context)
{
_context = context;
}
public object Get(int id)
{
return _context.Customers.Find(id);
}
public object Update(object obj)
{
// Code for updating
}
public void Dispose()
{
_context.Dispose();
}
}
If you register Service with HierarchicalLifetimeManager the context will practially never be disposed, since nothing will dispose the service and thus never dispose the context. However, the example above should work fine with TransientLifetimeManager.
From MSDN:
HierarchicalLifetimeManager. For this lifetime manager, as for the
ContainerControlledLifetimeManager, Unity returns the same instance of
the registered type or object each time you call the Resolve or
ResolveAll method or when the dependency mechanism injects instances
into other classes.
If you instead dispose it in each method, then it will be correctly disposed regardless of what lifetimemanager you use. Also, the consumer of IService doesn't need to care about disposing IService.
public class Service : IService
{
public object Get(int id)
{
using (var context = new DbContext())
{
return context.Customers.Find(id);
}
}
public object Update(object obj)
{
// Code for updating
}
}
Also, consider what happens if your Service was Transient, and is injected in a manager that is ContainerController. Since the manager never is disposed, neither is the service. The manager will keep the same instance of the service throughout the lifetime of the container. Therefore I personally suggest that you keep the disposing of the context outside of the containers control. It can work very well with the help of lifetimemanagers if you make sure that you have a chain of disposings. There are several posts here and on codereview that show examples of UoW with Unity to dispose the context.

Related

Disposing of object context when implementing a repository (DAL) and Mocking DAL for TDD

I am running into an issue where I can't figure out how to properly dispose of my object context I am creating every time I instantiate a new object.
public class OrderBLL{
var _iOrderLineDal;
public OrderBLL(){
_iOderLineDal = new OrderLineDal(new entityOBject(dbconnectionstring);
}
public OrderBLL(iOrderLineDal mockOrderLineDal){
_iOrderLineDal = mockOrderLineDal;
}
}
So the problem is, that every 30 seconds my service creates a new instance of the OrderBLL and then runs a method to see if there are any new orders in the Data base.
So every 30 seconds I create a new entityObject that is not being disposed of. the old implementation of the code was written using the using statement.
public bool HasNewOrders(){
using(var entityObject = new entityObject(dbconnectionString)){
var newOrders = entityObject.GetNewOrders();
}
//some logic
}
The problem with using this using statement is I cannot mock out the entityObject and easily write unit tests on any methods inside this OrderBLL class.
I tried disposing of it with a dispose method inside the OrderLineDal and once i got the data called dispose. That worked well the first iteration but the following iterations, the next 30 seconds, it would say that the entityObject was disposed of and cannot be used. (doesn't make sense to me, since I am creating a new one every time?)
Is there a way I can implement this repository pattern and still dispose of all the new entityObjects so I can mock the DAL out for unit testing?
I am working with EF 4. and it was not set up Code First, so I do not have POCO.
Ideally you would want to create your context outside of your OrderBLL (search google for Repository pattern).
public class OrderRepository : IOrderRepository, IDisposable
{
private readonly IOrderDBContext _dbContext;
// poor mans dependency injection
public OrderRepository() : this(new OrderDbContext("YourConnectionString")
{}
public OrderRepository(IOrderDBContext dbContext)
{
if (dbContext == null) throw new ArgumentNullException("dbContext");
_dbContext = dbContext;
}
public bool GetNewOrders(){
return _dbContext.Orders.Where(o => o.IsNew==true);
}
public void Dispose()
{
if (_dbContext != null) _dbContext.dispose();
}
}
public class OrderBLL : IOrderBLL
{
private readonly IOrderRepository _repository;
public OrderRepository(IOrderRepository repository)
{
if (repository == null) throw new ArgumentNullException("dbContext");
_repository = repository;
}
public bool HasNewOrders(){
var newOrders = _repository.GetNewOrders();
if (newOrders==null) return false;
return newOrders.Count() > 0;
}
}
[Test]
public void HasNewOrders_GivenNoNNewOrdersRetunedFromRepo_ReturnsFalse()
{
// test using nunit and nsubstitute
// Arrange
var repository = Substitue.For<IOrderRepository>();
var emptyOrderList = new List<Order>();
repository.GetNewOrders().Returns();
var orderBLL = new OrderBLL(repository);
// Act
var result = orderBLL.HasNewOrders();
// Assert
Assert.Equals(false, result);
}
Now you can inject your context into this class and easily test your business logic. Eventually you will need to create your dbContext and should also always expose this. I would suggest having a look at a DI container like Castle Windsor to manage the life of your objects, although in a service you may just want to manually create and dispose your context as close to the code entry point as possible (e.g. in the main method)

DbContext is Disposed Exception using StructureMap

I am using StructureMap as my IOC Container. I created a seed method that runs on start-up, to be sure the database has relevant data. When this runs, i get the error
The operation cannot be completed because the DbContext has been disposed.
The seed class in question is
public class SeedDatabase : IRunAtStartup
{
private DbContext _context;
private UserManager<ApplicationUser> _userManager;
public SeedDatabase(DbContext context, UserManager<ApplicationUser> userManager)
{
_context = context;
_userManager = userManager;
}
public async void Execute()
{
if (!_context.Set<ApplicationUser>().Any())
{
//Seed Admin User
await _userManager.CreateAsync(new ApplicationUser
{
UserName = "Admin",
Company = "Test Company Ltd",
EmailAddress = "email#emailaddress.com"
}, _userManager.PasswordHasher.HashPassword("Password"));
_context.SaveChanges();
}
}
}
The error occurs on hitting .SaveChanges()
This method just runs once at startup and it accepts a UserManager and DbContext in its conctructor which are provided by means of the IOC Container.
I have tried handling the DbContext per HttpRequest, which was my preference, but also as a singleton. However, the situation did not change.
Here is some of the setup for IOC Container
//convention for DbContext
public class DbContextConvention : IRegistrationConvention
{
public void Process(Type type, Registry registry)
{
//be sure a new context is used for each request
if (type.CanBeCastTo(typeof(DbContext)) && !type.IsAbstract)
{
registry.For(type).LifecycleIs(new UniquePerRequestLifecycle());
}
}
}
Any ideas why I keeps disposing it before it has even been used?
The problem is probably caused by the asynchronous nature of your Execute method. This method will return almost immediately and will continue on a background thread. You are probably disposing the DbContext after Execute returned, but at that moment in time the background operation hasn't finished. Instead, return a Task and wait for that task to finish before cleaning up, or make the Execute method synchronous.

Disposing entity framework dbcontext in singleton class (StructureMap)

In my application i am using StructureMap with EntityFramework.
Well, my ioc config looks like :
x.For<IDbContext>().Use(c => new DbContext(AppSettings.ConnectionString));
x.For<IManager>().Singleton().Use<DefaultManagerImplementation);
x.For<IManagerService>().Use<DefaultManagerServiceImplementation>();
My problem is about disposing DbContext instance, which one is use in IManagerService.
IManagerService :
using(var ctx = new DbContext(AppSettings.ConnectionString)
{
// works fine
ctx.
ctx.save();
}
public class ManagerService : IManagerService
{
private readonly IDbContext _dbContext;
public ManagerService(IDbcontext dbContext)
{
// not works, because DbContext is not disposed?
_dbContext = dbContext; // inject
...
_dbContext.Get... return old data
}
}
Well, is here any change to force dispose object which lives in singleton instance in structure map?
Thanks
You won't get any automatic disposing of this object because as far as your container is concerned, you're still using it. There are two options here:
Explicitly call .Dispose() on the DbContext when you're finished with it. You won't be able to use the DbContext anywhere else within your Singleton, since the object is now gone.
Instead of taking a dependency on DbContext, take a dependency on Func<DbContext> (or some other factory interface). I'm not sure about StructureMap, but other IoC containers handle Func automatically as long as you've registered T, so this shouldn't need any new dependencies. This would change your constructor to the following:
public class ManagerService : IManagerService
{
private readonly Func<IDbContext> _dbContextFactory;
public ManagerService(Func<IDbContext> dbContextFactory)
{
_dbContextFactory = dbContextFactory; // inject
using (var context = _dbContextFactory())
{
...
// Do stuff with your context here
} // It will be disposed of here
using (var context = _dbContextFactory())
{
// ...and here's another context for you
}
}
}

Ninject PerRequest injection

I have a MVC 2.0 application using Ninject.Web.Mvc2 and a repository pattern (built over an entity framework model ). I am trying to create a new ObjectContext that will only live for the duration of the request. I am attempting to accomplish this in the following manner:
protected override IKernel CreateKernel(){
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
return kernel;
}
protected override void OnApplicationStarted()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
I then ran out of ideas for keeping this generic enough so I set to work in the BeginRequest:
protected void Application_BeginRequest()
{
string EntityConnectionString = ConfigurationManager.ConnectionStrings["Entities"].ConnectionString;
HttpContext.Current.Items.Add(_PerRequestContextObjectKey, new EntityFrameworkContextWrapper(EntityConnectionString));
this.Kernel.Bind<IUserRepository>().To<UserRepository>().WithConstructorArgument("ContextWrapper", HttpContext.Current.Items[_PerRequestContextObjectKey]);
}
The Wrapper class is just a generic object for including anything I want to kill at the end of request. In this specific case, I use it to create my new ObjectContext and also implement IDisposable so I can do the following:
protected void Application_EndRequest()
{
foreach (var Item in HttpContext.Current.Items)
{
if (Item.GetType() == typeof(IPerRequestLifetimeObjectWrapper))
{
(Item as IPerRequestLifetimeObjectWrapper).Dispose();
}
}
}
I'm sure it's not the prettiest way of doing this, but at this point I'm trying to get moving since I've spent so much time "learning" all this stuff.
My Controller is then injected like so:
public class AdminUserController : Controller
{
// Mark for Ninject
[Inject] public IUserRepository _userRepo { get; set; }
public ViewResult Index( )
{
return View(_userRepo.Get);
}
public ViewResult Edit(Guid UserUID)
{
return View(_userRepo.GetById(UserUID));
}
}
and my Repository gets injected as well:
[Inject]
public UserRepository(EntityFrameworkContextWrapper ContextWrapper )
// Mark for Ninject Dependency Injection
// Must receive Wrapper that contains active ObjectContext
{
_db = ContextWrapper.Entities; //Not actually named this, just easier for typing right now
}
When my Controller calls the Get method inside my UserRepository object the first time it works great. If I hit refresh ( or I'm guessing postback as well ), _db is Null. When I try to step through the debugger, I find that the Controller Index( ) method is being called before a Application_BeginRequest() is called. I thought I had an understanding of the "pipeline" ( I'm used to calling things page lifecycle from WebForms ), but now I'm a bit lost. Can someone elaborate on where my brain has some wires crossed? Like I said, this probably isn't the prettiest method, but I've only had about a week and a half to learn MVC, DI with Ninject, Repository, and Entity Framework so please don't feel like you're talking down to me if it seems like I broke something very basic.
Why don't you simply use InRequestScope? What you do is adding a new binding for each request. This will lead to severe problems.
See https://github.com/ninject/ninject.web.mvc/wiki/Unit-of-work-pattern-with-nhibernate
It's NHilbernate but you can do the same with EntityFramework

When to call Dispose in Entity Framework?

In my application I am making use of Spring.Net for IoC. The service objects are called from the ASP.Net files to perform CRUD operations using these service object. For example, I have CustomerService to do all CRUD operations on Customer table. I use entity framework and the entities are injected .. my question is where do I call the dispose method?
As far as I understood from the API documentations, unless I call Dispose() there is no guaranty it will be garbage collected! So where and how do I do it?
Example Service Class:
public class CustomerService
{
public ecommEntities entities = {get; set;}
public bool AddCustomer(Customer customer)
{
try
{
entities.AddToCustomer(customer);
entities.SaveChanges();
return true;
}
catch (Exception e)
{
log.Error("Error occured during creation of new customer: " + e.Message + e.StackTrace);
return false;
}
}
public bool UpdateCustomer(Customer customer)
{
entities.SaveChanges();
return true;
}
public bool DeleteCustomer(Customer customer)
.
.
.
And I just create an object of CustomerService at the ASP partial class and call the necessary methods.
Thanks in advance for the best practice and ideas..
Regards,
Abdel Raoof
I have HttpModule in my application, which takes care of creating and disposing of context:
public class MyEntitiesHttpModule : IHttpModule
{
public void Init(HttpApplication application)
{
application.BeginRequest += ApplicationBeginRequest;
application.EndRequest += ApplicationEndRequest;
}
private void ApplicationEndRequest(object sender, EventArgs e)
{
if (HttpContext.Current.Items[#"MyEntities"] != null)
((MyEntities)HttpContext.Current.Items[#"MyEntities"]).Dispose();
}
private static void ApplicationBeginRequest(Object source, EventArgs e)
{
//TextWriter logFile = File.CreateText(HttpContext.Current.Server.MapPath("~/sqllogfile.txt"));
var context = new MyEntities();
//context.Log = logFile;
HttpContext.Current.Items[#"MyEntities"] = context;
}
}
It creates it at the beginning of request and disposes at the end. Context is taken from HttpContext.Current.Items by Ninject and injected into my service object. I don't know how exactly it works with Spring.Net and what is your approach to creating ObjectContext, but I hope this answer will help. If Sprint.Net supports per request lifetime and doesn't need any modules, it propably takes care of disposing too. In other case, you can do it like here.
#LukLed is generally correct (+1) that the HTTP request is the correct scope. However, I very much doubt explicit code is required to call Dispose() with either NInject or Spring.Net as both of these should already be disposing instances they manage. HttpContext.Current is as good a place to store the reference as anything.
However, you (#Abdel) are wrong to say:
As far as I understood from the API documentations, unless I call Dispose() there is no guaranty it will be garbage collected!
This is just not right. Dispose() makes the collection somewhat more optimal and provides for deterministic release of unmanaged resources (e.g., your DB connection). But everything will eventually be collected, with or without calling Dispose().