关于存储库模式的问题

时间:2009-09-23 09:34:54

标签: .net repository-pattern

这是一个好主意还是坏主意?

public interface IRepository<T>
{
    ...
    IList<T> Get(Func<T, bool> predicate)
    ...
}

我的意思是 - 这似乎是非常强大的补充,我也可以实现它(至少 - 在某种程度上),但我的胆量告诉我这是一种错误。谁能开导我?

4 个答案:

答案 0 :(得分:3)

我认为这更好:

public interface IRepository<T>
{
IQueryable<T> GetAll();
}

然后您可以将自定义查询编写为:

var employees=Repositroy<Employee>.GetAll().Where(emp=>emp.Salary>10000).Select(emp=>emp).ToList();

答案 1 :(得分:1)

嗯,这肯定是一个强大的功能。问题是:在接口中引入它会强制IRepository的所有实现提供合适的定义 - 这可能是不可能的(或者至少非常难),具体取决于实现(例如,由a支持的实现)数据库连接等等。

也许,你应该做

public interface IRepository<T>
{
    ...
}

public interface IAdvancedRepository<T>: IRepository<T> 
{
    IList<T> Get(Func<T, bool> predicate)
}

并仅提供Get,如果实施可以有效地执行此操作。

答案 2 :(得分:0)

我倾向于将'Get'与获取一个简单实例而不是列表相关联。 因此,当我有一个返回集合的方法时,我通常将该方法命名为“查找”或类似的东西。

(请注意,FxCop会告诉您使用'Get'作为函数名称是个坏主意。)

啊,好吧,我错过了这一点。 :) 我不会创建一个以标准作为参数的方法。我宁愿在我的存储库上有专门的方法,而不是传递各种标准。 我知道,它不是那么灵活,但它更明确。

答案 3 :(得分:0)

对我来说,它闻起来就像你不需要一个存储库,因为.NET开发人员通常都会理解它。

我认为你需要这样的东西:

public interface IStore {
    // Low-level abstraction over a real database
}

public interface IAction<TInput, TResult> { // Or maybe ICommand?
    TResult Execute(TInput input);
}

// then:
public interface IGetCustomerById : IAction<int, Customer> {
}
public class GetCustomerById : IGetCustomerById {
    IStore store;
    public GetCustomerById(IStore store) {
        this.store = store;
    }

    public Customer Execute(int id) {
        return store.ResultOfExecutedSqlOrWhatever(id);
    }
}
// it might not only be READ action but more complex one, reusing other actions too
public class ApproveCustomer<ApprovalInfo,ApprovalResult> : IAction {
    IStore store;
    IGetCustomerById getCustomer;
    public ApproveCustomer(IStore store, IGetCustomerById getCustomer) {
        this.store = store;
        this.getCustomer = getCustomer;
    }

    public ApprovalResult Execute(ApprovalInfo approval) {
        var customer = getCustomer.Execute(approval.CustomerId);
        var result = new ApprovalResult();
        if (customer == null) {
            result.Message = "No such customer";
            return result;
        }
        if (!customer.IsEligibleForSomething()) { // This can be another action!
            result.Message = "Not eligible"
            return result;
        }
        result.Message = "Successfully approved"
        result.IsApproved = true;
        return result;
    }
}

此处的其他好处是所有这些操作都可以轻松地与依赖注入一起使用。