I've been experiencing some strange code-issues, and finally seem to have noticed that what as supposed to be acting as Singleton, is not actually a singleton. This is a cache-class, so I am ending up having multiple-versions of the same cache. I've written some test-code as per below, and in my eyes this should work. Am I doing anything wrong, or have I stumbled upon a bug?
public class GenericClassesNotRegisteredAsSingletonTest
{
public interface ICacheManager<T> { }
public class SettingsData { }
public class SettingsCache : CacheManager<SettingsData> { }
public class CacheManager<T> : ICacheManager<T> { }
[Test]
public void Test()
{
var container = new Container();
var registration = Lifestyle.Singleton
.CreateRegistration(typeof(SettingsCache),
typeof(SettingsCache), container);
container.AddRegistration(
typeof(ICacheManager<SettingsData>), registration);
container.Verify();
var cache1 = container.GetInstance<SettingsCache>();
var cache2 = container.GetInstance<SettingsCache>();
bool sameRef = cache1 == cache2;
Assert.That(sameRef == true);
}
}
You made the following registration:
_container.AddRegistration(
serviceType: typeof(ICacheManager<SettingsData>),
registration: registration);
And you're doing the following resolve:
_container.GetInstance<SettingsCache>();
You haven't registered SettingsCache
explicitly, but only ICacheManager<SettingsData>
. Since SettingsCache
is a concrete class, Simple Injector will resolve it as transient instance for you.
The solution is to either register SettingsCache
explicitly or resolve ICacheManager<SettingsData>
instead. You can make a second registration with using the same Registration
instance. For instance:
_container.AddRegistration(
serviceType: typeof(SettingsCache),
registration: registration);
The Diagnostic Services will warn you about this this type of misconfiguration.