【问题标题】:Global access to an object from anywhere从任何地方全局访问对象
【发布时间】:2017-01-11 19:20:17
【问题描述】:

是否有某种技巧、设计模式或其他通用方法可以使对象“全局”可用,因此您可以根据需要从应用程序访问对象,以便可以在加载过程中加载它应用程序(无论是控制台等桌面应用程序,还是 MVC 等 Web 应用程序)

我基本上是在寻找可以在主启动方法中初始化的东西,并且无需将其传递给每个方法即可使用它,同时它保留其初始化时的状态和属性。

【问题讨论】:

标签: c#


【解决方案1】:

正如我在评论中提到的,这看起来像 XY Problem。我相信正确的解决方案是只使用 IoC/DI,而不是实际执行全局变量,大多数人认为堆栈溢出是不行的。我更喜欢使用Autofac(没有隶属关系,有很多 DI 框架可供选择)。这允许每个对象简单地请求(通过构造函数注入或不推荐的属性注入方法)它需要使用的对象才能正常运行。这减少了耦合并有助于测试代码(单元测试)。

using System;
using Autofac;

public class Program
{
    public static void Main()
    {
        // Start configuring DI
        IoCConfig.Start();

        // Start "scope" in which Autofac builds objects "in"
        using(var scope = IoCConfig.Container.BeginLifetimeScope())
        {
            // Resolve the Worker
            // Autofac takes care of the constructing of the object
            // and it's required parameters
            var worker = scope.Resolve<Worker>();

            worker.DoWork();
        }
    }
}

// the class that does work, it needs the Configuration information
// so it is added to the constructor parameters
public class Worker
{
    private readonly string _connectionString;

    public Worker(IConfiguration config)
    {
        _connectionString = config.ConnectionString;
    }

    public void DoWork()
    {
        // Connect to DB and do stuff
        Console.WriteLine(_connectionString);
    }
}

public static class IoCConfig
{
    public static IContainer Container { get; private set; }

    public static void Start()
    {
        var builder = new ContainerBuilder();


        // Register Global Configuration
        builder.Register(c => new Configuration{
            ConnectionString = "my connection string" // or ConfigurationManager.ConnnectionString["MyDb"].ConnectionString;
        })
            .As<IConfiguration>();

        // Register an concrete type for autofac to instantiate
        builder.RegisterType<Worker>();

        Container = builder.Build();
    }

    private class Configuration : IConfiguration
    {
        public string ConnectionString { get; set; }
    }

}

public interface IConfiguration
{
    string ConnectionString { get; }
}

【讨论】:

    【解决方案2】:

    我认为您正在寻找单例模式

    https://msdn.microsoft.com/en-us/library/ff650316.aspx

    【讨论】:

    • 虽然这可能是一个快速而肮脏的修复,但问题提到使用它来维护状态。当单例模式用于存储状态时,你真正得到的只是一个变相的全局变量。这更像是一种反模式,而不是推荐的东西。
    猜你喜欢
    • 1970-01-01
    • 2016-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-13
    相关资源
    最近更新 更多