假设有一个通用的用户页面控件,它提供操作并在大多数应用程序页面上重用。常见的操作,如:保存、取消、重置、发送等。目前大约有 10 个。
特定的动作状态通常但不一定取决于页面上显示的实体及其状态。在创建新实体实例的情况下,可以显示和启用保存和取消。但是,当我们要编辑现有的Save、Cancel和Reset时,可能会主动显示操作。
动作公共控件与页面之间的通信
由于这个带有动作的通用控件是状态解耦的,并且不知道页面的上下文(或实体类型及其状态),我决定给它注入钩子,这样页面就可以提供通用控件将使用的动作按钮获取器.
我没有定义事件和委托,而是决定做一个通常相同场景的简化类型。我刚刚使用了Func<bool>
属性,但它们可以很容易地转换为事件/代表。这仍然是它们目前的定义方式(发送操作的示例):
private Func<bool> DefaultState = () => false;
private Func<bool> isSendVisible;
public Func<bool> IsSendVisible
{
private get { return isSendVisible ?? DefaultState; }
set { isSendVisible = value; }
}
private Func<bool> isSendEnabled;
public Func<bool> IsSendEnabled
{
private get { return isSendEnabled ?? DefaultState; }
set { isSendEnabled = value; }
}
问题是我在接口中定义了这几个属性:
public interface ISendActionProvider
{
Func<bool> IsSendVisible { set; }
Func<bool> IsSendEnabled { set; }
}
我的普通控件实现了这个接口(以及其他动作的接口),但是其他控件(甚至页面本身)可以提供相同的接口,因此可以在多个地方显示相同的按钮,并重用相同的动作状态机制。页面只需在初始化期间将其 getter 绑定到提供程序,以便操作提供程序可以适当地设置操作的状态。
问题
问题是,对于每一个新动作,我都必须为其添加相同的接口和实现,这会导致相当多的半重复代码。
如果我可以有一个接口并为每个操作实现它,那就太好了,这样它就可以由一个类(操作提供程序类 - 在我的例子中提供这些操作的公共控件)实现多次。这可以在 C# 中工作的唯一方法是拥有一个通用接口,然后根据需要提供尽可能多的实现。但是我没有区分泛型类型来提供多个泛型接口实现。
public interface IActionProvider // multiple inplementations?
{
Func<bool> IsActionVisible { set; }
Func<bool> IsActionEnabled { set; }
}
实现的工作方式(如上所示)是每个动作都定义了其默认行为,但特定页面可以通过为特定动作提供自己的 getter 来覆盖它以提供它们的状态。
我必须整合我的代码有哪些可能性?
我想要的是某种可以在初始化绑定期间调用的通用属性提供程序:
(provider as IActionProvider<TSend>).IsActionVisible<TSend> = this.IsSendVisible;
但如前所述,我没有如此区分的泛型类型。