Ok, I give up...
What I want is to share the EF4's DbContext instance per request. I configured StructureMap like this:
For<MyContext>().Use(new MyContext("LocalhostConnString"));
But when I refresh my site, or even open it in another browser, I get the same exact instance of MyContext. Why is this shared across requests?
Am I missing something?
Yes... about 4 characters. Try:
For<MyContext>().Use(() => new MyContext("LocalhostConnString"));
If you give StructureMap an object instance, it will treat that instance as a singleton and return the same one every time. If instead you give it a lambda that creates an instance, it will run that lambda each time the type is requested.
Related
How DbMigrator works
I have code that instantiates a new DbMigrator(new Configuration())
Configuration is a custom extension of DbMigrationsConfiguration<T>, where T is DbContext
So within Configuration, there is a ContextType, which is equal to <T>.
When DbMigrator is instantiated, it attempts to create an instance of the <T> DbContext. It will either try to use an Empty Constructor on the <T> Context, or it will attempt to look for an implementation of IDbContextFactory<...> where ... is the actual type of , but not generic T.
How DbMigrator Doesn't Work
The problem is, the assembly instantiating DbMigrator has no access to the specific typed IDbContextFactory<...> that it needs to discover. Also, my DbContext has no default constructor, and I don't want it to. So I receive the exception The target context '...' is not constructible.
The thing that bothers me is, at the point I am instantiating DbMigrator, I already have an instance (or may already be within an instance) of the DbContext I am migrating. Also, I have access to a generic IDbContextFactory<T> that is not discoverable by DbMigrator's internals, but I'd be happy to provide it an instance.
The Question
So how do I tell DbMigrator to either just use my Context instance, or use an instance of a IDbContextFactory I specify? When it relies on its magic juju behind the scenes to try to discover these things (presumably using reflection/ServiceLocation) it is failing.
My Situation
Within one AppDomain, I am using n Contexts. I'd like to say one, but it's typically two, and may be more than that. So any solution that relies on a single app/web config property, or an attribute decorator, which points to a single DbConfiguration or ConnectionFactory won't work for me. Because there can only be one per AppDomain and, unless I could configure it based contextually on which Context I'm needing at the time, it is futile. So there's wiggle room there, but I dunno.
Also, there may be some juju I don't understand about EF relating to the base constructor. But I don't believe passing a DbConnection into the constructor instead of a nameOrConnectionString would work. It is still not an empty constructor. But if there's something EF does to search for constructors with that, and how to utilize it, that MIGHT work.
In an application I have the following components (among others):
MyDbContext : Entity framework data access
DBResourceProviderFactory : A custom ResourceProviderFactory providing a custom IResourceProvider (called DBResourceProvider...)
Other services
StructureMap
The custom resource provider is looking resources up in the db using MyDbContext, injected similarly as described in this SO answer.
The MyDbContext is also used in various other services, and since it is a web application, I use StructureMaps HttpContextScoped method to limit the lifetime of MyDbContext to the lifetime of the request (see an other SO question and its answer on this subject):
x.For<MyDbContext>().HttpContextScoped();
However, it seems that the lifetime of an IResourceProvider is not limited to a single http request. Therefore, DBResourceProvider keeps hanging onto a MyDbContext reference which will be disposed after the first request.
How can I handle this lifetime mismatch - have StructureMap return a transient MyDbContext for IDbResourceProvider while returning HttpContext-scoped instances to all other services?
Do I need two different implementations to do that? A marker interface?
Or is it a bad idea to use Entity Framework to look up localized resources in the first place (performance etc.)?
If you have a service that has (or needs to have) a long lifetime than (one of) its dependencies, the general solution is to use a factory to get those dependencies.
In your situation the solution might be simple. When your DBResourceProvider is defined in your composition root of your MVC application, it would simply succeed to use the DependencyResolver.Current.GetService method to get the MyDbContext.
When the DBResourceProvider service isn't part of the composition root (for instance because it contains business logic that you need to test), you could either extract that logic into its own class, to allow the service to be in the composition root, or you can inject a (singleton) factory (for instance IDbContextFactory or Func<MyDbContext>) that allows you to get the proper instance to be resolved.
Suppose I register some instance in OpenRasta's dependency resolver using
resolver.AddDependencyInstance(IInterface, instance, DependencyLifetime.Singleton)
Now if I want to swap that instance later, say to reread fresh data from the db, is another call to resolver.AddDependencyInstance the right thing to do?
Checking the InternalDependencyResolver implementation, it seems to be fine. However I'm asking because the behavior is not defined (in openrasta's sources, where I checked), and the method prefix "Add" is suggestive of different behavior.
I wouldn't use Singleton if you have to swap the instance at some point.
Use DependencyLifetime.Transient and have a constructor injection in the class where you need the new instance
I have an application using the Entity Framework code first. My setup is that I have a core service which all other services inherit from. The core service contains the following code:
public static DatabaseContext db = new DatabaseContext();
public CoreService()
{
db.Database.Initialize(force: false);
}
Then, another class will inherit from CoreService and when it needs to query the database will just run some code such as:
db.Products.Where(blah => blah.IsEnabled);
However, I seem to be getting conflicting stories as to which is best.
Some people advise NOT to do what I'm doing.
Other people say that you should define the context for each class (rather than use a base class to instantiate it)
Others say that for EVERY database call, I should wrap it in a using block. I've never seen this in any of the examples from Microsoft.
Can anyone clarify?
I'm currently at a point where refactoring is possible and quite quick, so I'd like some general advice if possible.
You should wrap one context per web request. Hold it open for as long as you need it, then get rid of it when you are finished. That's what the using is for.
Do NOT wrap up your context in a Singleton. That is not a good idea.
If you are working with clients like WinForms then I think you would wrap the context around each form but that's not my area.
Also, make sure you know when you are going to be actually executing against your datasource so you don't end up enumerating multiple times when you might only need to do so once to work with the results.
Lastly, you have seen this practice from MS as lots of the ADO stuff supports being wrapped in a using but hardly anyone realises this.
I suggest to use design principle "prefer composition over inheritance".
You can have the reference of the database context in your base class.
Implement a singleton for getting the DataContext and assign the datacontext to this reference.
The conflicts you get are not related to sharing the context between classes but are caused by the static declaration of your context. If you make the context an instance field of your service class, so that every service instance gets its own context, there should be no issues.
The using pattern you mention is not required but instead you should make sure that context.Dispose() is called at the service disposal.
Greetings,
Trying to sort through the best way to provide access to my Entity Manager while keeping the context open through the request to permit late loading. I am seeing a lot of examples like the following:
public class SomeController
{
MyEntities entities = new MyEntities();
}
The problem I see with this setup is that if you have a layer of business classes that you want to make calls into, you end up having to pass the manager as a parameter to these methods, like so:
public static GetEntity(MyEntities entityManager, int id)
{
return entityManager.Series.FirstOrDefault(s => s.SeriesId == id);
}
Obviously I am looking for a good, thread safe way, to provide the entityManager to the method without passing it. The way also needs to be unit testable, my previous attempts with putting it in Session did not work for unit tests.
I am actually looking for the recommended way of dealing with the Entity Framework in ASP .NET MVC for an enterprise level application.
Thanks in advance
Entity Framework v1.0 excels in Windows Forms applications where you can use the object context for as long as you like. In asp.net and mvc in particular it's a bit harder. My solution to this was to make the repositories or entity managers more like services that MVC could communicate with. I created a sort of generic all purpose base repository I could use whenever I felt like it and just stopped bothering too much about doing it right. I would try to avoid leaving the object context open for even a ms longer than is absolutely needed in a web application.
Have a look at EF4. I started using EF in production environment when that was in beta 0.75 or something similar and had no real issues with it except for it being "hard work" sometimes.
You might want to look at the Repository pattern (here's a write up of Repository with Linq to SQL).
The basic idea would be that instead of creating a static class, you instantiate a version of the Repository. You can pass in your EntityManager as a parameter to the class in the constructor -- or better yet, a factory that can create your EntityManager for the class so that it can do unit of work instantiation of the manager.
For MVC I use a base controller class. In this class you could create your entity manager factory and make it a property of the class so deriving classes have access to it. Allow it to be injected from a constructor but created with the proper default if the instance passed in is null. Whenever a controller method needs to create a repository, it can use this instance to pass into the Repository so that it can create the manager required.
In this way, you get rid of the static methods and allow mock instances to be used in your unit tests. By passing in a factory -- which ought to create instances that implement interfaces, btw -- you decouple your repository from the actual manager class.
Don't lazy load entities in the view. Don't make business layer calls in the view. Load all the entities the view will need up front in the controller, compute all the sums and averages the view will need up front in the controller, etc. After all, that's what the controller is for.