时间:2019-03-17 标签:c#SETTINGSarchitecture

发布于 2024-09-08 22:00:45 字数 789 浏览 2 评论 0原文

我有几个需要读取和写入应用程序设置的应用程序。由于其中一个应用程序是一个遗留的 C++ 应用程序,在注册表中具有数百个设置(并且不一定会更改),并且还有一些设置以专有数据库格式存储,我想知道如何将架构设置为允许使用单个接口读取和/或写入设置。
一个想法是有一个巨大的枚举,其中包含所有可能的设置和一个分割,根据一个巨大的 case 语句将读/写请求定向到正确的读取器或写入器。对于注册表,则必须进一步解析枚举可能性以找到该键的位置(如果它是一个 Http 设置,则位于此处,如果它是一个安装设置,则位于该键处)。这整个想法让我想到非 OOP 和太多的手动测试。请记住,大约有 30 个数据库设置,也许有 70 个注册表设置。

public class SettingsTest
{
    public enum ESetting
    {
        HttpUserName, HttpPassword, SetupAllowPublic,  //db server stored
        HttpProxyUsername, HttpProxyPassword, PublicOrPrivate //registry stored
    }

    public string GetSetting(ESetting setting)
    {
        if (IsSettingInRegistry(setting)
            return RegHandler.GetFromRegistry(setting);
        else
            return DBHandler.GetFromDB(setting);
    }
}

I have several applications that need to read and write application settings. Since one of the apps is a legacy c++ app with hundreds of settings in the registry (and that isn't bound to change) and there are also some settings stored in a proprietary database format I'm wondering how the architecture could be setup to allow a single interface in for reading and or writing the settings.
One idea is for there to be a giant enum with every possible setting and a split that directs the read/write request, based on a giant case statement, to the correct reader or writer. In the case of the registry this would then have to further parse the enum possibilities to find the key's location (if its an Http setting its here, if its a Setup setting its located at this key). This whole idea makes me think non-OOP and too much manual testing. Keep in mind that there are about 30 DB settings, and maybe 70 registry settings.

public class SettingsTest
{
    public enum ESetting
    {
        HttpUserName, HttpPassword, SetupAllowPublic,  //db server stored
        HttpProxyUsername, HttpProxyPassword, PublicOrPrivate //registry stored
    }

    public string GetSetting(ESetting setting)
    {
        if (IsSettingInRegistry(setting)
            return RegHandler.GetFromRegistry(setting);
        else
            return DBHandler.GetFromDB(setting);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

真心难拥有 2024-09-15 22:00:45

我认为“大”枚举可能有点令人讨厌 - 为什么不使用命名空间来分解它们?到 引用 MSDN

通常最好定义一个枚举
直接在命名空间内,以便
命名空间中的所有类都可以
访问它同样方便。
但是,枚举也可以嵌套
在类或结构内

所以你可以有:

RediVider.EnterpriseApp.DataAccess.ESettingsKeys
RediVider.EnterpriseApp.BusinessLogic.ESettingsKeys
RediVider.EnterpriseApp.ComponentXXX.ESettingsKeys

另外 - 你会声明枚举或静态只读字段吗? (其中值是键,并且假设当您定义键时,您明确定义了它的来源 - 因此是键的值)。

更好的想法是不定义存储库特定键,而是定义映射回 AppSetting 键的键 - 这就是您定义实际存储库特定键的位置。这将允许您通过配置更改从何处获取“设置”,而无需重新部署应用程序。

所以,你有:

namespace RediVider.EnterpriseApp.DataAccess
{
  Public class ESettingsKeys
  {
    // Note - AppSetting Keys are "namespaced" to match: 
    public readonly string SetupAllowPublic = "RediVider.EnterpriseApp.DataAccess.SetupAllowPublic";
  }
} 

然后在你的配置中(伪代码):

<AppSetting Key="RediVider.EnterpriseApp.DataAccess.SetupAllowPublic" value="/System/Settings/Blah/SetupAllowPublic">

唯一的障碍是,这只有助于将按键分解为更符合逻辑且更容易处理的区域 - 你仍然遇到以下问题解决存储库。如果你真的想抽象出来,你需要序列化一个具有

  • 存储
  • 键值

的简单类switch 语句的想法并不是那么糟糕,但你也可以在这里采取相同的方法,使用某种 Facade 或基于工厂模式的方法:

  • 有各种具体方法从存储库获取设置。
  • 在每个命名空间(根据 ESetting 枚举)中都有一个“GetSettings”方法,该方法可以执行您所描述的操作 - 但仅适用于该命名空间中定义的设置。

I think the "big" enum might be a bit nasty - why don't you break them up using namespaces; to quote MSDN:

Usually it is best to define an enum
directly within a namespace so that
all classes in the namespace can
access it with equal convenience.
However, an enum can also be nested
within a class or struct

So you could have:

RediVider.EnterpriseApp.DataAccess.ESettingsKeys
RediVider.EnterpriseApp.BusinessLogic.ESettingsKeys
RediVider.EnterpriseApp.ComponentXXX.ESettingsKeys

Also - would you be declaring enums, or static readonly fields? (where the value is the key, and working on the assumption that when you define a key you explicity define where it's coming from - hence the vale of the key).

A better idea would be to not define a repository specific key, but a key which mapped back to an AppSetting key - and that's where you defined the actual respository specific Key. This would allow you to change where to get the "setting" from - via config, and without having to re-deploy the app.

So, you have:

namespace RediVider.EnterpriseApp.DataAccess
{
  Public class ESettingsKeys
  {
    // Note - AppSetting Keys are "namespaced" to match: 
    public readonly string SetupAllowPublic = "RediVider.EnterpriseApp.DataAccess.SetupAllowPublic";
  }
} 

Then in your config (psuedo code):

<AppSetting Key="RediVider.EnterpriseApp.DataAccess.SetupAllowPublic" value="/System/Settings/Blah/SetupAllowPublic">

The only snag is that this only helps break-up the keys into more logical and easier to deal with areas - you stil have the issue of resolving the repository. If you really wanted to abstract that out you'd need to serialize a simple class that had

  • Key
  • Value
  • Repository

The idea of the switch statement isn't so bad, but you could take the same approach here too, using a sort of Facade or Factory pattern based approach:

  • Have various concrete methods that get the settings from storage repository.
  • In each namespace (as per the ESetting enums) have a "GetSettings" method that does what you've described - but only for the settings defined in that namespace.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文