c#中普通class和接口有什么区别

What is the difference between normal class and interface in c#

接口:

public interface IAuthenticationRepository
    {
        Task<IEnumerable<dynamic>> GetMenuItems(string groupIds);
    }

class:

 public class AuthenticationRepository : Base, IAuthenticationRepository
    {
        public AuthenticationRepository(string sqlConnRep) : base(sqlConnRep) { }

        public async Task<IEnumerable<dynamic>> GetMenuItems(string groupIds)
        {
            var menuAndFunctions = $@"select gfm.GroupId, fmm.MenuId, cm.MenuType, cm.MenuName, fmm.FunctionId,cf.FunctionName, 
                                    cf.Description, cf.IsDefault from FunctionMenuMapping fmm 
                                    inner join CoCMenu cm 
                                    on cm.Id = fmm.MenuId 
                                    inner join CoCFunction cf 
                                    on cf.Id = fmm.FunctionId 
                                    inner join GroupFunctionMapping gfm 
                                    on gfm.FunctionId = fmm.FunctionId 
                                    where gfm.GroupId in (" + groupIds + ")";
            return await ExecQueryDynamic<dynamic>(menuAndFunctions);
        }

AuthenticationRepository class 创建实例并将该实例分配给 AuthenticationRepository class 对象

public class AuthenticationLogic : IAuthenticationLogic
    {
            readonly AuthenticationRepository authenticationRepository;
            public AuthenticationLogic( AuthenticationRepository authenticationRepository)
            {
                this.authenticationRepository = new AuthenticationRepository("");
            }
    }

AuthenticationRepository创建实例class并将实例分配给IAuthenticationRepository接口

public class AuthenticationLogic : IAuthenticationLogic
    {
                readonly IAuthenticationRepository IauthenticationRepository;
                public AuthenticationLogic(IAuthenticationRepository IauthenticationRepository)
                {
                    this.IauthenticationRepository = new AuthenticationRepository("");
                }
    }

What is the difference between them? both are doing the same. Is any permanence difference for it? and which one is best approach?

接口是一种契约,它允许您使用抽象而不是具体实现,这意味着您的代码更加解耦,并且将更加可重用和可测试。第二个版本更好,因为传入接口意味着您的代码仅依赖于传入的对象满足该接口提供的 'contract' 这一事实。只要符合要求,构造函数就不必关心实际对象是什么。这允许您在将来更改实现细节和类型,但只要您仍然实现该接口,就不必更改该代码

接口用于在使用 classes 的地方隐藏实现。使用它的 class 只知道接口,不知道它的实现。 这通常与依赖注入结合使用,其中您的所有属性都通过构造函数作为接口传入,并且您可以在应用程序的某一点注册哪个实现应该用于哪个接口。 这允许轻松测试,因为在您的单元测试中,您可以创建 class 的测试实现以传递到 class 您的测试,因此您只测试 class 本身和 none 它的依赖项。这被称为模拟,并且有一些框架可以自动为您创建模拟。