IOC - 具有静态帮助方法的util类是否应该与IOC连接?

Gre*_*reg 27 static ninject instance ioc-container inversion-of-control

只是试着继续关注IOC原则.

Q1:静态方法 - 是否应将带有静态辅助方法的util类与IOC连接?

例如,如果我有一个带有许多静态方法的HttpUtils类,我应该尝试通过IOC将它传递给其他业务逻辑类吗?

关注这个问题可能是:

Q2:Singletons - 通过Logger.getInstance()类型调用,通常可以访问它的内容.您是否通常将其保留原样,并且不使用IOC将记录器注入需要它的业务类?

问题3:静态类 - 我还没有真正使用过这个概念,但如果你转向基于IOC的方法,那么你是否有任何指导方针可以解决这个问题.

提前致谢.

Bry*_*tts 32

关于IoC的有趣之处在于,以风格编写的对象通常与这些细节分离.

我们以实用程序类为例:

public class HttpUtils
{
    public static void DoStuff(int someValue)
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

在非IoC专注的应用程序中,您可以直接使用该方法:

public class Foo
{
    public int Value { get; set; }

    public void DoStuff()
    {
        HttpUtils.DoStuff(Value);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,它将DoStuff直接定义与其实现相结合.IoC努力离婚这些细节,所以我们自己定义操作:

public interface IDoesStuff
{
    void DoStuff(int someValue);
}
Run Code Online (Sandbox Code Playgroud)

然后,我们留出空间Foo让实施改变:

public class Foo
{
    private readonly IDoesStuff _doesStuff;

    public Foo(IDoesStuff doesStuff)
    {
        _doesStuff = doesStuff;
    }

    public int Value { get; set; }

    public void DoStuff()
    {
        _doesStuff.DoStuff(Value);
    }
}
Run Code Online (Sandbox Code Playgroud)

这样可以使FooHttpUtils.概念的实现者DoStuff现在是配置细节,而不是固有的依赖(就像静态方法一样).

请注意,Foo不知道它IDoesStuff是否是单身.这个生命周期也是一个配置细节,而不是一个固有的细节Foo.

总而言之,IoC static通常是不一致的,因为IoC促进了变化,并且static根据定义,它会阻止它.在构造函数中声明您的依赖项,您会发现几乎从未使用过static功能.

  • 最终你想要消除实用程序类.每个类的每个方法都有与上面的`HttpUtils.DoStuff`方法相同的耦合问题.因此,您不希望要求*any*代码直接依赖于`static`成员.相反,取"HttpUtils.DoStuff"的主体,把它放在`IDoesStuff`后面,并完全从`HttpUtils`中删除该方法.现在,任何可能调用静态方法的类都可以在其构造函数中接受`IDoesStuff`.中提琴:不再需要实用类! (2认同)
  • 我建议您按功能组织项目元素,而不是按技术细节组织.这意味着特定于Web的实用程序类将与其他与Web相关的内容一起使用,而特定于数据的实用程序类将与其他与数据相关的内容一起使用.将web和数据相关的实用程序类混合起来仅仅因为它们是实用程序类是没有多大意义的.所以为了回答你的问题,还有其他方法可以提供更多有用的方法. (2认同)

Ant*_*ony 8

IoC容器通常用于注入具有状态的对象; 或者具有多个实现的类或接口,即使第二个实现是用于测试目的的模拟.如果这些都不是真的,那么通过注入它就没有任何好处.这些天最常见的习惯是让你的类面向真实和模拟实现都可以实现的接口.

1)辅助类的静态方法 - 不,这些通常不会被IoC注入.通常它们是无状态实用程序.

要使用一个非常简单的示例,您不需要两个版本的实用程序方法调用StringUtils.Reverse().你只需要一个,你可以很容易地围绕它编写测试,因为它没有状态或依赖,所以嘲笑它绝对没有任何好处.示例测试:

string reversedString = StringUtils.Reverse("input");
Assert.AreEqual("tupni", reversedString)
Run Code Online (Sandbox Code Playgroud)

如果该实用程序实际上不是无状态的(例如,依赖于HttpContext.Current),那么您应该通过注入它来使该依赖项显式化,而不是使该实用程序保持静态.

2)单身人士:通常是的,单身人士注入.但IoC的一个好处是你不用担心是否只有一个东西.通过使用IoC,您可以获得实例化的灵活性.每次将特定类型作为单例或新实例的决定成为IoC容器配置的一部分,代码中的其他任何内容都不需要更改.

因此,singleton-hood不再是一个单独的问题,必须编写到类中(并且当它们不必要时有多个关注的类是坏的),它成为IoC容器的关注点.你没有把这个类"作为一个单独的代码"编写成任何特殊的东西,如私有构造函数和public static GetInstance()方法,你只需要为主要问题编写代码,而IoC容器的配置指定它是否是单例,或者在某处之间,像每个线程一个实例.

3)静态类 - 静态方法的自然之家.考虑在适当的地方制作静态方法扩展方法.您无法注入这些类,因为您无法创建它们.使用静态类使得过程不是面向对象的代码.这对小辅助方法来说并不坏,但如果大多数代码都是这样,那么你就不会使用.Net平台强大的OO功能.