Pavel Martynov
Pavel Martynov

Reputation: 560

Specification pattern for repository?

Inspired by http://huyrua.wordpress.com/2010/08/25/specification-pattern-in-entity-framework-4-revisited i have decided to write all nontrivial queries over specifications. But у encountered a problem that i dont know how to use one specification in a few functions:

public bool CheckAccountEmailExist(string email)
{
    var emailExistSpec = new Specification(a => a.Email.ToUpper() == email.ToUpper());
    return _accountRepository.GetBy(emailExistSpec).Any();
}

public bool CheckAccountEmailExist(string email, Guid exceptAccountId)
{
    var emailExistSpec = new Specification(a => a.Email.ToUpper() == email.ToUpper());
    var exceptAccountSpec = new Specification(a => a.Id != exceptAccountId);
    return _accountRepository.GetBy(emailExistSpec.And(exceptAccountSpec)).Any();
}

I want to extract specification “a => a.Email.ToUpper() == email.ToUpper()” to use it in both functions, but i should parametrize it with “email” (function parameter). How can I do this?

Upvotes: 1

Views: 973

Answers (2)

Klaus Byskov Pedersen
Klaus Byskov Pedersen

Reputation: 120917

I think the problem lies in the fact that you are using a generic Specification class that takes a lambda expression in its constructor. The purpose of a specification in my opinion is to specify some restriction on a domain object. Therefore I think that you should make your Specification class abstract, and inherit from it in a EmailExistsSpecification class and an AccountIdIsNotEqualSpecification class. It could look something like this:

public class EmailExistsSpecification : Specification<Account>
{
    public EmailExistsSpecification(string email) 
        : base(a => a.Email.ToUpper() == email.ToUpper())
    {
    }
}

I think this approach is more intention revealing than using a generic specification class.

Upvotes: 3

jason
jason

Reputation: 241583

For some reason I can't view the page that you link to, but I imagine that it would go something like this:

class EmailSpecification : Specification {
    public EmailSpecification(string email) :
        base(a => a.Email.ToUpper() == email.ToUpper())
    {
    }
}

Then:

public bool CheckAccountEmailExist(string email) {
    var emailExistSpec = new EmailSpecification(email);
    return _accountRepository.GetBy(emailExistSpec).Any();
}

Upvotes: 3

Related Questions