DbContextScope icon indicating copy to clipboard operation
DbContextScope copied to clipboard

IOC IDbContextScopeFactory and IAmbientDbContextLocator lifecycle

Open kimsagro1 opened this issue 10 years ago • 9 comments

What should the lifecycles of these two dependencies be when registering with a container. For example singleton, transient, one per web request etc.

kimsagro1 avatar Nov 04 '15 01:11 kimsagro1

I had the same question, how to registering IDbContextScope with autofac?

jrt324 avatar Jan 11 '16 04:01 jrt324

I too am wondering about this.

ghost avatar Mar 03 '16 19:03 ghost

We are also wondering what we need to register in Autofac to make this work. We "think" we need to register in Autofac:

  • IDbContextFactory and our own implementation for this
  • IDbContextScopeFactory and DbContextScopeFactory
  • IAmbientDbContextLocator and AmbientDbContextLocator

Also, we are using WCF, which is currently marking our transaction boundary (using autofachostfactory). How does this integrate with WCF and Autofac?

tomboon avatar Mar 04 '16 10:03 tomboon

Singleton makes sense

mitsbits avatar Mar 14 '16 00:03 mitsbits

Singleton probably doesn't make sense in AutoFac for web requests because I believe it would be shared across requests.

raysuelzer avatar Jun 14 '17 20:06 raysuelzer

Since you are using IoC I think you use whatever makes sense for whatever is consuming your service like Mehdi argues. If you are using MVC, have your web app configure the container for web requests. If you build a CLI for your service, you can create the context when your app starts and dispose of it after your command completes and the app exits.

What Mehdi is saying at the core of his article is the service needs to be the one in charge of the lifecycle of the DbContext so you can use transactions. But who's in charge of the life-cycle of the service? Whatever app is making use of the service. A web app is unique because it's technically running 24/7. If you take IoC out of the equation, it might help you think about this better. Just like when Mehdi say's he stopped calling his library a UnitOfWork things became more clear.

Consider if you had to choose manually on when you would new up your service.

VictorioBerra avatar Nov 01 '17 21:11 VictorioBerra

Singletons, from my perspective.

rock-walker avatar Dec 21 '17 21:12 rock-walker

It might be helpful to look into ASP.NET Core and how people are doing this over there. https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection DI is a first class citizen now. They might have the same issue as we are trying to solve here or they might not.

For what it's worth, there is nothing wrong with using a scoped lifetime. This library just makes it easy to let your services handle the transactions and also gives your repos easy access to the context without too much passing things around.

VictorioBerra avatar Dec 21 '17 22:12 VictorioBerra

Invert the dependency!

Always invert! Don't locate your dependencies, ask for them:

public class Example {
  public Func<IDbContext> DbContext { get; set; }
  Example(Func<IDbContext> dbContext)
  {
    DbContext = dbContext;
  }
}

Then you need a TransactionManager which will be responsible for creating scopes and threading the right DbContextScope dependency to Func<IDbContext>, like so:

// open a logical transaction
using (TransactionManager.OpenScope())
{
  DbContext().Save();
}

jzabroski avatar Oct 25 '18 01:10 jzabroski