C# 如何在点击事件中批量调用多个ActiveDirectory方法以精简代码?
优化方案
当前写法的核心问题如下:
- 重复传递
searchUsernametxt.Text参数,冗余度高 - 每次新增AD属性查询都要新增一行调用语句,代码会越来越臃肿
- 多数AD查询方法的底层逻辑都是读取域用户属性,多次调用会重复发起AD查询请求,性能损耗大
- UI交互、参数校验、业务查询逻辑耦合在同一个事件方法里,后续维护成本高
方案1:封装统一批量查询方法(性价比最高,改造成本低)
步骤1:定义AD用户信息存储实体
public class AdUserInfo { public string SamAccountName { get; set; } public bool IsUserEnabled { get; set; } public Guid ObjectGuid { get; set; } public string Sid { get; set; } public DateTime? PasswordExpirationDate { get; set; } public bool IsLockedOut { get; set; } public string EmployeeId { get; set; } public string CusAtt1 { get; set; } public string CusAtt2 { get; set; } public string CusAtt3 { get; set; } public string CusAtt4 { get; set; } }
步骤2:在ActiveDirectory工具类中新增批量查询方法
只需要发起一次AD查询,一次性读取所有需要的用户属性,返回上面定义的实体对象即可,原有单个查询方法可以保留兼容其他场景调用。
public static AdUserInfo GetUserAllInfo(string userName) { // 原有判断用户存在的逻辑可以合并到这里,不存在直接返回null即可 if (!DoesUserExist(userName)) return null; // 一次性查询所有需要的属性,填充AdUserInfo对象返回 return new AdUserInfo { SamAccountName = // 读取对应AD属性赋值 // 其他属性依次赋值即可 }; }
步骤3:改造点击事件代码
private void metroButton1_Click(object sender, EventArgs e) { // 控件状态操作封装成单独方法 DisableAllInputTextBox(); // 参数校验 if (string.IsNullOrWhiteSpace(searchUsernametxt.Text)) { MessageBox.Show("Domain or Username has not been completed, Please try again!", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 一次性查询所有用户信息 var userInfo = ActiveDirectory.GetUserAllInfo(searchUsernametxt.Text); if (userInfo == null) return; // 统一给控件赋值 samAccountNametxt.Text = userInfo.SamAccountName; userenabledtxt.Text = userInfo.IsUserEnabled.ToString(); GUIDtxt.Text = userInfo.ObjectGuid.ToString(); SIDtxt.Text = userInfo.Sid; passlstsettxt.Text = userInfo.PasswordExpirationDate?.ToString("yyyy-MM-dd HH:mm") ?? "无"; metroCheckBox1.Checked = userInfo.IsLockedOut; employeeidtxt.Text = userInfo.EmployeeId; cusatt1txt.Text = userInfo.CusAtt1; cusatt2.Text = userInfo.CusAtt2; cusatt3.Text = userInfo.CusAtt3; cusatt4.Text = userInfo.CusAtt4; } private void DisableAllInputTextBox() { foreach (MetroFramework.Controls.MetroTextBox item in groupBox1.Controls .OfType<MetroFramework.Controls.MetroTextBox>()) { item.Enabled = false; } }
如果后续需要新增属性查询,只需要:
- 在AdUserInfo实体中新增对应字段
- 在GetUserAllInfo方法中补充属性读取逻辑
- 最后在赋值部分加一行控件赋值即可,不需要额外新增AD调用方法
方案2:进一步简化赋值逻辑(适合后续会新增大量属性的场景)
可以提前配置属性和控件的映射关系,用遍历自动赋值,后续新增属性只需要加一行映射配置即可,不需要修改赋值逻辑:
// 提前定义映射关系 private readonly Dictionary<Func<AdUserInfo, object>, Control> _adPropertyControlMap = new() { {u => u.SamAccountName, samAccountNametxt}, {u => u.IsUserEnabled, userenabledtxt}, {u => u.ObjectGuid, GUIDtxt}, // 其他映射依次添加即可 }; // 赋值时直接遍历 foreach (var map in _adPropertyControlMap) { var value = map.Key(userInfo)?.ToString() ?? string.Empty; if (map.Value is CheckBox chk) chk.Checked = Convert.ToBoolean(value); else map.Value.Text = value; }
内容的提问来源于stack exchange,提问作者Tom Dobing
相关产品推荐
相关产品推荐

