2011-10-28 6 views
6

ho una classe che è cresciuta costantemente nel tempo. Si chiama LayoutManager.Cercando di allontanarsi da una classe singleton/god/manager. Non sono sicuro di come dovrei sostenere la funzionalità, anche se

Ha iniziato come metodo per tenere traccia di quali controlli creati dinamicamente erano nella mia pagina. Così, per esempio, ho questo:

public CormantRadDockZone() 
{ 
    ID = String.Format("RadDockZone_{0}", Guid.NewGuid().ToString().Replace('-', 'a')); 
    MinHeight = Unit.Percentage(100); 
    BorderWidth = 0; 
    HighlightedCssClass = "zoneDropOk"; 
    CssClass = "rightRoundedCorners"; 
    LayoutManager.Instance.RegisteredDockZones.Add(this); 
} 

In questo modo, durante le fasi iniziali del ciclo di vita pagina, i controlli sarebbero stati ricreati e loro stessi avrebbero aggiunto alla lista il loro rispettivo controllo.

Un po 'di tempo dopo mi sono ritrovato a passare l'oggetto "Pagina" tra i metodi. Questo era al solo scopo di poter accedere ai controlli trovati nella Pagina. Ho pensato a me stesso - beh, ho già un gestore di layout, mi limiterò a trattare i controlli statici allo stesso modo.

Come tale, il mio metodo Page_Init ora assomiglia a questo pasticcio:

protected void Page_Init(object sender, EventArgs e) 
{ 
    SessionRepository.Instance.EnsureAuthorized(); 

    LayoutManager.Instance.RegisteredPanes.Clear(); 
    LayoutManager.Instance.RegisteredDocks.Clear(); 
    LayoutManager.Instance.RegisteredDockZones.Clear(); 
    LayoutManager.Instance.RegisteredSplitters.Clear(); 
    LayoutManager.Instance.RegisteredSplitBars.Clear(); 
    LayoutManager.Instance.RegisteredPageViews.Clear(); 

    LayoutManager.Instance.CheckBox1 = CheckBox1; 
    LayoutManager.Instance.CheckBox4 = CheckBox4; 

    LayoutManager.Instance.StartEditButton = StartEditButton; 
    LayoutManager.Instance.FinishEditButton = FinishEditButton; 

    LayoutManager.Instance.RadNumericTextBox1 = RadNumericTextBox1; 
    LayoutManager.Instance.RadNumericTextBox2 = RadNumericTextBox2; 

    LayoutManager.Instance.LeftPane = LeftPane; 
    LayoutManager.Instance.DashboardUpdatePanel = DashboardUpdatePanel; 

    LayoutManager.Instance.CustomReportsContainer = CustomReportsContainer; 
    LayoutManager.Instance.HistoricalReportsContainer = HistoricalReportsContainer; 
    RegenerationManager.Instance.RegenerateReportMenu(); 

    LayoutManager.Instance.MultiPage = DashboardMultiPage; 
    LayoutManager.Instance.MultiPageUpdatePanel = MultiPageUpdatePanel; 
    LayoutManager.Instance.TabStrip = DashboardTabStrip; 

    RegenerationManager.Instance.RegenerateTabs(DashboardTabStrip); 
    RegenerationManager.Instance.RegeneratePageViews(); 

    LayoutManager.Instance.Timer = RefreshAndCycleTimer; 
    LayoutManager.Instance.Timer.TimerEvent += DashboardTabStrip.DoTimerCycleTick; 

    RegenerationManager.Instance.RegeneratePageState(); 
} 

sto guardando questo e dire no, no, no. È tutto sbagliato Tuttavia, ci sono controlli sulla mia pagina che sono molto dipendenti l'uno dall'altro, ma non hanno accesso l'uno all'altro. Questo è ciò che sembra renderlo così necessario.

Penso che un buon esempio di questo in pratica sarebbe utilizzare UpdatePanels. Ad esempio, DashboardUpdatePanel viene fornito al LayoutManager. Nella pagina sono presenti controlli che, a condizione, dovrebbero causare l'aggiornamento dell'intero contenuto del dashboard.

Ora, nei miei occhi, credo di avere due opzioni:

  1. all'interno dell'oggetto voler chiamare UpdatePanel.Update(), ho recurse attraverso oggetti padre, il tipo e l'ID controllo fino a trovare il UpdatePanel appropriato.
  2. Chiedo LayoutManager per UpdatePanel.

Chiaramente il secondo sembra più pulito in questo scenario ... ma mi trovo a utilizzare la stessa logica in molti casi. Ciò ha comportato una classe manager che assomiglia a questa:

public class LayoutManager 
{ 
    private static readonly ILog _logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 

    private static readonly LayoutManager _instance = new LayoutManager(); 
    private LayoutManager() { } 

    public static LayoutManager Instance 
    { 
     get { return _instance; } 
    } 

    private IList<CormantRadDock> _registeredDocks; 
    private IList<CormantRadDockZone> _registeredDockZones; 
    private IList<CormantRadPane> _registeredPanes; 
    private IList<CormantRadSplitter> _registeredSplitters; 
    private IList<CormantRadSplitBar> _registeredSplitBars; 
    private Dictionary<string, StyledUpdatePanel> _registeredUpdatePanels; 
    private IList<CormantRadPageView> _registeredPageViews; 

    public RadMultiPage MultiPage { get; set; } 
    public CormantTimer Timer { get; set; } 
    public CormantRadListBox HistoricalReportsContainer { get; set; } 
    public CormantRadListBox CustomReportsContainer { get; set; } 
    public StyledUpdatePanel MultiPageUpdatePanel { get; set; } 
    public CormantRadTabStrip TabStrip { get; set; } 
    public RadPane LeftPane { get; set; } 
    public StyledUpdatePanel DashboardUpdatePanel { get; set; } 
    public RadButton ToggleEditButton { get; set; } 

    public CheckBox CheckBox1 { get; set; } 
    public CheckBox CheckBox4 { get; set; } 
    public RadNumericTextBox RadNumericTextBox1 { get; set; } 
    public RadNumericTextBox RadNumericTextBox2 { get; set; } 

    public RadButton StartEditButton { get; set; } 
    public RadButton FinishEditButton { get; set; } 

    public IList<CormantRadDock> RegisteredDocks 
    { 
     get 
     { 
      if (Equals(_registeredDocks, null)) 
      { 
       _registeredDocks = new List<CormantRadDock>(); 
      } 

      return _registeredDocks; 
     } 
    } 

    public IList<CormantRadDockZone> RegisteredDockZones 
    { 
     get 
     { 
      if (Equals(_registeredDockZones, null)) 
      { 
       _registeredDockZones = new List<CormantRadDockZone>(); 
      } 

      return _registeredDockZones; 
     } 
    } 

    public IList<CormantRadPane> RegisteredPanes 
    { 
     get 
     { 
      if (Equals(_registeredPanes, null)) 
      { 
       _registeredPanes = new List<CormantRadPane>(); 
      } 

      return _registeredPanes; 
     } 
    } 

    public IList<CormantRadSplitter> RegisteredSplitters 
    { 
     get 
     { 
      if (Equals(_registeredSplitters, null)) 
      { 
       _registeredSplitters = new List<CormantRadSplitter>(); 
      } 

      return _registeredSplitters; 
     } 
    } 

    public IList<CormantRadSplitBar> RegisteredSplitBars 
    { 
     get 
     { 
      if (Equals(_registeredSplitBars, null)) 
      { 
       _registeredSplitBars = new List<CormantRadSplitBar>(); 
      } 

      return _registeredSplitBars; 
     } 
    } 

    public Dictionary<string, StyledUpdatePanel> RegisteredUpdatePanels 
    { 
     get 
     { 
      if(Equals(_registeredUpdatePanels, null)) 
      { 
       _registeredUpdatePanels = new Dictionary<string, StyledUpdatePanel>(); 
      } 

      return _registeredUpdatePanels; 
     } 
    } 

    public IList<CormantRadPageView> RegisteredPageViews 
    { 
     get 
     { 
      if (Equals(_registeredPageViews, null)) 
      { 
       _registeredPageViews = new List<CormantRadPageView>(); 
      } 

      return _registeredPageViews; 
     } 
    } 

    public StyledUpdatePanel GetBaseUpdatePanel() 
    { 
     string key = MultiPage.PageViews.Cast<CormantRadPageView>().Where(pageView => pageView.Selected).First().ID; 
     return RegisteredUpdatePanels[key]; 
    } 

    public CormantRadDockZone GetDockZoneByID(string dockZoneID) 
    { 
     CormantRadDockZone dockZone = RegisteredDockZones.Where(registeredZone => dockZoneID.Contains(registeredZone.ID)).FirstOrDefault(); 

     if (Equals(dockZone, null)) 
     { 
      _logger.ErrorFormat("Did not find dockZone: {0}", dockZoneID); 
     } 
     else 
     { 
      _logger.DebugFormat("Found dockZone: {0}", dockZoneID); 
     } 

     return dockZone; 
    } 

    public CormantRadPane GetPaneByID(string paneID) 
    { 
     CormantRadPane pane = RegisteredPanes.Where(registeredZone => paneID.Contains(registeredZone.ID)).FirstOrDefault(); 

     if (Equals(pane, null)) 
     { 
      _logger.ErrorFormat("Did not find pane: {0}", paneID); 
     } 
     else 
     { 
      _logger.DebugFormat("Found pane: {0}", paneID); 
     } 

     return pane; 
    } 

    public CormantRadDock GetDockByID(string dockID) 
    { 
     CormantRadDock dock = RegisteredDocks.Where(registeredZone => dockID.Contains(registeredZone.ID)).FirstOrDefault(); 

     if (Equals(dock, null)) 
     { 
      _logger.ErrorFormat("Did not find dock: {0}", dockID); 
     } 
     else 
     { 
      _logger.DebugFormat("Found dock: {0}", dockID); 
     } 

     return dock; 
    } 
} 

Sono su una cattiva strada? Quali passi vengono generalmente presi a questo punto?

EDIT1: Ho deciso di iniziare il percorso di miglioramento trovando i controlli meno integrati in LayoutManager e trovando i modi per suddividerli in oggetti separati. Quindi, ad esempio, anziché assegnare gli oggetti HistoricalReportsContainer e CustomReportsContainer a LayoutManager (che viene quindi utilizzato in RegenerationManager.RegenerateReportMenu) ho spostato il codice sull'evento "Load" di RadListBox. Lì, controllo l'ID del controllo che sta caricando e reagisco di conseguenza. Un primo forte miglioramento, e ha rimosso 2 controlli e un metodo da LayoutManager!

+0

Sembra che tu voglia il modello di Mediatore. È molto simile a quello che stai succedendo qui. Vedi: http://www.dofactory.com/Patterns/PatternMediator.aspx –

+2

Il gestore di layout singleton odora un po '... Sei in grado di elaborare più di una richiesta di pagina contemporaneamente? Sembra che tu non possa al momento ... – Reddog

+0

La tua domanda mi confonde leggermente, ma speriamo di poterlo chiarire. Sto progettando un'applicazione web con utenti registrati. Quando un utente accede, le informazioni vengono estratte da un DB, caricate in Session e quindi le variabili del Gestore layout impostate in base a Session. Onestamente, non mi sento come se il mark-up di Singleton aggiungesse qualcosa di diverso dal "sentirsi bene" nel senso che non volevo avere mai due manager. Non c'è niente nel codice che richiederebbe mai un secondo manager, però. –

risposta

1

Inversion of control è un approccio generale che le persone utilizzano per tali problemi. Le tue dipendenze non dovrebbero essere archiviate nell'unica classe di tipo Jack-Bauer, ma piuttosto essere iniettate, ad esempio tramite costruttore. Dai un'occhiata ai contenitori IoC, come Castle Windsor, Unity, NInject o altri.

+0

MEF è un buon supporto supportato come parte di .NET versioni 4.0 o successive – Mranz

0

Non sono sicuro di come questo interagirebbe con i piani futuri di MVC, ma avevi considerato di rifare i blocchi di LayoutManager in una classe astratta che eredita da Page, quindi che le tue pagine reali ereditassero da quella classe astratta?

Problemi correlati