0

I want to use EF Second Level Cache and change the default cache provider of EF in an ASP.NET MVC project to use Redis instead of its InMemory cache provider.

I have the following sample code for MVC Core:

// Add Redis cache service provider
var jss = new JsonSerializerSettings
{
    NullValueHandling = NullValueHandling.Ignore,
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};

const string redisConfigurationKey = "redis";
services.AddSingleton(typeof(ICacheManagerConfiguration),
    new CacheManager.Core.ConfigurationBuilder()
        .WithJsonSerializer(serializationSettings: jss, deserializationSettings: jss)
        .WithUpdateMode(CacheUpdateMode.Up)
        .WithRedisConfiguration(redisConfigurationKey, config =>
        {
            config.WithAllowAdmin()
                .WithDatabase(0)
                .WithEndpoint("localhost", 6379);
        })
        .WithMaxRetries(100)
        .WithRetryTimeout(50)
        .WithRedisCacheHandle(redisConfigurationKey)
        .WithExpiration(ExpirationMode.Absolute, TimeSpan.FromMinutes(10))
        .Build());
services.AddSingleton(typeof(ICacheManager<>), typeof(BaseCacheManager<>));

My project is not MVC Core, it is MVC. Also I use StructureMaps as IOC.

Now I have 2 question:

  1. How should I configure EF in my project to use Redis as its Second Level Cache Provider (I'm using this package)?
  2. Can I use the saved data in the cache (Redis) in this way in a separate project on my computer (Sharing cache of an MVC application between several application)?

1 Answer 1

1

Redis in StructureMap

There is a fair amount of code in StructureMap to get that service registered. Singletons are a little different in that system, and you are better off using a "factory" pattern to create and manage your redis cache. SM has an auto-factory that will do the trick.

If you'd like, I can post some basic code here. But - you'd need to test in your environment to get it to work (I'm not a fan of posting theoretical code here on stack).

If you haven't used redis before, I'd create a console app and make sure that you can configure it and get it to run before inserting IOC and your .Net MVC app into the picture (you're a strong coder, so I'm not tell you something you don't already know there).

Can your other apps use the Redis cache?

Yes. As long as they have access to the endpoint you create (in the code above, it's listening on localhost:6379).

You can just use the same "config" setup that you use in your MVC app. When you do, both apps will hit the same redis "server" and share the same cached objects.

Think of redis the same way you think of your database: as long as both systems use the same "config" (eg - connect string), then they can access the same data.

redis is super-fast and really cool. You're gonna love it!

Totally Untested Sample Code

Here's a quick overview just so my comment on code structure make more sense. If others have suggestions on adjustments, feel free to add to comments and I'll update.

public interface ICacheManagerConfigFactory {
    ICacheManagerConfiguration CreateCacheManager();
}

public CacheManagerFactory:ICacheManagerConfigFactory {

    private static ICacheManagerConfiguration _cache;
    private static object syncRoot = new Object();
    
    public ICacheManagerConfiguration CreateCacheManager() {

        if(_cache!=null) { return _cache; } 
        //locking to make sure that we only create 1 _cache object (thread-safe)
        lock(syncRoot) {
            //idiot-proofing our thread-safe code
            if(_cache!=null) { return _cache; } 
            //create _cache if it doesn't already exist
            var jss = new JsonSerializerSettings {
                NullValueHandling = NullValueHandling.Ignore,
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            };  
            _cache= new CacheManager.Core.ConfigurationBuilder()
               .WithJsonSerializer(serializationSettings: jss, deserializationSettings: jss)
               ... etc ...
               .Build();
        }
        return _cache;
    }
}

And, this is just a quick test method which proves we can pull the static config from memory. It's also pulled from SM's documentation for auto-factory.

public void Simple_factory_creation() {
    var container = new Container(cfg => {
        cfg.For<ICacheManagerConfiguration>().Use<CacheManagerFactory>();
        cfg.For<ICacheManagerConfigFactory>().CreateFactory();
    });

    var cache = container.GetInstance<ICacheManagerConfiguration>();

}   
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you bri, I forget to say about EF in my question (I updated it) but I want to Change EF Cache provider to use Redis. Really I want use Second Level Cache for EF by Redis. I configured StructureMap for ICacheManagerConfiguration without Factory method (directly in IOC configs) but EF cache dose not store in Redis yet. It seems it is not enough. Maybe I should implement a custom class for DbConfiguration to force The EF CachingProvider to use Redis.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.