我的类(class)随着时间的推移稳步增长。它称为LayoutManager

它起初是我跟踪页面上动态创建的控件的一种方式。因此,例如,我有这个:

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);
}

这样,在页面生命周期的开始阶段,将重新创建控件,并将其添加到各自控件的列表中。

不久之后,我发现自己在方法之间传递了“Page”对象。这仅是为了能够访问Page上的控件。我心想-好吧,我已经有一个布局管理器,我将以相同的方式对待静态控件。

因此,我的Page_Init方法现在看起来像这样:
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();
}

我看着那个,说不,不,不。都错了但是,我页面上的控件彼此非常依赖,但彼此之间没有访问权限。这似乎使它变得如此必要。

我认为实践中的一个很好的例子是使用UpdatePanels。因此,例如,将DashboardUpdatePanel提供给LayoutManager。页面上有控件,有条件地,这些控件应导致仪表板的全部内容更新。

现在,在我看来,我相信我有两种选择:
  • 在想要调用UpdatePanel.Update()的对象内部,我通过父对象递归向上,检查类型和ID,直到找到合适的UpdatePanel。
  • 我要求LayoutManager提供UpdatePanel。

  • 显然,在这种情况下,第二个听起来更干净...但是我发现自己在很多情况下都使用相同的逻辑。这导致了一个经理类,如下所示:
    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;
        }
    }
    

    我走的路不好吗?此时通常采取什么步骤?

    EDIT1:我决定通过查找与LayoutManager集成最少的控件并找到将其分解为单独对象的方法来开始改进之路。因此,例如,我没有将HistoricalReportsContainer和CustomReportsContainer对象分配给LayoutManager(然后在RegenerationManager.RegenerateReportMenu中使用),而是将代码移至RadListBox“Load”事件。在那里,我检查正在加载的控件的ID并做出相应的 react 。一项强大的先行改进,并从LayoutManager中删除了2个控件和一个方法!

    最佳答案

    Inversion of control是人们用于解决此类问题的通用方法。您的依赖项不应存储在一个Jack-Bauer类型的类中,而应注入(inject),例如通过构造函数。看一下IoC容器,例如CaSTLe Windsor,Unity,NInject或任何其他容器。

    关于c# - 试图避开单例/神/经理阶层。虽然不确定我应该如何维持功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7935022/

    10-10 22:20