. net MVC3服务定位器/依赖解析器问题

本文关键字:问题 依赖 MVC3 服务 定位器 net | 更新日期: 2023-09-27 17:51:21

我有一个我认为是标准的。net mvc存储库模式项目,我一直在玩/学习。这是非常标准的结构。

  • 存储库项目(包含下面提到的缓存基础设施)
  • 领域模型项目
  • 服务层项目
  • MVC演示项目

我遇到了一个场景,我需要注入一个只有静态构造函数的类的私有成员,这使我无法进行构造函数注入。

所讨论的类是使用我刚刚完成的AppFabric缓存实现的包装器。(对于那些有这种倾向的人,我的实现是基于https://github.com/geersch/AppFabric)

基本上我有:

  • 界面ICacheProvider
  • 类defaultacheprovider: ICacheProvider
  • 静态类缓存(利用我注入的任何实现)

静态类缓存是我想注入一个ICacheProvider的地方,它被解析为defaultacheprovider。

    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的建议,将缓存类设计为一个标准类,并在SingletonScope中注入ICacheProvider

kernel.Bind<ICacheProvider>().To<DefaultCacheProvider>().InSingletonScope();

但是我个人更喜欢静态包装器,因为这样更容易使用。

是ServiceLocator设置的方式去这里还是有其他明显的东西,我不知道?如果ServiceLocator是要走的路,是否有任何与Ninject的关联来利用?我知道Ninject现在有服务定位器功能,但不确定如何实现。

. net MVC3服务定位器/依赖解析器问题

我认为你的方法错过了控制反转容器提供依赖注入的本质。

根据我所读到的,这似乎是ServiceLocator的一个场景,但我看到了一些非常强烈的意见(反模式等)

非常强烈的观点通常包括对单例模式的厌恶,或者换句话说,使用静态类来提供服务。这里的问题是,您编写的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实现的更改。它还有简化测试的额外好处。单例模式几乎不可能进行测试