如何避免ef以上的业务逻辑类中的重复代码?

时间:2019-01-24 08:23:04

标签: c# entity-framework interface abstract-class

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

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

第一个示例:

xData类是EF生成的x类的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
    }
}

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

第二个示例:

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

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
    }
 }

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

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>
{
}

现在一切看起来都很好,但是在那之后,我所有与业务逻辑层一起工作的项目都需要引用数据层,因为它们不了解数据类型,例如当我尝试使用BookService.Any();时,我收到一个错误,指出书类是未定义的,缺少参考。

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

1 个答案:

答案 0 :(得分:0)

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