将多个事件合并到一个接口中

用什么替代方法可以避免暴露事件和界面。 我有一个具有确定生命周期的类:创建,修改,...客户端主要是GUIs需要连接到该类的生命周期,所以最简单的方法是公开事件,同时我需要在生命周期中将某些职责转移到课堂外,所以我想出了这个解决方案:

Interface ILifeCycle
{
    void OnCreated(...);
    void OnModified(...);
    // ...
}

classA
{
    private ILifeCycle lifeCycle;
    /// ...
    public event EventHandler Created(object sender, EventArgs args);
    public event EventHandler Modified(object sender, EventArgs args);
    /// ...

    protected void OnCreated()
    {
        lifeCycle.OnCreated(...);
        if(Created!=null)
        Created(this,EventArgs.Empty);
    }

    protected void OnModified()
    {
        lifeCycle.OnModified(...);
        if(Modified!=null)
        Modified(this,EventArgs.Empty);
    }
    /// ...
}

这样做,我可以注入一个实现ILifeCycleLogger ,并将日志记录责任移到它自己的类上,但感觉它会有很多重复。 你会推荐什么干净的替代品来实现这个目标?


通常, InterfaceEvents/Delegates用于两种截然不同的方法。 让我们先描述它们 -

接口接口的主要目的是它为该接口的所有实现强制执行一些功能。 只要你在子类中实现它,你就会覆盖超类的实现。 例如 -

interface IA
{
    void test();
}

class A : IA
{
    public void test(){
    }
}

class B : A 
{
    public void test(){
         //you can only go up by calling base.test(), but cannot move down, because you do not know whether there is an implementation down the tree or not. So you cannot call it.
    }
}

class C : B 
{
    public void test(){
         //you can only go up by calling base.test(), but cannot move down, because you do not know whether there is an implementation down the tree or not. So you cannot call it.
    }
}

正如你所看到的,通过界面,你只能回头看看,但不能期待,并假设将会有更多的实现。

事件 :事件是为了不同的目的而创建的。 我们可以说你想给开发者一些依赖某些活动的设施,并根据这些活动和变化进行一些其他活动,最重要的是他们将在未来实现这一点。 这些事件不会取决于您的实施,他们只会订阅它并根据这些做一些事情。 无论它们是否存在,您自己的实现不会改变,或者您自己的代码的行为不会基于它们而改变。 换句话说,你只能向下移动树。 基类捕获事件,然后将它们传播到树中。

这些是InterfaceEvents的常用用法,它们的用意是这样的。 但是,编码完全不可能完全取决于界面,反之亦然,即完全依赖于事件的代码,但这不是它们的意图。

在这种情况下 :在您的情况下,我认为您正在尝试实现一个不依赖于对方但又订阅事件的模块化系统。 还有其他体系结构和模式,特别是IOC容器将对您非常有用,完全取决于接口,您不需要事件。 一些.net IOC容器是AutoFac,Castle.Windsor,MEF

我自己最喜欢MEF,这是几年前我写的一篇关于MEF的文章,向您展示了如何在容器中注入运行时处理程序 -

http://mahmudulislam.me/2012/04/20/1a-managed-extensibility-framework-introduction/

顺便说一句,文章有点老,我正在更新这一个。

国际奥委会的解决方案 :我正在为MEF提供一个可能的解决方案 -

Interface ILifeCycle
{
  void OnCreated(...);
  void OnModified(...);
  ...
} 

[Export(typeof(ILifeCycle))] //export our classes for injection
classB : ILifeCycle{
   public void OnCreated(...)
   {
       ....
   }

   public void OnModified(...){
   }
}

[Export(typeof(ILifeCycle))] //export our classes for injection
classC : ILifeCycle{
   public void OnCreated(...)
   {
       ....
   }

   public void OnModified(...){
   }
}

classA
{

  [ImportMany] //get all exported classes for injection
  private IList<ILifeCycle> _observers;

  protecetd void OnCreated()
  {
     //use MEF to build composition and then do the following

     foreach(var o in _observers){
        o.OnCreated(...);
     }
  }

  protecetd void OnModified()
  {
     //use MEF to build composition and then do the following

     foreach(var o in _observers){
        o.OnModified(...);
     }
  }
  ...
}

这是一个非常基本的解决方案。 但在你的情况下,你可能想使用异步编程。 因为事件和接口之间有很大的区别。 默认情况下,事件处理程序在单独的线程中调用,因此它不会暂停调用程序,但接口实现将挂起调用程序直到方法结束。 所以确保你使用异步编程来阻止你的主进程。

使用Async和Await进行异步编程(C#和Visual Basic)


我不确定我是否理解你,但我认为你担心实施ILifeCycle不同类型的重复。 所以,你可以利用继承:

abstract class LifeCycleBase
{
  public void OnCreated(...)
  {
        .....
  }
  public void OnModified(...);
  {
        .....
  }
  ...
}

class LifeCycleLoger : LifeCycleBase
{
  public void OnCreated(...)
  {
     ....
     base.OnCreate();
  }
....
}
链接地址: http://www.djcxy.com/p/82263.html

上一篇: Aggregate multiple events into one interface

下一篇: Is this the correct way to implement the factory pattern?