今天,我重构了一个我创建的库,并在多个平台(WPF,WF,WP7,WP8)之间共享代码。
这个想法是我使用继承来扩展类中的功能。top类向客户端公开几个事件,此事件在方法中引发,该方法使用接受某些参数的构造函数向下传递给基类。
该对象基本上用作单例。
例:
public class SomeHandler : BaseHandler
{
public event EventHandler<Custom1EventArgs> RequestCompleted = delegate {};
public event EventHandler<Custom2EventArgs> ActionHandled = delegate { };
protected SomeHandler()
: base(new CustomUtil(), new CustomRepository(),
new AnotherRepository(ADelegateMethod),
AnotherDelegateMethod, AnotherOneDelegateMethod) {}
#region [ Singleton ]
public static SomeHandler Instance
{ get { return Nested.instance;} }
class Nested
{
internal static readonly SomeHandler instance = new SomeHandler ();
}
#endregion
private static void ADelegateMethod(Custom1EventArgs args)
{
Instance.RequestCompleted (Instance, args);
}
private static void AnotherDelegateMethod(
Custom2EventArgs args, CustomObject result)
{
// Do stuff....
AnotherCustomObject cusObj = new AnotherCustomObject(args);
Instance.ActionHandled (Instance, cusObj);
}
private static void AnotherOneDelegateMethod(CustomObject result)
{
// Do some stuff...
}
}
好的,如果您注意到了,我需要将委托方法标记为静态,因为注入发生在构造函数参数中。但这迫使我使事件静态。为了解决方法,我依赖于这样一个事实,即用户始终使用我的对象的Instance
单例实例,尽管如果需要,可以初始化该对象,sealed
目前不是一个选项,因为它也用作特定特殊实现中另一个类的基本继承类。
将事件更改为静态不好吗?这对我来说似乎不合适,你怎么看?这个设计能变得更好吗?
实际上,我将委托用作代码的一部分,这些代码需要在特定时间内从其他对象new AnotherRepository(ADelegateMethod)
或BaseHandler
类执行,因此我基本上可以为客户端提供信息。
我建议更改的主要内容是:
- 将
AnotherDelegateMethod
和AnotherOneDelegateMethod
传递(然后从父类调用)替换为相应的虚拟方法。
至于另一件事,这一切都取决于你的类应该实现的逻辑。可能需要进行更多的解耦。
-
new AnotherRepository(ADelegateMethod).这确实是一个棘手的问题,如何正确地做所有事情 - 需要更多关于一般逻辑的信息,因为可能有不同的方法:
- 您也可以将其替换为虚拟方法,例如ADelegateMethod - 与上面提到的两个方法相同,但新的AnotherRepository作为
protected virtual ISomeRepositoryInterface CreateRepositoryInstance()
(例如); -
您可以将依赖注入到一些外部类中,这些类将使用您的处理程序来传递存储库,实际上与工具或其他存储库相同(但是,同样,一切都取决于一般逻辑);
-
自定义处理程序的方法之一是将基本类设置为泛型,并通过提供一些具体的类来继承子类,该逻辑与继承器完全相关,但主要仅在父类中使用。
- 您也可以将其替换为虚拟方法,例如ADelegateMethod - 与上面提到的两个方法相同,但新的AnotherRepository作为
关于活动:
- 我建议您阅读类似内容并大致熟悉 Rx(响应式扩展)——它们既现代又很棒(在许多情况下,您可以考虑使用它们而不是事件(如果不在此处理程序类中,则在其他一些情况下))。(但是,目前我看不到您真正需要在课堂上使用事件的情况)。
另外,至于@durilka的回答(但是,考虑到他来自俄语的昵称"骗子",相信他真的很有趣,呵呵):他正确地提到了(在我进入之前)关于:
- 删除嵌套类并替换为静态构造函数(如果在基类中)。但这必须仔细重新考虑(特别是,如果你真的广泛使用多线程)。
摆脱嵌套。声明默认构造函数私有。在返回现有实例或创建新实例(也称为 return instance ?? instance = new SomeHandler()
)时在实例属性中使用它。并开始考虑从代表转移到某种消息总线。