Note that there are some explanatory texts on larger screens.

plurals
  1. POTrying to shy away from a singleton/god/manager class. Not sure how I am supposed to sustain functionality, though
    primarykey
    data
    text
    <p>I have a class which has been steadily growing over time. It's called <code>LayoutManager</code>. </p> <p>It started as a way for me to keep track of which dynamically created controls were on my page. So, for instance, I have this:</p> <pre><code>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); } </code></pre> <p>In this way, during the beginning stages of the Page Lifecycle, controls would be re-created and they would add themselves to their respective control's list. </p> <p>A while later I found myself passing the 'Page' object between methods. This was for the sole purpose of being able to access controls found on Page. I thought to myself -- well, I already have a Layout Manager, I'll just treat the static controls in the same way.</p> <p>As such, my Page_Init method now looks like this mess:</p> <pre><code>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(); } </code></pre> <p>I'm looking at that and saying no, no, no. That is all wrong. Yet, there are controls on my page which are very dependent on each other, but do not have access to each other. This is what seems to make this so necessary.</p> <p>I think a good example of this in practice would be using UpdatePanels. So, for instance, <code>DashboardUpdatePanel</code> is being given to the LayoutManager. There are controls on the page which, conditionally, should cause the entire contents of the dashboard to update.</p> <p>Now, in my eyes, I believe I have two options:</p> <ol> <li>Inside the object wanting to call UpdatePanel.Update(), I recurse up through parent objects, checking type and ID until I find the appropriate UpdatePanel.</li> <li>I ask LayoutManager for the UpdatePanel.</li> </ol> <p>Clearly the second one sounds cleaner in this scenario... but I find myself using that same logic in many instances. This has resulted in a manager class which looks like this:</p> <pre><code>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&lt;CormantRadDock&gt; _registeredDocks; private IList&lt;CormantRadDockZone&gt; _registeredDockZones; private IList&lt;CormantRadPane&gt; _registeredPanes; private IList&lt;CormantRadSplitter&gt; _registeredSplitters; private IList&lt;CormantRadSplitBar&gt; _registeredSplitBars; private Dictionary&lt;string, StyledUpdatePanel&gt; _registeredUpdatePanels; private IList&lt;CormantRadPageView&gt; _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&lt;CormantRadDock&gt; RegisteredDocks { get { if (Equals(_registeredDocks, null)) { _registeredDocks = new List&lt;CormantRadDock&gt;(); } return _registeredDocks; } } public IList&lt;CormantRadDockZone&gt; RegisteredDockZones { get { if (Equals(_registeredDockZones, null)) { _registeredDockZones = new List&lt;CormantRadDockZone&gt;(); } return _registeredDockZones; } } public IList&lt;CormantRadPane&gt; RegisteredPanes { get { if (Equals(_registeredPanes, null)) { _registeredPanes = new List&lt;CormantRadPane&gt;(); } return _registeredPanes; } } public IList&lt;CormantRadSplitter&gt; RegisteredSplitters { get { if (Equals(_registeredSplitters, null)) { _registeredSplitters = new List&lt;CormantRadSplitter&gt;(); } return _registeredSplitters; } } public IList&lt;CormantRadSplitBar&gt; RegisteredSplitBars { get { if (Equals(_registeredSplitBars, null)) { _registeredSplitBars = new List&lt;CormantRadSplitBar&gt;(); } return _registeredSplitBars; } } public Dictionary&lt;string, StyledUpdatePanel&gt; RegisteredUpdatePanels { get { if( Equals( _registeredUpdatePanels, null)) { _registeredUpdatePanels = new Dictionary&lt;string, StyledUpdatePanel&gt;(); } return _registeredUpdatePanels; } } public IList&lt;CormantRadPageView&gt; RegisteredPageViews { get { if (Equals(_registeredPageViews, null)) { _registeredPageViews = new List&lt;CormantRadPageView&gt;(); } return _registeredPageViews; } } public StyledUpdatePanel GetBaseUpdatePanel() { string key = MultiPage.PageViews.Cast&lt;CormantRadPageView&gt;().Where(pageView =&gt; pageView.Selected).First().ID; return RegisteredUpdatePanels[key]; } public CormantRadDockZone GetDockZoneByID(string dockZoneID) { CormantRadDockZone dockZone = RegisteredDockZones.Where(registeredZone =&gt; 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 =&gt; 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 =&gt; 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; } } </code></pre> <p>Am I on a bad path? What steps are generally taken at this point?</p> <p>EDIT1: I have decided to start down the path of improvement by finding the controls which are least-integrated into LayoutManager and finding ways of breaking them down into separate objects. So, for instance, instead of assigning the HistoricalReportsContainer and CustomReportsContainer objects to LayoutManager (which is then used in RegenerationManager.RegenerateReportMenu) I have moved the code to RadListBox "Load" event. There, I check the ID of the control which is loading and react accordingly. A strong first improvement, and has removed 2 controls and a method from LayoutManager!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload