简体   繁体   English

访问static数据的设计模式

[英]Design pattern for accessing static data

I have a scenario where I have a set of credentials for each environment eg for dev env username1/pwd1, for qa env username2/pwd2, for staging username3/pwd3 and so on.我有一个场景,其中每个环境都有一组凭据,例如,dev env username1/pwd1、qa env username2/pwd2、staging username3/pwd3 等等。 Now I want to create a class which will return me a set of credentials based on the env I feed to it.现在我想创建一个 class,它将根据我提供给它的环境向我返回一组凭据。 All the data has to go within code (as per my brilliant boss, no xml files and all), what design pattern I could use so that the code will be elegant and data can be made extensible in future?所有数据在代码中都必须为 go(根据我聪明的老板,没有 xml 文件和所有),我可以使用什么设计模式,以便代码优雅并且数据可以在将来扩展?

Personally, I am used to create a channel attribute: 就个人而言,我习惯于创建一个频道属性:

[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public sealed class AssemblyChannelAttribute : Attribute
{
    public ChannelType Type { get; private set; }

    public AssemblyChannelAttribute(ChannelType type)
    {
        this.Type = type;
    }
}

public enum ChannelType
{
    Dev,
    Beta,
    PreProd,
    Prod
}

This attribute is set on the Assembly: 此属性在程序集上设置:

#if DEBUG
// In release mode, this attribute is set by the MSBuild script
[assembly: AssemblyChannel(ChannelType.Dev)]
#else

As the comment said, the value of the attribute is set on compile time by my MSBuild script (too tied to my project to show you this part). 正如评论所说,属性的值是在我的MSBuild脚本的编译时设置的(与我的项目过于关联,以向您展示此部分)。

Once you have setup all of this, you can create a simple singleton like this: 设置完所有这些后,您可以创建一个简单的单例,如下所示:

public class Credentials
{
    private static readonly Lazy<Credentials> instanceHolder =
        new Lazy<Credentials>(() => new Credentials());

    public IReadOnlyDictionary<string, string> Passwords { get; private set; }

    public Credentials Instance { get { return instanceHolder.Value; } }

    private Credentials()
    {
        var channel = typeof(Credentials).Assembly
            .GetCustomAttributes<AssemblyChannelAttribute>()
            .ElementAt(0)
            .Type;

        switch (channel)
        {
            case ChannelType.Dev:
                this.Passwords = new ReadOnlyDictionary<string, string>(new Dictionary<string, string>
                {
                    ["User1"] = "Pwd1",
                    ["User2"] = "Pwd2",
                    // etc
                });
                break;
            case ChannelType.Beta:
                // etc
                break;
            case ChannelType.PreProd:
                // etc
                break;
            case ChannelType.Prod:
                // etc
                break;
        }
    }
}

Then you can access your credentials like this: 然后您可以像这样访问您的凭据:

var password = Credentials.Instance.Passwords["User1"];

If you use .Net core, you could use the configuration techniques. 如果使用.Net core,则可以使用配置技术。 They are very powerful and work in asp .net as well as console programs They are very configurable and composable (pass in config via cmd and json for example) 它们非常强大,可以在asp .net以及控制台程序中工作。它们非常易于配置和组合(例如通过cmd和json传递配置)

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration

What you're after is the Multiton design pattern.您所追求的是Multiton设计模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM