I have what I'd consider a standard .NET MVC3 Repository pattern project that I've been playing/learning with. It's pretty standard structure.
I've run into a scenario where I need to inject a private member of a class that only has a static constructor which leaves me out of luck for constructor injection.
The class in question is a wrapper to use an AppFabric caching implementation that I just completed. (For those so inclined, my implementation is based on https://github.com/geersch/AppFabric )
Essentially I have:
The static class cache is where I'd like to inject an ICacheProvider that gets resolved to DefaultCacheProvider.
private static readonly ICacheProvider CacheProvider;
static Cache()
{
//DependencyResolver.Current.GetService<ICacheProvider>();
//CacheProvider =
// (ICacheProvider)ServiceLocator.Current
// .GetInstance(typeof(ICacheProvider));
}
public static void Add(string key, object value)
{
CacheProvider.Add(key, value);
}
public static void Add(string key, object value, TimeSpan timeout)
{
CacheProvider.Add(key, value, timeout);
}
public static object Get(string key)
{
return CacheProvider[key];
}
public static bool Remove(string key)
{
return CacheProvider.Remove(key);
}
Based off what I've read, this seems like a scenario for ServiceLocator but I've seen some very strong opinions on it (anti pattern, etc. etc), that and my familiarity with it is low so I'm unsure of an implementation that would work.
I've seen the recommendation on StackOverflow to design the Cache class as a standard class and inject the ICacheProvider in SingletonScope
kernel.Bind<ICacheProvider>().To<DefaultCacheProvider>().InSingletonScope();
but I personally would prefer a static wrapper for ease of use.
Is a ServiceLocator setup the way to go here or is there something else obvious that I'm unaware of? If ServiceLocator is the way to go, is there any tie-in with Ninject to utilize? I know Ninject now has service locator capabilities but was unsure how to implement.
Thanks for any info.
I think your approach is missing the essence of the Inversion of Control container to provide Dependency Injection.
Based off what I've read, this seems like a scenario for ServiceLocator but I've seen some very strong opinions on it (anti pattern, etc. etc)
The very strong opinons usually include an aversion to the Singleton pattern, or, in other words, using a static class to provide services. The problem here is that the Cache
class you've written is the same Singleton pattern that is the anti-pattern you referred to.
What does the code that consumes the Cache
singleton look like? Let me propose a hypothetical.
public class SomeClass
{
public string GetSomeMetaData()
{
return Cache.Get("magicKey");
}
}
In this case, you've abstracted the IoC and avoided DI by using a Singleton. I would suggest
public class SomeClass
{
private readonly ICacheProvider _cacheProvider;
public SomeClass(ICacheProvider cacheProvider)
{
_cacheProvider = cacheProvider;
}
public string GetSomeMetaData()
{
return _cacheProvider.Get("magicKey");
}
}
Now the consumption of the ICacheProvider
occurs directly in the class that needs it and can more easily accomodate change to ICacheProvider
implementations. It had the added benefit of simplifying testing. The Singleton pattern is nearly impossible to test against.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With