2017-01-11 1 views
-2

Gibt es eine Art Trick oder Entwurfsmuster oder andere universelle Möglichkeiten, ein Objekt "global" verfügbar zu machen, damit Sie von einer Anwendung aus so auf ein Objekt zugreifen können, wie es möglich ist geladen werden mit dem Ladevorgang der Anwendung (unabhängig davon, ob es eine Desktop-App wie Konsole oder eine Web-App wie MVC ist)Globaler Zugriff auf ein Objekt von überall aus

Ich bin im Grunde auf der Suche nach etwas, das ich in der Hauptstartmethode initialisieren kann und Es wird verfügbar sein, ohne es an jede Methode übergeben zu müssen, während es seinen Zustand und seine Eigenschaften beibehält, mit denen es initialisiert wurde.

+0

Sicher, definieren 'öffentliche statische Klasse Globals {öffentliches statisches Objekt EvilGlobal {erhalten; set;}} 'und dann können Sie von überall auf' Globals.EvilGlobal' zugreifen. – Blorgbeard

+0

Ich glaube, Sie suchen ein Objekt statisch zu machen: https://msdn.microsoft.com/en-us/library/98f28cdx.aspx –

+1

Es gibt verschiedene Optionen je nach Art der App (Web/Konsole/was auch immer) aber das ist fast immer ein Antipattern. – DavidG

Antwort

3

Wie ich in meinem Kommentar erwähnt, dies wie ein XY Problem aussieht. Anstatt globale Variablen zu verwenden, die die meisten Leute beim Stacküberlauf fühlen, sind sie ein No-No. Ich glaube, die richtige Lösung ist, einfach IoC/DI zu verwenden. Ich bevorzuge die Verwendung von Autofac (keine Zugehörigkeit und es gibt viele DI-Frameworks zur Auswahl). Dadurch kann jedes Objekt einfach (durch Konstruktorinjektion oder den nicht empfohlenen Ansatz der Eigenschafteninjektion) die Objekte anfordern, die es benötigt, um richtig zu funktionieren. Dies verringert die Kopplung und kann beim Testen von Code (Komponententests) helfen.

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

Ich glaube, Sie suchen das Singleton Pattern

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

+2

Während dies eine schnelle und dreckige Lösung sein kann, erwähnt die Frage die Verwendung, um den Zustand beizubehalten. Wenn das Singleton-Muster zum Speichern des Zustands verwendet wird, erhalten Sie nur eine globale Variable in Verkleidung. Dies ist viel mehr wie ein Anti-Muster als etwas zu empfehlen. –

Verwandte Themen