如何避免ef上面业务逻辑类中出现重复代码?

yol*_*ora 5 c# abstract-class entity-framework interface

我的应用程序中有一个业务逻辑层,它封装了 EF 的工作。

我有大量的服务类提供对数据库的访问并具有类似的方法,因此我想避免重复。

第一个例子:

xDatax类是EF 生成的类的 DTO 类。

public class UserService
{
    public static bool Any()
    {
         // default logic
    }
    public static List<UserData> Filter(Expression<Func<UserData, bool>> predicate)
    {
         // default logic
    }
    public static long CreateOrUpdate(UserData userData)
    {
        // default method with custom logic
    }
    public static bool AuthorizeUser(UserData data)
    {
        // custom method
    }
}

public class BookService
{
    public static bool Any()
    {
         // default logic
    }
    public static List<BookData> Filter(Expression<Func<BookData, bool>> predicate)
    {
         // default logic
    }
    public static long CreateOrUpdate(BookData userData)
    {
         // default logic
    }
}
Run Code Online (Sandbox Code Playgroud)

主要问题:大多数方法中的逻辑重复,仅类型不同。

第二个例子:

我创建了一个包含所有共享逻辑的通用服务。

public abstract class Service<TEntity,TData> where TEntity : class
                                             where TData : IDataObject<TEntity>, new()
{
    public static bool Any()
    {
         // default logic
    }

    public static List<TData> Filter(Expression<Func<TData, bool>> predicate)
    {
         // default logic
    }

    public static long CreateOrUpdate(TData data)
    {
         // default logic
    }
 }
Run Code Online (Sandbox Code Playgroud)

所以我的定制服务现在看起来像这样:

public class UserService : Service<user, UserData>
{
     public new static long CreateOrUpdate(UserData userData)
     {
          // overriden custom logic
     }

     public static AuthorizeUser(UserData userData)
     {
          // custom method
     }

}


public class BookService : Service<book, BookData>
{
}
Run Code Online (Sandbox Code Playgroud)

现在一切看起来都很好,但之后我所有使用业务逻辑层的项目都需要对数据层的引用,因为它们不知道数据类型,例如当我尝试使用时,BookService.Any();我收到一个错误,即书籍类未定义,缺少引用。

我不想在我的所有客户端项目中添加对数据层的引用,那么如何处理呢?

Mar*_*und 0

您可以创建一个单独的接口,就像类型实现的IService<TData>那样Service<TEntity,TData>。然后,您可以利用依赖注入并仅提供具体BookService类型作为IService<BookData>. 这样,您根本不必引用Book顶层中的具体实体,并且可以简单地使用BookData.