8

I'm a little confused about which way is better and which one to use. Surely if you can always get HttpContext.GetOwinContext().Get(); then why even create a new ApplicationDbContext and risk doubling objects etc.?

Note: I'm specifically talking about a Web application here.

Fabis
  • 1,540
  • 2
  • 14
  • 30
  • See http://blogs.microsoft.co.il/gilf/2010/02/07/entity-framework-context-lifetime-best-practices/ – haim770 May 11 '15 at 08:40
  • So "use the context per request" means that at least in Web Applications I should always be using HttpContext.GetOwinContext().Get();? – Fabis May 11 '15 at 08:44
  • Generally, yes. Unless there's a good reason not to. – haim770 May 11 '15 at 08:45
  • Do you have an example of what would be a good reason not to? – Fabis May 11 '15 at 08:46
  • As far as I know, you shouldn't be using the same instance of DbContext that you're using for Identity Framework within your application. It is purely for use by Identity Framework... you should be generating a DbContext by other means outside of your Identity Framework methods (IE. Injecting it in using your IoC Container). – Luke May 11 '15 at 08:49
  • Also, although you *can* get a reference to the context using the above approach, a better way would be to *inject* the context instance instead of requesting it in a 'Service Locator' mode. Internally, your IoC container would return the same instance for the same request. See http://stackoverflow.com/a/5191797 – haim770 May 11 '15 at 08:49

2 Answers2

3

The DbContext instance that you create and can be retrieved using HttpContext.GetOwinContext().Get<ApplicationDbContext>(); within your MVC application can be left exclusively for the use of Identity Framework.

If you need an instance of your DbContext for general use within your application, you can make use of an IoC Container (dependency injection) to provide you with a fresh instance of it as an when required and in request scope if desired.

You shouldn't need to retrieve the identity framework instance of the DbContext for the use within your application, it will be managed independently of your application and you can manage your own lifecycle.

Because you wired these up within the Owin Startup class to use an instance of your DbContext, they will make use of it under the hood and will create and destroy instances as and when it is required.

Luke
  • 19,970
  • 26
  • 98
  • 180
  • but sometimes i need to create a user and insert his ID into some tables in one transaction, otherwise i lose data integrity. What to do? – Toolkit Feb 15 '16 at 18:33
  • why Request.GetOwinContext().Get(); even exists then? – Toolkit Feb 15 '16 at 18:33
  • If you need to do something special during the login process, you should create a custom implementation of IUserStore and attach it to your identity setup. As for using the DbContext that identity uses, you should be creating and managing the life cycle of your DbContext yourself as with any application, this way it's creation and destruction is predictable. You don't want the identity DbContext to be disposed before you need to use it. I hope this helps. – Luke Feb 15 '16 at 18:40
  • are you sure?? "The solution is to store a single instance of UserManager and DbContext per request and reuse them throughout the application. Since Identity hooks into the OWIN pipeline via cookie middleware, we can store the UserManager and DbContext in the OWIN context object and retrieve them as needed." – Toolkit Feb 15 '16 at 19:05
  • and "Also in the application if we need to work with the DbContext object directly we can get the instance of the class from the OWIN context as mentioned earlier using the ‘Get’ method" https://blogs.msdn.microsoft.com/webdev/2014/02/12/per-request-lifetime-management-for-usermanager-class-in-asp-net-identity/ – Toolkit Feb 15 '16 at 19:05
  • What did you end up doing in the end? – Luke Sep 14 '17 at 11:35
  • var db = HttpContext.Current.Request.GetOwinContext().Get(); – Toolkit Sep 14 '17 at 14:19
  • Cool. Is that how you resolve it in your IoC container? – Luke Sep 14 '17 at 19:46
  • Downvoters - Please read [this thread](https://stackoverflow.com/a/35616444/894792) for more discussion about this. It isn't *wrong* to have one per request, nor is it *wrong* to create your DbContext per logical piece of work during the request, both are acceptable. This answer enables both. Having control over your own DbContext instances isn't a bad thing. Maybe I went in a bit strong saying _the DbContext is just for identity framework_... updated. Enjoy. – Luke Aug 17 '18 at 12:47
1

The solution is to store a single instance of UserManager and DbContext per request and reuse them throughout the application. Since Identity hooks into the OWIN pipeline via cookie middleware, we can store the UserManager and DbContext in the OWIN context object and retrieve them as needed

Also in the application if we need to work with the DbContext object directly we can get the instance of the class from the OWIN context as mentioned earlier using the ‘Get’ method

var dbContext = context.Get<ApplicationDbContext>();

From https://blogs.msdn.microsoft.com/webdev/2014/02/12/per-request-lifetime-management-for-usermanager-class-in-asp-net-identity/

Community
  • 1
  • 1
Toolkit
  • 9,302
  • 7
  • 50
  • 63
  • I think I'd rather stick to having them separated out. DbContext is a [lightweight object](https://softwareengineering.stackexchange.com/a/359672/114058) after all. It's not __wrong__ to have more than one created in a single request. Two DbContexts used one after another in a request isn't a big deal. It also means that you can allow your IoC container to intelligently create/destroy it per request. – Luke Aug 17 '18 at 12:34