1

I am using AutoFac and have a custom caching implementation. When I register type of the Cached implementation, I configured the caching service as as a SingleInstance(). However, this prompts issues with the database connection (using EF) because the second concurrent request tries to access a closed connection.

Builder.RegisterType<MyCachingDataService>().As<IMyCachingDataService>().SingelInstance();

Hence we removed the SingleInstance() and made it default instance per call, now the issue is that it kind of defeats the purpose of caching if we do an instance per call, that way it is less performant.

What is the way around this, what am I doing wrong.

Immortal
  • 1,233
  • 4
  • 20
  • 47
  • 1
    This has nothing to do with AutoFac. You should also have specified which version of EF you are using and posted some code – Mick Apr 01 '16 at 00:03
  • I updated the question just now, apparently I thought it was AutoFac because of the connection issue that I have and the singleton nature of my cached implementation object. – Immortal Apr 01 '16 at 00:07
  • 1
    You can replicate this problem without Autofac. Simply set your entities into a static member and try and reuse them, you'll encounter the same issue. If you attempt to use an unpopulated navigation property on an entity which was loaded with a context that has since been disposed, it will throw an exception. – Mick Apr 01 '16 at 00:14

2 Answers2

1

You should cache detached entities. This way they will not attempt to access the database. e.g.

context.MyEntities.AsNoTracking().Where(...).ToList();

See here for more details.

How do I detach objects in Entity Framework Code First?

This code will differ depending on which version of EF you are using.

Community
  • 1
  • 1
Mick
  • 6,527
  • 4
  • 52
  • 67
  • I think you misunderstood caching he asked. He asks general cache not cache on context. one service will ask some result and he will keep this data in memory(or redis vs) and will not go db for same ask let say for 10 mins. – Erkan Demirel Apr 01 '16 at 10:43
  • @ErkanDemirel it doesn't matter how EF entites are cached, whether it is in memory or using the HttpContext cache, unless you specifically detach the entities from the EF context, attempting to use a navigation property after the EF context has been disposed will result in an exception. – Mick Apr 04 '16 at 02:16
1

First of all dbcontext shouldn't be singleton. But if you have dbcontext in a singleton, it will be singleton also. Even you have not singleton db context.

You should use Factory to solve your problem. You can crate a factory for your own. Everytime you ask dbcontext, you will first ask the factory and it will return you dbcontext(related with lifetime of db context).

So your Cache and Factory will be singleton, but not dbcontext.

Autofac has auto generated factories.

You can use Dynamic Instantiation

But I suggest your cache shouldn't have dbcontext. Your services (or whatever) first asks cache, if the result is not there, they should ask db and get result and save it to cache. Cache shouldn't be responsible for db. Cache just should be responsible of saving result to memory by key and returning results from memory by key.

You can use Aspect-Oriented Programming to implement cache system by method. This is good for clean code. Check Postsharp

Erkan Demirel
  • 4,302
  • 1
  • 25
  • 43