I'm using Entity Framework in my project, and I have the problem that, once I pass my entities to a View (keep in mind that these entities have lazy-initialized objects along the lines of: Products.Owner, where owner is an object that is lazily initialized) I get a run-time exception telling me that the ObjectContext is out of scope.
Now this makes sense since I am getting the entities from a Service with a using (.... entities...) { .... } statement, which means it is disposed when the result is returned.
How would I get around this and have an Object Context that is alive from start to end. Thanks.
One option is to associate the repository with the Request, and have the Repository implement IDisposable, and have the Dispose method dispose of the contained ObjectContext, rather than using the more familiar using pattern inside your controller actions.
Related
I'm using a "nested container per request" pattern. It's wrapped in a using block so the nested container is disposed after handling the request. This causes all instances created by the nested container to also be disposed at the end of the request.
This works great and is usually exactly what I want to happen. However I have ran into a use case where I don't want one particular instance to be disposed while everything else is.
I tried explicitly removing the instance at the bottom of the using block like so:
using (var nestedContainer = _container.GetNestedContainer())
{
nestedContainer.Configure ( x =>
x.For<IFoo>()
.Use(getFooForRequest())
);
var handler = (IRequestHandler) nestedContainer.GetInstance(handlerType);
handler.execute(....)
nestedContainer.EjectAllInstancesOf<IFoo>();
}
Unfortunately it appears that EjectAllInstancesOf is also calling dispose.
My application has a few different instances of IFoo, and they all need to live for the entire lifetime of the application. However incoming requests need to be dynamically associated with one particular instance of IFoo.
Injecting it into the nested container like above accomplished this goal, but my IFoo is getting disposed with the nested container, which is bad.
So how do I block the dispose for IFoo while still letting it dispose everything else?
If that's not possible, is there some other way to dynamically select my per-request IFoo without manual injection via nested.Configure()?
Looking at some of the MVC examples online, I've see that typically in a controller the DbContext variable is declared as a private member variable (i.e. global) and accessible to all the methods.
But, I recently came across an article on ASP.NET Identity, and noticed in the controller, the DbContext is declared within each method (that requires it).
Is there a security benefit to this approach? Perhaps limit the lifespan of the security object(s) for better overall security?!?!
If not, then I see the first approach being more efficient, where the database context is instantiated upon the controller loading.
Below is all I could find about DbContext, but nothing to really answer my question.
DbContext declaration - Framework 4.1 - MVC 3.0
MVC, DbContext and Multithreading
On every request, a new instance of the controller is constructed. Therefore, for all intents and purposes, it does not really matter whether the dbcontext is instantiated in the constructor vs encapsulated in any given method.
Aside from a style choice, reasons to declare and contain a dbcontext in a given method is that:
Methods that do not need it will not instantiate the context, eliminating the overhead (if there is any). This can also be accomplished using a lazy initialization pattern.
The context is disposed of immediately as soon as a method is done with it, rather than at the end of the request. Generally this should not be a concern though; usually if users are waiting around for longer than a few seconds you have a bigger problem.
Different methods use different contexts.
Among others, some reasons to declare a single context and instantiate it once:
You have only one place that instantiates a context rather than many. In a typical application, most pages will need some information from the database anyway.
Methods that call other methods will not each hold on to their own instance of a context object.
You can create a base controller class that by default creates a dbcontext object, allowing you to be DRY in all inherited controllers.
Answer from #Ic. is pretty good. I wanted to add that if you need to pass information from your Request into your DbContext constructor then you need to create the instance of your DbContext inside your action methods. The reason is the Request object will be null till the control enters your action method.
More information: I had a need to build connection string dynamically depending on the location of the user. I saved the location as a cookie that I accessed through Request object. I had a valid Request inside the action method but it was null inside the constructor or at the class level properties of the controller.
I create a new System.Data.Objects.ObjectContext (my EF model) every time a DAL method is called:
Public void DoSomeDataManipulation()
{
using (MyModel myModel = new MyModel(connectionString))
myModel.AddRecord(someParametersHere);
}
DoSomeDataManipulation() is called frequently (also many other methods). I have tried a static version of myModel but EF produces many concurrency errors on high load.
Currently I'm curious if this approach can lead a Large Object Heap or not and if it is the best practice for calling mapped EF methods.
Using static context is a bad practice - you have found that it doesn't work in concurrent scenario (because context is not thread safe) but it also has other problems.
You should use a new instance of the context for each unit of work. Is adding single record unit of work (business operation / transaction)? In such case you are using it right. If your unit of work is adding multiple records or any other more complicated scenario where you insert / update / delete several entities you should use one context instance for the whole operation.
Using new context for the operation should not cause performance problems. Context internally uses some mapping description which is shared anyway. Problems with large heap can happen but that will not make any difference when using static context.
Large heap can happen due to memory leaks caused most often by POCO proxies (either tracking or lazy loading). If you load entity from the context and then dispose the context without detaching the entity it will still hold reference to the context and context will hold references to all attached entities = if the main entity is still referenced neither object context or anything it references can be garbage collected. In the same time detaching entity will break all relations because there is no "DetachGraph". You can detach entities one-by-one and EF will break navigation properties. I think this is a bug in Entity framework and dynamic proxies.
I'm putting a project together with Spring.NET and Caliburn v2. I have some objects that I'm trying to instantiate, but not sure how to go about it.
I have been using Caliburn's IoC aspect annotations (Singleton and PerRequest) to get objects into the Spring context. The problem with this is that I have two objects, A and B, where Object B is a subclass of Object A (meaning B is also an A). This means that if I register both, Spring complains of ambiguity when an object of type A is requested. To get around this, I could stop using Caliburn's IoC aspects to register the objects and instead register them in the Spring context XML files. That way I can specify a named object in the Spring context file to use in the constructor of object C, which needs an object of type B injected.
However, this creates a new problem. Object B needs the Caliburn window manager to be injected (which is not available to the Spring container at the time when the objects listed in the context XML files are instantiated, but only later, after Caliburn has loaded and added its own objects to the Spring container).
I could simply remove the inheritance and let some code duplication occur between objects A and B, but then what would be the point of doing OO programming? Otherwise I guess I'm looking for a way to specify objects in Spring.NET context XML, but keep them from being resolved until after Caliburn has loaded.
Any ideas?
I'm not familiar with Caliburn but if you want to delay instantiation then you could mark your objects in xml as lazy-init, like this:<object id="foo" type="..." lazy-init="true"/>
This way they will be instantiated when you first request them
I managed to solve this by maintaining a separate list of caliburn-dependent spring context XML files. I loaded these into the ApplicationContext object by adding the following code at the beginning of the overridden DisplayRootView() method in my application's bootstrapper:
var objectDefinitionReader = new XmlObjectDefinitionReader(applicationContext);
objectDefinitionReader.LoadObjectDefinitions(GetCaliburnDependentContextFiles());
applicationContext.Refresh();
I have using blocks in each method of my repository. If I want to cross reference methods, it seems it would be against best practices to initialize another Datacontext What am i doing wrong? If I declare a Datacontext in the class instead of using blocks in methods will I not lose power to dispose ??
public IList<something> GetSomething()
{
using (DB db=new DB())
{ ...GetListofSomethingElse(id)
}
}
public IList<somethingelse> GetListofSomethingElse(int id)
{
using (DB db=new DB())
{
... return IList
}
}
Actually, I think it is semantically (or how should I say that), not correct to create and dispose a datacontext in your repository.
I mean: if you open a new connection to the DB in each and every method of your repository, you're doing it wrong IMHO. This is too much fine grained.
The repository class has no knowledge of the 'context' in which it is being used. Your repository should not be responsible for opening / closing connections or starting and committing transactions.
Context is king, and the repository has no knowledge of the context in where it is being used. So, IMHO it is the responsability of the Application layer or service layer to open new DataContext objects, and closing / disposing them. (The same applies for transactions).
So, this is how I do it: (note that I do not use the Entity Framework, but I use NHibernate. I assume that the DataContext class in the EF is similar to the ISession in NHibernate):
using( ISession s = theSessionFactory.OpenSession() )
{
ICustomerRepository cr = RepositoryFactory.GetCustomerRepository(s);
Customer c1 = cr.GetCustomer(1);
Customer c2 = cr.GetCustomer(2);
// do some other stuff
s.StartTransaction();
cr.Save (c1);
cr.Save (c2);
s.Commit();
}
(This is not real world code offcourse; and it won't even compile since ISession doesn't have a Commit method. ;) Instead, the StartTransaction returns an ITransaction which has some kind of commit method, but I think you'll catch my drift. ;) )
If you don't use a using statement, you can still dispose explicitly. Even if you don't dispose of the data context though, cross-referencing these methods will still create a new data context. That may or may not be a good thing, depending on your usage. Think about the state management aspect of the data context, and whether you want to isolate the methods from each other or not. If you want to avoid creating a new context all the time, overload the methods with versions which take the context as a parameter.
Note that you don't usually need to dispose of a data context, although I tend to dispose of anything implementing IDisposable.
The using statement is syntactic sugar. It compiles to a try/finally block with the Dispose() call in the finally section. It ensures that Dispose will be called even if an exception occurs.
You can call .Dispose() on a class without using a 'using' statement - usually you'll do this in the Dispose method of your repository, if you've got one.