2017-01-11 3 views
-2

Есть ли какой-либо трюк или шаблон дизайна или каким-либо другим способом универсальные способы сделать доступный объект «глобально», поэтому вы можете получить доступ к объекту по мере необходимости из приложения, чтобы он мог загружаться с процессом загрузки приложения (независимо от того, является ли это настольным приложением, например консолью или веб-приложением, таким как MVC)Глобальный доступ к объекту из любого места

Я в основном ищу что-то, что я могу инициализировать в основном способе запуска и он будет доступен без необходимости передавать его каждому методу для его использования, в то время как он сохраняет свое состояние и свойства, с которыми он был инициализирован.

+0

Несомненно, определите 'public static class Globals {public static object EvilGlobal {get; set;}} ', и вы можете получить доступ к' Globals.EvilGlobal' из любого места. – Blorgbeard

+0

Я считаю, что вы хотите сделать объект статическим: https://msdn.microsoft.com/en-us/library/98f28cdx.aspx –

+1

Существуют различные варианты в зависимости от типа приложения (web/console/whatever) но это почти всегда антипаттерн. – DavidG

ответ

3

Как я уже упоминал в своем комментарии, это выглядит как 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; } 
} 
1

Я думаю, что вы ищете Singleton Pattern

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

+2

Хотя это может быть быстрое и грязное исправление, в этом вопросе упоминается использование его для поддержания состояния. Когда шаблон Singleton используется для хранения состояния, все, что вы действительно получаете, является переопределенной глобальной переменной. Это намного больше похоже на анти-шаблон, чем что-то рекомендовать. –

Смежные вопросы