C# 从任何位置全局访问对象

C# 从任何位置全局访问对象,c#,C#,是否有某种技巧、设计模式或其他通用方法使对象“全局”可用,以便您可以根据需要从应用程序访问对象,以便在应用程序的加载过程中加载对象(无论它是桌面应用程序(如console)还是web应用程序(如MVC)) 我基本上是在寻找我可以在主启动方法中初始化的东西,它将不必传递给每个方法就可以使用,同时它保留了初始化时使用的状态和属性。我想您正在寻找单例模式 正如我在评论中提到的,这看起来像是一个错误。我认为正确的解决方案是只使用IoC/DI,而不是实际执行全局变量,因为大多数人在堆栈溢出时都认为全局变量

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


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

我想您正在寻找单例模式


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

使用系统;
使用Autofac;
公共课程
{
公共静态void Main()
{
//开始配置DI
IoCConfig.Start();
//启动Autofac在其中“中”构建对象的“范围”
使用(var scope=IoCConfig.Container.BeginLifetimeScope())
{
//解决工人问题
//Autofac负责对象的构造
//这是必需的参数
var worker=scope.Resolve();
工人。道工();
}
}
}
//如果类不工作,它需要配置信息
//因此,它被添加到构造函数参数中
公社工人
{
私有只读字符串_connectionString;
公共工作者(IConfiguration配置)
{
_connectionString=config.connectionString;
}
公共工作
{
//连接到数据库并做一些事情
Console.WriteLine(_connectionString);
}
}
公共静态类IoCConfig
{
公共静态IContainer容器{get;private set;}
公共静态void Start()
{
var builder=new ContainerBuilder();
//注册全局配置
注册器(c=>新配置{
ConnectionString=“我的连接字符串”//或ConfigurationManager.ConnnectionString[“MyDb”]。ConnectionString;
})
.As();
//注册一个具体类型,以便autofac实例化
RegisterType();
Container=builder.Build();
}
私有类配置:IConfiguration
{
公共字符串连接字符串{get;set;}
}
}
公共接口I配置
{
字符串连接字符串{get;}
}

当然,定义
公共静态类Globals{public static object EvilGlobal{get;set;}}
然后你就可以从任何地方访问
Globals.EvilGlobal
。我相信你正在寻找一个静态对象:根据应用程序的类型(web/console/whatever)有各种选项但这几乎总是一个反模式。假设您有这个,但当您尝试使用它时。你怎么才能找到损坏它的东西?它可能是任何东西。相反,创建对象并只将它们传递给对象所包含的对象。这是一个。虽然这可能是一个快速而肮脏的修复,但问题提到使用它来维护状态。当单例模式用于存储状态时,您真正得到的只是一个伪装的全局变量。这更像是一种反模式,而不是推荐的东西。
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; }
}