I'm working on a website, and just trying to get my head around the general structure. I have a database in the background that I'm accessing using the "Repository Pattern". I have the below code in my UserRepository class:
public bool IsValid(User user)
{
if (_context.Users.Any(c => c.EmailAddress == user.EmailAddress))
{
Message = "Email address already in use";
return false;
}
return true;
}
And that is implemented here
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(User user)
{
if (ModelState.IsValid)
{
var context = new Context("DatabaseContext");
var userRepo = new UserRepository(context);
if (userRepo.IsValid(user))
{
userRepo.Add(user);
// return to different view
}
else
{
// display userRepo.Message on page
return View(user);
}
}
return View(user);
}
My problem is I don't think I'm going around the "message" bit correctly, but I can't find anything online to help me out (specifically around repository). I think I should be changing the return type of IsValid to something like a result (as I've seen with dialog boxes), but again, I'm not sure.
Any help would be much appreciated.
Thanks.
In this article, we will learn what is Repository pattern and how to implement the Repository pattern in Java with an example. Repository layer is added between the domain and data mapping layers to isolate domain objects from details of the database access code and to minimize scattering and duplication of query code.
Before and after the Repository pattern shows a little preview of what we’re going to build: a Repository object that sits between our domain model and the database. Figure 1. Before and after the Repository pattern The code for this chapter is in the chapter_02_repository branch on GitHub.
A question that arose when we discussed the Repository Pattern is about its application in a domain model that has lots and lots of objects - let's say, a hundred, to put a number. Since you named the class AbstractRepository, and not AbstractBatchRepository, I'm guessing that you'll have a single repository class for the entire application.
Queries (in CQS) are used to return information to the user interface while the repository pattern is used to create an abstraction layer which can be used in your business code.
One way to achieve this is exactly like you have suggested - change the return type of IsValid
.
In the past I have had similar validation methods in my "business layer" that return a collection of ValidationResult
, where each returned record accounts for a validation error within the model and an empty collection would be interpreted as a valid model.
For example:
public class ValidationResult
{
public string FieldName { get; set; }
public string Message { get; set; }
}
public interface IValidator<T>
{
IEnumerable<ValidationResult> IsValid(T model);
}
//...in your implementation
public IEnumerable<ValidationResult> IsValid(User user)
{
//Return a new ValidationResult per validation error
if (_context.Users.Any(c => c.EmailAddress == user.EmailAddress))
{
yield return new ValidationResult
{
Message = "Email address already in use",
FieldName = nameof(user.EmailAddress)
};
}
}
This could then be interpreted by your presentation layer to feedback to the user.
I agree with what you mentioned in question. Returning custom class will be better approach IMO.
public ValidationResult IsValid(User user)
{
ValidationResult validationResult = new ValidationResult(true, "");
if (_context.Users.Any(c => c.EmailAddress == user.EmailAddress))
{
validationResult.Status = false;
validationResult.Message = "Email address already in use";
return validationResult;
}
return validationResult;
}
This way, Status
and Message
give you all info needed. Check the status first. If it is false, check message for exact details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With