繁体   English   中英

C#中如何使用接口默认实现

[英]How to use interface default implementation in C#

我有继承自基 class 的类。

public class Car : BaseEntity
{
    public string Name { get; private set; }

    public Car(string name)
    {
        Name = name;
        // update method goes here
    }
}


public abstract class BaseEntity
{
    public Guid Id { get; } = Guid.NewGuid();
}

我想要一个接口或其他东西,我可以在其中审核此实体更改。 我制作了一个界面并添加了如下默认实现:

public interface IAuditable
{
    // userNameProvider goes here
    DateTime CreatedTime { get; set; }
    Guid CreatedBy { get; set; }

    void Audit()
    {
        CreatedTime = DateTime.UtcNow;
        // CreatedBy =  userNameProvider.GetUserId();
    }
}

但问题是我需要将我的 Car 转换为该接口才能调用 Audit 方法。 因为它不是强制在 Car class 中实现的,所以我想我可以忘记它或其他东西。 我想要一个解决方案,只需调用一个方法就可以对从此接口派生的所有实体进行重用,并且不要害怕忘记 Audit 方法。 我非常感谢你的建议。 谢谢

示例代码现在可以正常工作但需要简化:

var car = new Car("bmw");

Console.WriteLine(car.CreatedTime);

public class Car : BaseEntity, IAuditable
{
    public string Name { get; private set; }
    public DateTime CreatedTime { get; set; }

    public Car(string name)
    {
        Name = name;
        (this as IAuditable).Audit();
        // update method goes here
    }
}

上面说了我的所作所为和期待,大家看看吧:)

您可以覆盖 DbContext SaveChangesAsync方法

public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
{
    foreach (var e in ChangeTracker.Entries()
                                   .Where(i => i.State == EntityState.Added
                                            || i.State == EntityState.Modified)
                                   .Select(i => i.Entity)
                                   .OfType<IAuditable>())
    {
        e.Audit();
    }

    return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}

这将确保通过您的数据库上下文修改的所有IAuditable实体都将调用其Audit方法。

您可以像这样使用外部处理 class:

public class Car : BaseEntity, IAuditable
{
    public string Name { get; private set; }

    public Car(string name)
    {
        Name = name;
        Auditor.Audit(this);
    }
}

public static class Auditor
{
    public static void Audit(IAuditable entity)
    {
        entity.Audit();
    }
}

如果不在具体class中实现默认接口方法,则不能直接使用默认接口方法。但是,您可以添加扩展方法,使调用默认接口方法更容易:

public static class AuditableExtensions
{
    public static void Audit(this IAuditable auditable)
    {
        auditable.Audit();
    }
}

// usage:

Car car = new Car();
car.Audit();

// or

public class Car : BaseEntity, IAuditable
{
    public Car()
    {
        this.Audit();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM