需要在使用前调用“Initialize”方法的静态类 - 可以吗?

时间:2010-12-11 11:33:07

标签: c# .net

在我的项目中,我有多个“服务”静态类,应该可以在整个项目中轻松访问,因此它们是静态的。但是,为了初始化它们,我必须传递它们仅在启动时可用的数据,这导致代码类似于:

public static class VisualStudioEvents
{
    private static Data _data;

    public static void Initialize(Data data)
    {
        _data = data;
    }

    public static void Func()
    {
        AssertInitialized(_data);

        // Code of actual Func() goes here.
    }
}

你怎么看?这里应该应用不同的设计模式吗?或者这种设计是否可以接受?

谢谢!

5 个答案:

答案 0 :(得分:5)

我对此非常满意。我所做的唯一改变就是将其强制执行一次:

    public static void Initialize(Data data)
    {
        if (data == null) throw new ArgumentNullException("data");
        if (Interlocked.CompareExchange(ref _data, data, null) != null)
        {
            throw new InvalidOperationException("Already initialized");
        }
    }

哦 - 我猜Data也应该是不可变的,以避免人们意外更改配置。

答案 1 :(得分:4)

我强烈反对具有状态的静态类,它与全局变量没有区别,带有状态的静态类只是将全局变量包装到类中。并we all know why globals are bad

我认为你应该得到某种inversion of control解决方案,这将允许你获得辅助类的非静态的,已初始化的实例。您的IoC容器可以在内部使用单例来确保使用单个配置对象。

例如,结构可能是:

public class VisualStudioEvents
{
    public VisualStudioEvents(VisualStudioEventsConfig config)
    {
        // ...
    }

    // ...
}

在应用程序初始化时,您可以创建一个VisualStudioEventsConfig实例,对其进行配置并添加到IoC容器中作为该类型的唯一实例。然后,将使用此准备好的配置实例初始化VisualStudioEvents实例的每个调用。

答案 2 :(得分:3)

这可能是Singleton模式的一个很好的例子,您可以在构造函数中调用initialize,Data作为类成员,如果Data不可用则抛出异常。

但是,您问题中的Data尽可能通用,因此根据其目的/可用性,可能有更好的方法来协调此初始化。

编辑

答案 3 :(得分:2)

名称VisualStudioEvents似乎表明此类是代码与实际Visual Studio扩展API之间抽象的一部分。

如果这是正确的,那么你需要在单元测试中模拟VisualStudioEvents。我根本不会把它变成静态类。 Static methods are death to testability

编辑:正如评论中所述,链接的博文可能过于激进。我个人认为静态方法只有在包含应该是component一部分的代码时才是邪恶的。将组件代码放在静态方法中会导致单元测试和依赖注入的static cling问题。

答案 4 :(得分:0)

您可以尝试使用singleton pattern而不是静态类。这样也可以更容易地测试代码。

相关问题