Here we will introduce a VAB (Validation Application Block), ASP.. net mvc uses the Attribute declarative verification component FluentValidation, which uses the expression syntax chain programming to separate the verification component from the entity. The reason why I like him is that I like expressions and chain.
Enter the topic of today. First, if you do not have this component, you can use NuGet of VS2010 to install it. If not, install the open source DataBase component: the method mentioned in FluentMigrator ), command:
Now we can start to experience it. The entity class do is still the Orders in the previous section:
Do:
- public class Orders
- {
- public int ID { get; set; }
- public string CustomerID { get; set; }
- public decimal DisCount { get; set; }
- public DateTime OrderDate { get; set; }
- }
Verification logic:
- public class OrdersValidator:AbstractValidator<Orders>
- {
- public OrdersValidator()
- {
- RuleFor(orders => orders.CustomerID).NotEmpty().Length(2, 20).WithName("CustomerID");
- RuleFor(orders => orders.DisCount).GreaterThanOrEqualTo(0).LessThan(1).WithMessage("discount must between 0 and 1!");
- RuleFor(orders => orders.OrderDate.Date).GreaterThanOrEqualTo(DateTime.Now.Date).WithName("Order Date");
- }
- }
How do you feel when you see this code? The current language focuses not only on functions but also semantics.
Next we will write a simple test class to test it:
- [TestMethod]
- public void TestMethod1()
- {
- var orders = new Orders(){DisCount = 2,CustomerID = "1", OrderDate = DateTime.Now.AddDays(-1).Date};
- IValidator validator = new OrdersValidator();
- var results = validator.Validate(orders);
-
- var validationSucceeded = results.IsValid;
- var failures = results.Errors;
- Assert.IsTrue(failures.Any(t => t.PropertyName == "CustomerID"));
- Assert.IsTrue(failures.Any(t => t.PropertyName == "DisCount"));
- Assert.IsTrue(failures.Any(t => t.PropertyName == "OrderDate.Date"));
- failures.ToList().ForEach(t=>Debug.WriteLine(t.ErrorMessage));
- }
Result:
The unit test results will not be posted, and I feel redundant.
Finally, I forgot to mention that this component provides us with multi-language support in many languages:
I am thinking that the verification components we adopt in architecture design can be switched at will. We can create a facade mode for the same abstract interface of VAB and FluentValidation. With the help of the IOC plug-in architecture, different keys are used to obtain the verification component interface, and this key value will be processed on the Attribute of the method, and the AOP method is cross-cutting to our application, verification is a business function component, a cross-cutting point. I am referencing my architecture as well.
|