如何在BasePage中创建CalendarHelper单实例,避免循环实例化且供子类使用?
解决无限循环并实现单实例CalendarHelper方案
问题根源
当前代码中CalendarHelper继承BasePage,而BasePage构造函数又实例化CalendarHelper,导致构造函数无限递归调用,触发栈溢出。
解决方案
1. 重构CalendarHelper:用组合替代继承
去掉CalendarHelper对BasePage的继承,改为接收BasePage实例作为依赖,这样既能调用BasePage的方法,又打破循环依赖。
修改后的CalendarHelper代码:
class CalendarHelper { private readonly BasePage _basePage; // 接收BasePage实例,通过它调用BasePage的方法和Driver public CalendarHelper(BasePage basePage) { _basePage = basePage; } // 示例:调用BasePage的Driver或其他方法 public void SelectDate(string date) { // 使用_basePage.Driver操作日历元素 // 或者调用BasePage中的公共方法,比如_basePage.WaitForElementVisible() } }
2. 在BasePage中实现CalendarHelper的单实例
通过静态字段确保CalendarHelper是单实例,同时在BasePage构造函数中仅初始化一次:
修改后的BasePage代码:
class BasePage { public IWebDriver Driver; // 静态字段存储单实例 private static CalendarHelper _calendarInstance; // 公共属性供子类访问 public CalendarHelper Calendar => _calendarInstance; public BasePage(IWebDriver driver) { Driver = driver; // 仅当单实例未初始化时创建 if (_calendarInstance == null) { _calendarInstance = new CalendarHelper(this); } } // 示例:BasePage中的公共方法,供CalendarHelper调用 public void WaitForElementVisible(By locator) { // 实现等待逻辑 } }
3. 子类使用方式
所有继承BasePage的页模型可以直接通过Calendar属性访问单实例的CalendarHelper:
class HomePage : BasePage { public HomePage(IWebDriver driver) : base(driver) { } public void SetCheckInDate() { // 调用单实例的CalendarHelper方法 Calendar.SelectDate("2024-10-01"); } }
关键说明
- 组合替代继承:避免了循环依赖的问题,同时让
CalendarHelper能通过BasePage实例调用其所有公共方法和属性。 - 静态单实例:确保所有
BasePage子类共享同一个CalendarHelper实例,符合需求。 - 线程安全(可选):如果是多线程测试场景,可以在初始化单实例时添加线程锁:
private static readonly object _lockObj = new object(); public BasePage(IWebDriver driver) { Driver = driver; lock (_lockObj) { if (_calendarInstance == null) { _calendarInstance = new CalendarHelper(this); } } }
内容的提问来源于stack exchange,提问作者automationTester9491
相关产品推荐
相关产品推荐

