我在某些类中反复出现设计问题,这些类需要使用参数(例如配置文件等外部资源的名称)进行一次性初始化。
例如,我有一个 corelib 项目,它提供应用程序范围的日志记录、配置和通用帮助程序方法。该对象可以使用静态构造函数来初始化自身,但它需要访问一个它自己找不到的配置文件。
我可以看到几个解决方案,但这两个似乎都不太正确:
1) 使用带参数的构造函数。但是每个需要 corelib 功能的对象也应该知道配置文件的名称,所以这必须在应用程序中传递。此外,如果我将 corelib 实现为单例,我还必须将配置文件作为参数传递给 GetInstance 方法,我认为这也不正确。
2) 创建一个静态属性或方法来传递配置文件或其他外部参数。
我有点使用了后一种方法并创建了一个 Load 方法,该方法初始化一个内部类,它通过构造函数中的配置文件传递。然后这个内部类通过公共(public)属性 MyCoreLib 公开。
public static class CoreLib
{
private static MyCoreLib myCoreLib;
public static void Load(string configFile)
{
myCoreLib = new MyCoreLib(configFile);
}
public static MyCoreLib MyCoreLib
{
get { return myCoreLib; }
}
public class MyCoreLib
{
private string configFile;
public MyCoreLib(string configFile)
{
this.configFile = configFile;
}
public void DoSomething()
{
}
}
}
不过我还是不开心。在您调用 load 方法之前,内部类不会被初始化,因此在访问 MyCoreLib 的任何地方都需要考虑这一点。也没有什么可以阻止某人再次调用加载方法。
还有其他模式或想法可以实现吗?
最佳答案
您需要一个共同的位置来存储它。即使这是一个单独的程序集,您也可以使用 app.config,方法是在库程序集中定义一个配置部分并引用它来处理 app.config。或者您可以只向 appSettings 添加一个通用设置并引用它而不使用强类型设置。如果该值是用户输入的,那么您可以使用隔离存储。 最后,您可以在安装时将它放在注册表中一个众所周知的位置。
下面的代码封装得更好
public interface ICoreLib
{
void SomeMethod();
}
public static class CoreLibManager
{
private static ICoreLib coreLib;
private static volatile bool initialized;
private static readonly object lockObject = new object();
public static ICoreLib CoreLib
{
get
{
Inititialize();
return coreLib;
}
}
/// <summary>
/// The inititialize.
/// </summary>
private static void Inititialize()
{
if (initialized)
{
lock (lockObject)
{
if (!initialized)
{
string configFile = // Fech from common location
coreLib = new MyCoreLib(configFile);
initialized = true;
}
}
}
}
/// <summary>
/// The my core lib.
/// </summary>
private class MyCoreLib : ICoreLib
{
public MyCoreLib(string configPath)
{
}
public void SomeMethod()
{
}
}
}
关于C#静态构造函数设计问题——需要指定参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2687403/