覆盖派生类中的基类方法并触发其事件

时间:2016-09-28 10:58:14

标签: c# event-handling override

我想覆盖派生类中的基类方法,然后在派生类中执行某些操作。因此,可以使用其泛型类型调用基类方法。然后我的目标是触发被覆盖的派生类方法。

我有以下代码:

    public class Service<T> : Interface.IService<T> where T : class
    {

    public virtual event System.EventHandler<EntitySavingEventArgs<T>> BeforeSavingRecord;

    public Service()
    {

    }

    public virtual void OnBeforeSavingRecord(object sender, EntitySavingEventArgs<T> e)
    {

    }

    private readonly DbContext _dbContext;
    public Service(DbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public virtual void Create(T item)
    {
        if (item == null)
            throw new ArgumentNullException("item");

        BeforeSavingRecord?.Invoke(this, new EntitySavingEventArgs<T>() { SavedEntity = item });
        _dbContext.Set(typeof(T)).Add(item);
        _dbContext.SaveChanges();
    }
}

在它的原始课程中,我有类似的东西:

[Service]
public partial class BankBusiness : Service<Bank>, IBankBusiness
{
    public BankBusiness()
        : base(ContainerManager.Container.Resolve<MyContext>())
    {

    }


    public override void OnBeforeSavingRecord(object sender, EntitySavingEventArgs<Bank> e)
    {
        //Do something with entity item before saving
        base.OnBeforeSavingRecord(sender, e);
    }
}

然后在我的控制器中打电话

bankBiz.Create(new Bank() { ... });

我想解雇注册到BeforeSavingRecord事件的bankBiz(derrived class)重写方法(OnBeforeSavingRecord)。

我不知道我的情景是否正确,如果它是正确的,我可以解雇它。

如果不正确我应该做什么。

2 个答案:

答案 0 :(得分:0)

我在基类中实现了类似的模式,我这样做了:

<强>基

public virtual void OnBeforeSavingRecord(object sender, EntitySavingEventArgs<T> e)
{    }

在派生类中我完全使用了你的调用:

<强> Derivied:

public override void OnBeforeSavingRecord(object sender, EntitySavingEventArgs<Bank> e)
{
    //Do something with entity item before saving
    base.OnBeforeSavingRecord(sender, e);
}

要在我的情况下触发事件,只需调用

即可
OnBeforeSavingRecord(this, new EntitySavingEventArgs<T>() { SavedEntity = item });

整个场景对我有用。

编辑:

如果从派生类的实例调用它,则调用OnBeforeSavingRecord将执行派生类的overriden方法中的代码!

如果我理解正确,你想在方法Create中触发事件,但希望执行派生类的事件代码。如果事件被覆盖就像你的情况一样。您可以使用这个简单的控制台应用程序对其进行测试:(只需复制粘贴并运行)

public class Service 
{
    public virtual event System.EventHandler<EventArgs> BeforeSavingRecord;

    public virtual void OnBeforeSavingRecord(object sender, EventArgs e)
    {
        Console.WriteLine("Base: OnBeforeSavingRecord method call");
    }

    public virtual void Create(object item)
    {
        Console.WriteLine("Base: Create method call");
        // this will call the method of the derived class! if you call it from an instance of the derived class
        OnBeforeSavingRecord(this, new EventArgs());
    }
}

public partial class BankBusiness : Service
{
    public override void OnBeforeSavingRecord(object sender, EventArgs e)
    {
        //Do something with entity item before saving
        Console.WriteLine("Derived Class OnBeforeSavingRecord CALL");

        base.OnBeforeSavingRecord(sender, e);                
    }
}

static void Main(string[] args)
{        
    BankBusiness bankBiz = new BankBusiness();

    bankBiz.Create(new object());

    Console.ReadKey();
}

答案 1 :(得分:0)

@Mong Zhu您的解决方案有效但不适合我的方案。我提出了以下解决方案

public class Service<T> : Interface.IService<T> where T : class
{

    Interface.IService<T> implementation;

    public virtual event System.EventHandler<EntitySavingEventArgs<T>> BeforeSavingRecord;

    public virtual event System.EventHandler<EntitySavingEventArgs<T>> SavingRecord;

    public virtual event System.EventHandler<EntitySavingEventArgs<T>> RecordSaved;

    public void PopulateEvents(Interface.IService<T> _implementation)
    {
        implementation = _implementation;

        implementation.BeforeSavingRecord += new System.EventHandler<EntitySavingEventArgs<T>>(this.OnBeforeSavingRecord);
        implementation.SavingRecord += new System.EventHandler<EntitySavingEventArgs<T>>(this.OnSavingRecord);
        implementation.RecordSaved += new System.EventHandler<EntitySavingEventArgs<T>>(this.OnRecordSaved);
    }

    public virtual void OnBeforeSavingRecord(object sender, EntitySavingEventArgs<T> e)
    {

    }

    public virtual void OnSavingRecord(object sender, EntitySavingEventArgs<T> e)
    {

    }
    public virtual void OnRecordSaved(object sender, EntitySavingEventArgs<T> e)
    {

    }

    private readonly DbContext _dbContext;
    public Service(DbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public virtual void Create(T item)
    {

        if (item == null)
            throw new ArgumentNullException("item");

        BeforeSavingRecord?.Invoke(this, new EntitySavingEventArgs<T>() { SavedEntity = item });
        _dbContext.Set(typeof(T)).Add(item);
        SavingRecord?.Invoke(this, new EntitySavingEventArgs<T>() { SavedEntity = item });
        _dbContext.SaveChanges();
        RecordSaved?.Invoke(this, new EntitySavingEventArgs<T>() { SavedEntity = item });

    }
}

和派生类:

    [Service]
public partial class BankBusiness : Service<Bank>, IBankBusiness
{
    public BankBusiness()
        : base(ContainerManager.Container.Resolve<MyContext>())
    {
        base.PopulateEvents(this);
    }


    public override void OnBeforeSavingRecord(object sender, EntitySavingEventArgs<Bank> e)
    {

        base.OnBeforeSavingRecord(sender, e);
    }
}

点是

base.PopulateEvents(this);