Ninject 的 .NET MVC3 服务定位器/依赖关系解析器问题

发布于 2024-11-02 23:09:04 字数 1796 浏览 6 评论 0原文

我有一个我一直在玩/学习的标准 .NET MVC3 存储库模式项目。这是非常标准的结构。

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

我遇到了一个场景,我需要注入一个只有静态构造函数的类的私有成员,这让我运气不佳构造函数注入。

相关类是使用我刚刚完成的 AppFabric 缓存实现的包装器。 (对于那些如此倾向于的人,我的实现是基于 https://github.com/geersch/AppFabric

本质上我有:

  • 接口 ICacheProvider
  • 类 DefaultCacheProvider : ICacheProvider
  • 静态类缓存(利用我注入的任何实现)

静态类缓存是我想注入解析为 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 类设计为标准类并将 ICacheProvider 注入 SingletonScope 上的建议,

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

但我个人更喜欢静态包装器以方便使用。

ServiceLocator 设置是到这里的方法还是有其他我不知道的明显的事情?如果 ServiceLocator 是可行的方法,是否可以与 Ninject 结合使用?我 知道 Ninject 现在具有服务定位器功能,但不确定如何实施。

感谢您提供任何信息。

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.

  • Repository project (with the below mentioned Caching infrastructure)
  • Domain Model Project
  • Service Layer Project
  • MVC Presentation project

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:

  • interface ICacheProvider
  • class DefaultCacheProvider : ICacheProvider
  • static class Cache (utilizing whatever implementation I've injected)

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猫烠⑼条掵仅有一顆心 2024-11-09 23:09:04

我认为您的方法缺少控制反转容器提供依赖注入的本质。

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

非常强烈的意见通常包括对单例模式的厌恶,或者,也就是说,使用静态类来提供服务。这里的问题是您编写的 Cache 类与您提到的反模式是相同的单例模式。

使用 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 实现的更改。它还有简化测试的额外好处。单例模式几乎不可能进行测试。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文