代码之家  ›  专栏  ›  技术社区  ›  unos baghaii

重写派生类中的基类方法并激发其事件

  •  0
  • unos baghaii  · 技术社区  · 10 年前

    我想重写派生类中的基类方法,然后在派生类中执行一些操作。因此,基类方法用其泛型类型调用。然后,我打算激发被重写的派生类方法。

    我有以下代码:

        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类)重写方法(OnBeforeSavingRecord)。

    我不知道我的设想是否正确,如果是正确的,我如何才能开火。

    如果不正确,我应该怎么做。

    2 回复  |  直到 10 年前
        1
  •  0
  •   Mong Zhu Bart de Boer    10 年前

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

    底座:

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

    在派生类中,我正好有您使用的调用:

    派生:

    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 如果从派生类的实例调用它,将在派生类的重写方法中执行代码!

    如果我没弄错的话,你想在方法中触发事件 Create 但希望执行派生类的事件代码。如果事件像您的情况一样被重写,则会发生这种情况。您可以使用这个简单的Console应用程序测试它:(只需复制粘贴并运行)

    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();
    }
    
        2
  •  0
  •   unos baghaii    10 年前

    @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);
    
    推荐文章