rolf wroteYeah, what bothers me though is that your logic will be distributed over more then one object. Let's say you want to use the auction class in another project, you'll have to copy the auction class itself, and the input validation class for the auction class... see what I mean? I like to keep my code modular.
Oh you mean the ViewModel for the Auction class? Or are you referring to the AuctionService? In case you are talking about the ViewModel, no I do not have to copy it to the new project, because I have a ViewModel for each "screen". The screen of the new project will not necessarily be an exact match of the one in the current project. Each project has its own requirements. My infrastructure code will still be the same, but the UI code will definitely have to be re-written/copied in the new project, yes.
Now if you are talking about the AuctionService class, you do have a point there. The AuctionService class does not have any coupling with some validation logic because that logic lives in the AuctionService class itself! But it does inherit from the BaseService class which contains the Erros collection and the IsValid() method. So yeah, I do not like that, and that's exactly why I went ahead and implemented
that developer's approach. Now, in any new project that requires validation (they all do anyway), I could simply add a reference to my infrastructure assembly where all the validation plumbing code resides, and then I would simply create the specific validator classes and plug them into the ValidationProvider (that all happens using an IoC container that is smart enough to find what specific Validator is required to validate the given specific model class, Product for example => ProductValidator).
//The call from my BiddingService class
public void PlaceBid(Bid bid)
{
if (bid == null)
throw new ArgumentNullException("bid");
_validationProvider.Validate(bid);
_repository.Add<Bid>(bid);
_unitOfWork.Commit();
}
//BidValidator class
public sealed class BidValidator : Validator<Bid>
{
protected override IEnumerable<ValidationResult> Validate(Bid bid)
{
if (bid.User.HasEnoughCredits() == false)
yield return new ValidationResult("InsufficientCredits", "Not enough credits.");
if(bid.Item.IsValidBidAmount(bid.Amount) == false)
yield return new ValidationResult("Amount", "Bid amount has to be higher than last posted bid.");
if(bid.User.OwnsItem(bid.Item.ID))
yield return new ValidationResult("InvalidBidder", "User cannot bid on his/her own items.");
}
}