使用构造函数将委托方法从派生类注入到基类

时间:2013-11-10 01:20:21

标签: c# oop dependency-injection delegates design-principles

今天我重新考虑了我创建的库,并在多个平台上共享代码(WPF,WF,WP7,WP8)。

我的想法是我使用继承来扩展类中的功能。顶级类向客户端公开了几个事件,这个事件是在一个方法中引发的,该方法使用接受一些参数的构造函数传递给基类。

该对象基本上用作单身。

示例:

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类执行,这样我基本上可以为客户提供信息。

2 个答案:

答案 0 :(得分:3)

我建议改变的主要是:

  • 使用相应的虚拟方法替换AnotherDelegateMethodAnotherOneDelegateMethod传递(然后从父类调用)。

至于另一件事,这完全取决于你的班级想要实施的逻辑。 可能,可能需要一些更多脱钩

  • 新的AnotherRepository(ADelegateMethod)。那个真的是一个棘手的问题如何正确地完成所有事情 - 需要更多关于一般逻辑的信息,因为可能采用不同的方法

    • 您也可以将其替换为虚拟方法,例如ADelegateMethod - 与上面提到的相同,但新的AnotherRepository为protected virtual ISomeRepositoryInterface CreateRepositoryInstance()(例如);
    • 你可以将依赖注入用于一些外部类,这些外部类会使用你的处理程序来传递存储库,实际上就像工具或另一个存储库一样(但是,一切都依赖于关于一般逻辑);

    • 自定义处理程序的一种方法是将基本类设为 Generic ,并通过提供一些具体类来继承子类,这些逻辑与之完全相关。继承者,但主要只在父类中使用。

关于活动:

  • 我建议您阅读类似this的内容,并且通常熟悉 Rx(反应性扩展) - 它们很现代且很棒(您可以考虑使用代替它们事件在许多情况下(如果不在此处理程序类中,则在其他情况下))。 (但是,目前我无法看到你真正需要在课堂上使用事件的情况。)

另外,至于@ durilka的答案(然而,相信他从俄语中考虑他的绰号“骗子”真的很有趣,他):他正确地提到了(在我进入之前)关于:

  • 删除嵌套类并替换为静态构造函数(如果在基类中)。但必须仔细重新考虑(特别是,如果你真的广泛使用多线程)。

答案 1 :(得分:0)

摆脱嵌套。声明默认构造函数private。在返回现有实例或创建新实例(又名return instance ?? instance = new SomeHandler())时,在Instance属性中使用它。并开始考虑从代表转移到某种消息总线。