alastairtree / LazyCache

An easy to use thread safe in-memory caching service with a simple developer friendly API for c#
https://nuget.org/packages/LazyCache
MIT License
1.72k stars 159 forks source link

LazyCache changes cached instance when changing retrieved instance #43

Closed Blackclaws closed 4 years ago

Blackclaws commented 6 years ago

LazyCache persists changes to reference objects into the cache.

This, if not avoidable (very unlikely as objects would have to be copyable which is not a given), should at least be documented somewhere as a potential caveat.

Find an example application below:

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LazyCache;

namespace LazyCacheTest
{
    class ExampleClass
    {
        public string Prop { get; set; } = "Not set";
    }

    class Program
    {
        static void Main(string[] args)
        {
            IAppCache cache = new CachingService();

            var CacheResult = cache.GetOrAdd("StringOne", () => new ExampleClass());

            Console.WriteLine(CacheResult.Prop);
            CacheResult.Prop = "Changed";
            Console.WriteLine(CacheResult.Prop);

            CacheResult = cache.GetOrAdd("StringOne", () => new ExampleClass());

            Console.WriteLine(CacheResult.Prop);

            Console.WriteLine("Exiting");
        }
    }
}

Expected result:

"Not Set" "Changed" "Not Set" "Exiting"

Result:

"Not Set" "Changed" "Changes" "Exiting"

alastairtree commented 6 years ago

This is what happens with any in-memory based caching - you are caching the actual reference to the object in-memory, the object does not get serialised or persisted anywhere magically - that is why it is usually the fasted type of cache. To avoid you would need to do some form of object cloning before you cached it. In your example the second instance is never used, because the first instance is in the cache. Would some improved documentation help?

smblee commented 5 years ago

@alastairtree

Hi, i just ran into this issue and was able to figure out after an hour of debugging. It would be very useful to have it documented :)

alastairtree commented 4 years ago

Added a new Troubleshooting docs page to cover this scenario. Thanks for getting in touch.