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

问题描述 投票:-1回答:3

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

public static Guid Token { get; set; }

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

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

c# .net class variables static
3个回答
0
投票

你不能强迫某人这样做。

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

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

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


0
投票

如果你必须使用静态属性,那么你可以要求消费者调用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等做同样的事情。

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

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


0
投票

一个简单的解决方案可能是添加一个接受此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。

© www.soinside.com 2019 - 2024. All rights reserved.