我有我认为的标准.NET MVC3存储库模式项目,我一直在玩/学习。这是非常标准的结构。
我遇到了一个场景,我需要注入一个只有一个静态构造函数的类的私有成员,这会让我的构造函数注入失败。
有问题的类是使用我刚刚完成的AppFabric缓存实现的包装器。 (对于那些如此倾向的人,我的实施基于 http://cgeers.wordpress.com/2010/07/04/windows-server-appfabric-caching/)
基本上我有:
静态类缓存是我想要注入一个解析为DefaultCacheProvider的ICacheProvider的地方。
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);
}
基于我所读到的内容,这似乎是ServiceLocator的一个场景,但我已经看到了一些非常强烈的意见(反模式等等),而且我对它的熟悉程度很低 所以我不确定哪种方式可行。
我已经看到StackOverflow建议将Cache类设计为标准类并在SingletonScope中注入ICacheProvider
kernel.Bind<ICacheProvider>().To<DefaultCacheProvider>().InSingletonScope();
但我个人更喜欢静态包装以方便使用。
ServiceLocator是设置到这里的方式还是还有一些我不知道的明显的东西?如果要使用ServiceLocator,是否可以使用与Ninject的搭配?一世 知道Ninject现在有服务定位器功能,但不确定如何实现。
感谢您的任何信息。
答案 0 :(得分:5)
我认为你的方法缺少控制反转容器的本质来提供依赖注入。
根据我所读到的内容,这似乎是ServiceLocator的一个场景,但我已经看到了一些非常强烈的意见(反模式等)
非常强烈的观点通常包括对Singleton模式的厌恶,换句话说,使用静态类来提供服务。这里的问题是你编写的Cache
类是与你所引用的反模式相同的Singleton模式。
消耗Cache
单身的代码是什么样的?让我提出一个假设。
public class SomeClass
{
public string GetSomeMetaData()
{
return Cache.Get("magicKey");
}
}
在这种情况下,您通过使用Singleton抽象了IoC并避免了DI。我建议
public class SomeClass
{
private readonly ICacheProvider _cacheProvider;
public SomeClass(ICacheProvider cacheProvider)
{
_cacheProvider = cacheProvider;
}
public string GetSomeMetaData()
{
return _cacheProvider.Get("magicKey");
}
}
现在ICacheProvider
的消费直接发生在需要它的类中,并且可以更容易地适应对ICacheProvider
实现的更改。它具有简化测试的额外好处。 Singleton模式几乎不可能进行测试。