让一些私有方法暴露出IQueryable <t>以及暴露IEnumerable <t>的所有公共方法是否有什么问题?</t> </t>

时间:2010-05-25 20:36:51

标签: c# .net

我想知道是否有更好的方法来解决这个问题。目标是重用代码。

假设我有一个Linq-To-SQL datacontext,我编写了一个“存储库样式”类,它包含了我需要的许多方法并公开了IQueryables。 (到目前为止,没问题)。

现在,我正在构建一个位于此存储库顶部的服务层,许多服务方法将使用存储库方法为1&lt; - &gt; 1,但有些服务方法不会。我认为代码示例会比单词更好地说明这一点。

public class ServiceLayer 
{
    MyClassDataContext context;
    IMyRepository rpo;

    public ServiceLayer(MyClassDataContext ctx) 
    { 
        context = ctx; 
        rpo = new MyRepository(context);   
    }

    private IQueryable<MyClass> ReadAllMyClass()
    {
        // pretend there is some complex business logic here
        // and maybe some filtering of the current users access to "all"
        // that I don't want to repeat in all of the public methods that access
        // MyClass objects.
        return rpo.ReadAllMyClass();
    }

    public IEnumerable<MyClass> GetAllMyClass()
    {
        // call private IQueryable so we can do attional "in-database" processing
        return this.ReadAllMyClass();
    }

    public IEnumerable<MyClass> GetActiveMyClass()
    {
        // call private IQueryable so we can do attional "in-database" processing
        // in this case a .Where() clause
        return this.ReadAllMyClass().Where(mc => mc.IsActive.Equals(true));
    }

    #region "Something my class MAY need to do in the future"
    private IQueryable<MyOtherTable> ReadAllMyOtherTable()
    {
        // there could be additional constrains which define
        // "all" for the current user
        return context.MyOtherTable;
    }

    public IEnumerable<MyOtherTable> GetAllMyOtherTable()
    {
        return this.ReadAllMyOtherTable();
    }

    public IEnumerable<MyOtherTable> GetInactiveOtherTable()
    {
        return this.ReadAllMyOtherTable.Where(ot => ot.IsActive.Equals(false));
    }
    #endregion

}

这个特例不是最好的例子,因为我可以直接在GetActiveMyClass方法中调用存储库,但是我们假设我的私有IQueryable做了一些我不想在两者中复制的额外处理和业务逻辑。我的公共方法。

这是一种攻击这样的问题的坏方法吗?我不认为它是如此复杂以至于它确实需要建立第三类来存放在存储库和服务类之间,但我想得到你的想法。

为了争论,我们假设另外两件事。

  1. 此服务将通过WCF公开,并且每个公共IEnumerable方法将在每个返回的集合上调用.Select(m => m.ToViewModel()),并将其转换为POCO以进行序列化。
  2. 该服务最终需要公开一些不会被包装到存储库中的context.SomeOtherTable

1 个答案:

答案 0 :(得分:5)

我认为这是一个很好的模型,因为你可以创建基本的IQueryable私有函数,可以被公开公开的函数使用。这样,您的公共方法不需要重新创建IQueryable方法执行的许多常用功能,并且可以根据需要进行扩展,并在仍然公开隐藏该功能的同时推迟执行。

一个例子,比如如何从一些表中获取X,这可能会占用你原始形式中不需要的大量逻辑。然后,您将其作为私有方法,就像您在示例中所做的那样,然后公共方法添加最终标准或查询以生成可用的数据集,这些数据可能因函数而异。为什么要一遍又一遍地重新发明轮子...只需创建基本设计(你可以使用IQueryable)并根据需要放下胎面花纹(你的公共IEnumerable会这样做):)

+1为一个好的设计IMO。