I am building an ASP.NET 4.0 MVC 2 app with a generic repository based on this blog post.
I'm not sure how to deal with the lifetime of ObjectContext -- here is a typical method from my repository class:
public T GetSingle<T>(Func<T, bool> predicate) where T : class
{
using (MyDbEntities dbEntities = new MyDbEntities())
{
return dbEntities.CreateObjectSet<T>().Single(predicate);
}
}
MyDbEntities is the ObjectContext generated by Entity Framework 4.
Is it ok to call .CreateObjectSet() and create/dispose MyDbEntities per every HTTP request? If not, how can I preserve this object?
If another method returns an IEnumerable<MyObject> using similar code, will this cause undefined behavior if I try to perform CRUD operations outside the scope of that method?
Yes, it is ok to create a new object context on each request (and in turn a call to CreateObjectSet). In fact, it's preferred. And like any object that implements IDisposable, you should be a good citizen and dispose it (which you're code above is doing). Some people use IoC to control the lifetime of their object context scoped to the http request but either way, it's short lived.
For the second part of your question, I think you're asking if another method performs a CRUD operation with a different instance of the data context (let me know if I'm misinterpreting). If that's the case, you'll need to attach it to the new data context that will perform the actual database update. This is a fine thing to do. Also, acceptable would be the use the Unit of Work pattern as well.
Related
I've decided to architect my solution without repositories and unit of work (given that EF is itself a repository/uow so why abstract an abstraction). So I have a Service/Business Logic layer which will call EF directly. My service has a number of methods (Create, Update, Delete) which call _context.SaveChanges() and I am injecting the DbContext in the constructor.
However if I call multiple methods using the same service instance and one fails, all further service methods will also fail. For example
var svc = new PersonService();
var person = new Person{ Name = "Angie" };
svc.Create(person);
svc.Delete(56); //delete person with Id 50
Lets assume Create throws an exception on SaveChanges for some reason. When I call Delete, there is still a faulty Person object in my context, so when Delete method calls SaveChanges it will throw the same exception.
Of course I can get around this by always instantiating a new PersonService in my calling code but this just screams WRONG.
This leads me to using a new context for each service method, which will mean method injection instead of constructor injection which I was hoping to avoid.
I've considered going back to repository/uow but it seems that this just moves the problem one layer deeper.
Is method injection of my context the right way to go or am I missing something here?
Thanks
Apologies, in advance, if this seems like a duplicate question. This question was the closest I could find, but it doesn't really solve the issues I am facing.
I'm using Entity Framework 5 in an ASP.NET MVC4 application and attempting to implement the Unit of Work pattern.
My unit of work class implements IDisposable and contains a single instance of my DbContext-derived object context class, as well as a number of repositories, each of which derives from a generic base repository class that exposes all the usual repository functionality.
For each HTTP request, Ninject creates a single instance of the Unit of Work class and injects it into the controllers, automatically disposing it when the request is complete.
Since EF5 abstracts away the data storage and Ninject manages the lifetime of the object context, it seems like the perfect way for consuming code to access in-memory entity objects without the need to explcitly manage their persistence. In other words, for optimum separation of concerns, I envisage my controller action methods being able to use and modify repository data without the need to explicitly call SaveChanges afterwards.
My first (naiive) attempt to implement this idea employed a call to SaveChanges within every repository base-class method that modified data. Of course, I soon realized that this is neither performance optimized (especially when making multiple successive calls to the same method), nor does it accommodate situations where an action method directly modifies a property of an object retrieved from a repository.
So, I evolved my design to eliminate these premature calls to SaveChanges and replace them with a single call when the Unit of Work instance is disposed. This seemed like the cleanest implementation of the Unit of Work pattern in MVC, since a unit of work is naturally scoped to a request.
Unfortunately, after building this concept, I discovered its fatal flaw - the fact that objects added to or deleted from a DbContext are not reflected, even locally, until SaveChanges has been called.
So, what are your thoughts on the idea that consuming code should be able to use objects without explicitly persisting them? And, if this idea seems valid, what's the best way to achieve it with EF5?
Many thanks for your suggestions,
Tim
UPDATE: Based on #Wahid's response, I am adding below some test code that shows some of the situations in which it becomes essential for the consuming code to explicitly call SaveChanges:
var unitOfWork = _kernel.Get<IUnitOfWork>();
var terms = unitOfWork.Terms.Entities;
// Purge the table so as to start with a known state
foreach (var term in terms)
{
terms.Remove(term);
}
unitOfWork.SaveChanges();
Assert.AreEqual(0, terms.Count());
// Verify that additions are not even reflected locally until committed.
var created = new Term { Pattern = "Test" };
terms.Add(created);
Assert.AreEqual(0, terms.Count());
// Verify that additions are reflected locally once committed.
unitOfWork.SaveChanges();
Assert.AreEqual(1, terms.Count());
// Verify that property modifications to entities are reflected locally immediately
created.Pattern = "Test2";
var another = terms.Single(term => term.Id == created.Id);
Assert.AreEqual("Test2", another.Pattern);
Assert.True(ReferenceEquals(created, another));
// Verify that queries against property changes fail until committed
Assert.IsNull(terms.FirstOrDefault(term => term.Pattern == "Test2"));
// Verify that queries against property changes work once committed
unitOfWork.SaveChanges();
Assert.NotNull(terms.FirstOrDefault(term => term.Pattern == "Test2"));
// Verify that deletions are not even reflected locally until committed.
terms.Remove(created);
Assert.AreEqual(1, terms.Count());
// Verify that additions are reflected locally once committed.
unitOfWork.SaveChanges();
Assert.AreEqual(0, terms.Count());
First of all SaveChanges should NOT be ever in the repositories at all. Because that's leads you to lose the benefit of UnitOfWork.
Second you need to make a special method to save changes in the UnitOfWork.
And if you want to call this method automatically then you may fine some other solution like ActionFilter or maybe by making all your Controllers inherits from BaseController class and handle the SaveChanges in it.
Anyway the UnitOfWork should always have SaveChanges method.
Ive just started using EF4 with the repository pattern. Im having to call the dispose method after every use of context or wrap code arround in the using block. Can I use the ObjectContext without doing this in every method I write or is there a better way of handling this in the repository.
Also I dont want to pass the ObjectContext to the repository from the UI as well.
To do this as resource effectively as possible without dependency injection, I would suggest that you implement a private, lazy-loading property for the object context.
private ObjectContext _context;
private ObjectContext Context
{ get
{
return _context ?? (_context = new ObjectContext());
}
}
Next, make your repository implement IDisposable and take care of the object context in your dispose method:
public Repository : IDisposable
{
...
public void Dispose()
{
_context.Dispose();
}
}
Then, you just use the property in all your methods, and wrap usage of your repository in using statements.
To decrease traffic to the database, you could also factor out the saving to a separate method on the repository, which just forwards the call to the object context. That way you get more control of when data is saved in the UI layer, even though you don't control how. That means you could do
using (var repo = new Repository())
{
repo.AddSomeStuff("this", "is", true);
repo.ChangeSomethingElse("yes, please");
repo.Save();
}
and there would only be one call from EF to the database. On the other hand, if you do
using (var repo = new Repository())
{
repo.AddSomeStuff("this", "is", true);
repo.ChangeSomethingElse("yes, please");
}
nothing happens, which might be confusing.
The general pattern for using an object context is:
public BusinessObject GetSomething(){
using (MyObjectContext context = new MyObjectContext()){
//..do fun stuff
}
}
Which hopefully is the pattern you are using. Calling dispose seems a little overkill when you can just use a "using" statement.
Another option is if you are going to be doing multiple DB queries in a flow. I have seen a pattern where you can reuse the same context within the thread. People basically implement a Thread based singleton pattern and pass around the context. Advantages to this is not having to rebuild the context, as well as some in memory caching. Downside is you could run into concurrency issues. Someone updating something that you have cached internally in EF.
I am guessing the second case doesn't really apply because it sounds like you are writting a small app. (that statement was based on your comments about passing a context from UI...a statement which will scare any good code architect).
If you are interested in a thread based singleton. First learn about the Singleton pattern, and then check out this blog about "DataContext" threads. You will have to change the "DataContext" type to the ObjectContext class but it would work.
EDIT
I will say I overlooked an obvious solution and that would be the below ;). Just using a property based Object Context and playing your repository in a using statement. It would be the same as the using example above, but you would implement IDisoposable.
I'm a total newbie at Entity Framework and ASP.Net MVC, having learned mostly from tutorials, without having a deep understanding of either. (I do have experience on .Net 2.0, ADO.Net and WebForms)
My current doubt comes from the way I'm instancing my Entities objects.
Basically I'm doing this in my controllers:
public class PostsController : Controller {
private NorthWindEntities db = new NorthWindEntities();
public ActionResult Index() {
// Use the db object here, never explicitly Close/Dispose it
}
}
I'm doing it like this because I found it in some MSDN blog that seemed authoritative enough to me that I assumed this was a correct way.
However, I feel pretty un-easy about this. Although it saves me a lot of code, I'm used to doing:
using (NorthWindEntities db = new NorthWindEntities() {
}
In every single method that needs a connection, and if that method calls others that'll need it, it'll pass db as a parameter to them. This is how I did everything with my connection objects before Linq-to-SQL existed.
The other thing that makes me uneasy is that NorthWindEntities implements IDisposable, which by convention means I should be calling it's Dispose() method, and I'm not.
What do you think about this?
Is it correct to instance the Entities object as I'm doing? Should it take care of its connections by opening and closing them for each query?
Or should I be disposing it explicitly with a using() clause?
Thanks!
Controller itself implements IDisposable. So you can override Dispose and dispose of anything (like an object context) that you initialize when the controller is instantiated.
The controller only lives as long as a single request. So having a using inside an action and having one object context for the whole controller is exactly the same number of contexts: 1.
The big difference between these two methods is that the action will have completed before the view has rendered. So if you create your ObjectContext in a using statement inside the action, the ObjectContext will have been disposed before the view has rendered. So you better have read anything from the context that you need before the action completes. If the model you pass to the view is some lazy list like an IQueryable, you will have disposed the context before the view is rendered, causing an exception when the view tries to enumerate the IQueryable.
By contrast, if you initialize the ObjectContext when the Controller is initialized (or write lazy initialization code causing it to be initialized when the action is run) and dispose of the ObjectContext in the Controller.Dispose, then the context will still be around when the view is rendered. In this case, it is safe to pass an IQueryable to the view. The Controller will be disposed shortly after the view is rendered.
Finally, I'd be remiss if I didn't point out that it's probably a bad idea to have your Controller be aware of the Entity Framework at all. Look into using a separate assembly for your model and the repository pattern to have the controller talk to the model. A Google search will turn up quite a bit on this.
You are making a good point here. How long should the ObjectContext live? All patterns and practises books (like Dino Esposito's Microsoft-NET-Architecting-Applications) tell you that a DataContext must not live long, nor should it be cached.
I was just wondering why not having, in your case, a ControllerBase class (I'm not aware of the MVC implementation, so bear with me) where the ObjectContext gets initiated once for all controller. Especially think about the Identity Map Pattern, that's already implemented by Entity Framework. Even though you need to call another controller as your PostsController, it would still work with the same Context and improve performance as well.
I have a question, and I'm going to tag this subjective since that's what I think it evolves into, more of a discussion. I'm hoping for some good ideas or some thought-provokers. I apologize for the long-winded question but you need to know the context.
The question is basically:
How do you deal with concrete types in relation to IoC containers? Specifically, who is responsible for disposing them, if they require disposal, and how does that knowledge get propagated out to the calling code?
Do you require them to be IDisposable? If not, is that code future-proof, or is the rule that you cannot use disposable objects? If you enforce IDisposable-requirements on interfaces and concrete types to be future-proof, whose responsibility is objects injected as part of constructor calls?
Edit: I accepted the answer by #Chris Ballard since it's the closest one to the approach we ended up with.
Basically, we always return a type that looks like this:
public interface IService<T> : IDisposable
where T: class
{
T Instance { get; }
Boolean Success { get; }
String FailureMessage { get; } // in case Success=false
}
We then return an object implementing this interface back from both .Resolve and .TryResolve, so that what we get in the calling code is always the same type.
Now, the object implementing this interface, IService<T> is IDisposable, and should always be disposed of. It's not up to the programmer that resolves a service to decide whether the IService<T> object should be disposed or not.
However, and this is the crucial part, whether the service instance should be disposed or not, that knowledge is baked into the object implementing IService<T>, so if it's a factory-scoped service (ie. each call to Resolve ends up with a new service instance), then the service instance will be disposed when the IService<T> object is disposed.
This also made it possible to support other special scopes, like pooling. We can now say that we want minimum 2 service instances, maximum 15, and typically 5, which means that each call to .Resolve will either retrieve a service instance from a pool of available objects, or construct a new one. And then, when the IService<T> object that holds the pooled service is disposed of, the service instance is released back into its pool.
Sure, this made all code look like this:
using (var service = ServiceContainer.Global.Resolve<ISomeService>())
{
service.Instance.DoSomething();
}
but it's a clean approach, and it has the same syntax regardless of the type of service or concrete object in use, so we chose that as an acceptable solution.
Original question follows, for posterity
Long-winded question comes here:
We have a IoC container that we use, and recently we discovered what amounts to a problem.
In non-IoC code, when we wanted to use, say, a file, we used a class like this:
using (Stream stream = new FileStream(...))
{
...
}
There was no question as to whether this class was something that held a limited resource or not, since we knew that files had to be closed, and the class itself implemented IDisposable. The rule is simply that every class we construct an object of, that implements IDisposable, has to be disposed of. No questions asked. It's not up to the user of this class to decide if calling Dispose is optional or not.
Ok, so on to the first step towards the IoC container. Let's assume we don't want the code to talk directly to the file, but instead go through one layer of indirection. Let's call this class a BinaryDataProvider for this example. Internally, the class is using a stream, which is still a disposable object, so the above code would be changed to:
using (BinaryDataProvider provider = new BinaryDataProvider(...))
{
...
}
This doesn't change much. The knowledge that the class implements IDisposable is still here, no questions asked, we need to call Dispose.
But, let's assume that we have classes that provide data that right now doesn't use any such limited resources.
The above code could then be written as:
BinaryDataProvider provider = new BinaryDataProvider();
...
OK, so far so good, but here comes the meat of the question. Let's assume we want to use an IoC container to inject this provider instead of depending on a specific concrete type.
The code would then be:
IBinaryDataProvider provider =
ServiceContainer.Global.Resolve<IBinaryDataProvider>();
...
Note that I assume there is an independent interface available that we can access the object through.
With the above change, what if we later on want to use an object that really should be disposed of? None of the existing code that resolves that interface is written to dispose of the object, so what now?
The way we see it, we have to pick one solution:
Implement runtime checking that checks that if a concrete type that is being registered implements IDisposable, require that the interface it is exposed through also implements IDisposable. This is not a good solution
Enfore a constraint on the interfaces being used, they must always inherit from IDisposable, in order to be future-proof
Enforce runtime that no concrete types can be IDisposable, since this is specifically not handled by the code using the IoC container
Just leave it up to the programmer to check if the object implements IDisposable and "do the right thing"?
Are there others?
Also, what about injecting objects in constructors? Our container, and some of the other containers we've looked into, is capable of injecting a fresh object into a parameter to a constructor of a concrete type. For instance, if our BinaryDataProvider need an object that implements the ILogging interface, if we enforce IDispose-"ability" on these objects, whose responsibility is it to dispose of the logging object?
What do you think? I want opinions, good and bad.
One option might be to go with a factory pattern, so that the objects created directly by the IoC container never need to be disposed themselves, eg
IBinaryDataProviderFactory factory =
ServiceContainer.Global.Resolve<IBinaryDataProviderFactory>();
using(IBinaryDataProvider provider = factory.CreateProvider())
{
...
}
Downside is added complexity, but it does mean that the container never creates anything which the developer is supposed to dispose of - it is always explicit code which does this.
If you really want to make it obvious, the factory method could be named something like CreateDisposableProvider().
(Disclaimer: I'm answering this based on java stuff. Although I program C# I haven't proxied anything in C# but I know it's possible. Sorry about the java terminology)
You could let the IoC framework inspect the object being constructed to see if it supports
IDisposable. If not, you could use a dynamic proxy to wrap the actual object that the IoC framework provides to the client code. This dynamic proxy could implement IDisposable, so that you'd always deliver a IDisposable to the client. As long as you're working with interfaces that should be fairly simple ?
Then you'd just have the problem of communicating to the developer when the object is an IDisposable. I'm not really sure how this'd be done in a nice manner.
You actually came up with a very dirty solution: your IService contract violates the SRP, wich is a big no-no.
What I recommend is to distinguish so-called "singleton" services from so-called "prototype" services. Lifetime of "singleton" ones is managed by the container, which may query at runtime whether a particular instance implements IDisposable and invoke Dispose() on shutdown if so.
Managing prototypes, on the other hand, is totally the responsibility of the calling code.