interface IDynamicControl { string Id { get; set; } string Label { get; set; } string Value { get; set; } } interface IDynamicList : IDynamicControl { IList ListItems { get; set; } }
我有一个返回IDynamicControl的ControlResolver类 – 为了我的目的,我有ASP.NET TextBoxes,CheckBoxes和DropDownLists的包装类,它们实现IDynamicControl(DropDown实现IDynamicList).要点是我可以给解析器一个控件的名称,例如“TextBox”,它会给我一个IDynamicControl,它是一个修改过的ASP.NET文本框.
这很有效,但问题是DropDownList.也许我有一个大脑放屁,但我遇到的问题是,当控件是下拉列表时,我必须对IDynamicList进行显式转换(因为解析器返回IDynamicControl)所以我可以添加项目到它用于显示.这通常不是问题,但动态控制的目的是我可以在外部存储字段类型并将其读入,因此我必须做一些丑陋的事情:
string controlType = SomeService.GetControlType(); if (controlType == "dropdown") { var control = (IDynamicList)ControlResolver.ResolveControl(controlType); // set up list items } else { var control = ControlResolver.ResolveControl(controlType); // stuff with normal controls }
但这看起来相当丑陋.我可以在基类中包含ListItems属性,只是在不使用它的类中抛出NotImplemented,但这违反了ISP,甚至比if语句更有气味.总之,我想让我的解析器返回一种控件,所以我不需要使用不同的Resolve()方法,但是在使用代码时,如果只有控件那么我需要做额外的工作是下拉列表.
除非我弄错了或者我忘记了一些基本的东西,有没有更好的解决方案来做这个或我应该只使用if语句?我不能使用基类,因为我的所有“动态”类都继承自基本ASP.NET UI类.
解决方法
var control = ControlResolver.ResolveControl(controlType); // ... do common logic for all controls var list = control as IDynamicList; if (list != null) { // .. do additional logic for list controls }
您调用ControlResolver.ResolveControl的代码实际上不应该知道“下拉”控件的任何特殊规则.它真正需要知道的是解析的控件是否实现了IDynamicList接口.
当然,您仍然需要一些条件逻辑,但至少条件是基于您的代码已经知道的众所周知的接口而不是底层的实现细节.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。