如何要求消费者使用类库来初始化静态变量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何要求消费者使用类库来初始化静态变量相关的知识,希望对你有一定的参考价值。

我正在创建一个包含许多类(也是子类)的DLL。 其中一个(主类)有公共静态属性,如:

public static Guid Token { get; set; }

然后我将编译后的文件发送给另一个人。此人将DLL连接为对他/她的项目的引用,然后使用特定的类。

在使用任何类之前,是否有一种模式/优雅方式强制用户使用值填充静态属性?

答案

你不能强迫某人这样做。

你可以记录它需要完成,但我们都知道它有多好。

如果没有完成,您可以抛出异常,最好使用描述性错误消息和描述如何解决此问题。

更好的方法是将这个令牌实际传递给所有需要它的方法。这样很明显他们需要通过它。此外,它甚至是线程安全的,并且它们可以在不同的时间将多个令牌传递给不同的方法。

另一答案

如果你必须使用静态属性,那么你可以要求消费者调用Initialize方法:

public void InitializeThisGuidThatYouMustInitialize(Guid guid)
{
    // throw an exception if it's empty. Maybe throw an exception
    // if it's already been initialized.
    _theStaticGuid = guid;
}

然后,在你的库中,当你需要Guid时,调用一个方法,如果它已被初始化则返回Guid,如果不是则抛出异常。

像这样的东西

internal Guid GetTheGuidINeed()
{
    if(_theStaticGuid == Guid.Empty) // or use nullable
        // Don't make them guess.
        throw new Exception("Really clear, helpful exception.");
    return _theStaticGuid;
}

只有当您与静态实现绑定时才会这样。如果有很多这些值,那么您可以使用不可变的设置类。要求使用者使用类的实例进行初始化,并验证类的构造函数中的值。


另一种消除静态属性的方法是,如果您可以编写一个类来为消费者使用的DI容器配置库。以下是使用Windsor的示例:

public interface IMyLibrarySettings
{
    Guid TheGuidINeed { get; }
}

public class MyLibrarySettings : IMyLibrarySettings
{
    public MyLibrarySettings(Guid theGuidINeed)
    {
        TheGuidINeed = theGuidINeed;
    }

    public Guid TheGuidINeed { get; }
}

public class MyLibraryWindsorFacility : AbstractFacility
{
    private readonly IMyLibrarySettings _settings;

    public MyLibraryWindsorFacility(IMyLibrarySettings settings)
    {
        _settings = settings;
    }

    protected override void Init()
    {
        // validate the settings, make sure they didn't leave stuff out
        // throw awesome clear exception messages.
        Kernel.Register(Component.For<IMyLibrarySettings>().Instance(_settings));
        // register the other dependencies in your library.
    }
}

现在消费者会打电话

var settings = new MyLibrarySettings(guidThatTheySupply);
var facility = new MyLibraryWindsorFacility(settings);
container.AddFacility(facility);

你可以用Unity,Autofac等做同样的事情。

现在你用一块石头杀死了很多鸟。您的库在使用者的容器中配置其依赖项,为此,它需要使用者提供所需的设置值。当各个类需要这些设置时,只需将该接口注入其构造函数中即可,因为该类型已向容器注册以返回使用者提供的实例。

我更喜欢这个,而不是要求使用者将该值传递给构造函数,除非它是消费者明确创建的类。我不希望消费者知道所有各种类所依赖的东西。

另一答案

一个简单的解决方案可能是添加一个接受此guid作为参数的构造函数。这样,用户需要通过构造函数进行设置,如果没有有效的guid,则无法实例化类:

 public class YourClass
 {
      public YourClass(Guid token)
      {
           // Validate token and throw exception if not valid
           Token = token;
      }

      public static Guid Token { get; set; }
 }

通过这种方法,依赖性也变得清晰。此外,您还可以检查集合,以确保它不能设置为Guid.Empty。

以上是关于如何要求消费者使用类库来初始化静态变量的主要内容,如果未能解决你的问题,请参考以下文章

AJAX相关JS代码片段和部分浏览器模型

如何通过 JavaCSV 类库来优雅地(偷懒)读写 CSV 文件?

请问java构造函数如何初始化成员变量的啊?

函数范围的静态变量如何导致与共享库中函数代码的未来使用不兼容

如何更改片段中的主要活动变量

java中的静态变量,静态方法与静态代码块详解