Design guidelines for this scenario in C#?

I have to create a validation system(I don’t want to use Data Annotation or any other system) for my C# application using .Net Compact Framework, where I have an object which contains many other objects.

Many of the properties are dependent on each other means they have some sort of dependencies.

I can write a simple validator class which goes through all the properties
and checks them one by one with lots of if and else but I want to design something dynamic e.g. I should be able to specify list of dependencies on a property and specify a method which should be invoked during validation.

I mean some design guidelines would be appreciated ?

Example ( just for demo purpose ):

    public enum Category
        {
            Toyota,
            Mercedes,
            Tata,
            Maruti
        }

        class MyBigClass
        {
            public Category Category { get; set; }
            public double LowerPrice { get; set; }
            public double UpperPrice { get; set; }

            public SomeOtherObject OtherObject { get; set; }

public List<string> Validate()
        {
            List<string> listErrors = new List<string>();
            ParameterInfo pInfo = null;
            switch (Category)
            {
                case Category.Toyota:
                    pInfo = ParameterStorage.GetParameterInfo(PTYPE.Category_Toyota);
                    break;
                case Category.Mercedes:
                    pInfo = ParameterStorage.GetParameterInfo(PTYPE.Category_Mercedes);
                    break;
                case Category.Tata:
                    pInfo = ParameterStorage.GetParameterInfo(PTYPE.Category_Tata);
                    break;
                case Category.Maruti:
                    pInfo = ParameterStorage.GetParameterInfo(PTYPE.Category_Maruti);
                    break;
                default:
                    break;
            }

            if (LowerPrice < pInfo.Min || LowerPrice >= pInfo.Max)
            {
                listErrors.Add("LowerPrice");
            }

            if (UpperPrice > pInfo.Max || UpperPrice <= pInfo.Min)
            {
                listErrors.Add("UpperPrice");
            }

            return listErrors;
        }
        } 

        public enum PTYPE
            {
                RATING,
                Category_Tata,
                Category_Toyota,
                Category_Mercedes,
                Category_Maruti
            }

            public class ParameterInfo
            {
                public PTYPE Type { get; set; }
                public int Min { get; set; }
                public int Max { get; set; }
                public int Default { get; set; }
            }

       public class ParameterStorage
        {
            private static Dictionary<PTYPE, ParameterInfo> _storage = new Dictionary<PTYPE, ParameterInfo>();
            static ParameterStorage()
            {
                _storage.Add(PTYPE.Category_Maruti, new ParameterInfo { Type = PTYPE.Category_Maruti, Min = 50000, Max = 200000 });
                _storage.Add(PTYPE.Category_Mercedes, new ParameterInfo { Type = PTYPE.Category_Mercedes, Min = 50000, Max = 800000 });
                _storage.Add(PTYPE.Category_Toyota, new ParameterInfo { Type = PTYPE.Category_Toyota, Min = 50000, Max = 700000 });
                _storage.Add(PTYPE.Category_Tata, new ParameterInfo { Type = PTYPE.Category_Tata, Min = 50000, Max = 500000 });
            }

            public static ParameterInfo GetParameterInfo(PTYPE type)
            {
                ParameterInfo pInfo = null;
                _storage.TryGetValue(type, out pInfo);
                return pInfo;
            }
        }

In the above example I have a MyBigObject which contains some properties and some other objects and I have a storage class which keeps all the limits of properties which will be required to validate a property.

As described in the above example I have to get ParameterInfo for each property and then compare, I am looking for some kind of automatic way/dynamic way of doing the same.

7

  1. Objects that contain many other objects are probably doing too many things.
  2. Requiring the programmer to specify dependencies is forcing them to repeat themselves, which will lead to errors/inconsistencies. If you can find a way to detect dependencies (statically or dynamically) that would be better.
  3. Having a bundle of dependencies makes me concerned that your abstractions are not as clean as they should be. Dependencies between variables should (ideally) be isolated within a class. This might not apply in your case, but as a guideline – be sure you really need that tight coupling between variables in different classes.

And all that said, compact framework has had to do input validation for forever. Even if data annotations aren’t supported, this is likely to be a solved problem.

1

What about extracting the validation, and putting it at the same level as the input?

What I want to say is that it’s not the role of an object to validate itself. An object should always be valid: creating an invalid one doesn’t make too much sense. In the same way, you don’t create a person with an age of -50, because an age is always a positive value or zero.

In order to ensure an object is valid, one uses Code contracts in .NET Framework. Invariants would be especially useful, since they would not only prevent creating an invalid object, but also alter a valid one so it becomes invalid. In the same way, constraints in databases prevent invalid data from being stored.

Then, finding a place for input validation will depend on the context. If the object is created from user input (including, for example, an application which is using your API), validate the input. Other situations would mitigate the validation somewhere else. If creating an object is a difficult task, one will use a factory, which will how to create an object, without violating its contracts.

0

I think there is one mistake you are making. And that is you want to create a framework/library directly. Eg. you don’t know all cases this framework/library needs to solve, yet, you are trying to create this framework/library.

You should first do things directly, without first making a framework. Only after you create multiple cases should you try to abstract away what is common among those classes. Trying to be “dynamic” and “universal” will only hurt you in the long run.

Also, your code example is screaming from bad OO design. The moment you name an enum “type” or “kind” (or “category” in your case), it becomes obvious it should be multiple different classes within a hierarchy. This is probably why your code looks so bad and “static”. Because you didn’t care about proper separation of concerns and polymorphism. If you did this, you could even realize you don’t need any dynamic validation and that hand-coded validation is just fine.

Well, if you want to get rid of those switch statements it’s a good idea to use polymorphism to validate objects (e.g. making MyBigClass a class which is supertype for your vehicle brands).

The benefits of this approach are:

  1. You can use dynamic dispatch for methods like validate which are abstract at MyBigClass Level and are implemented in the specific classes (Toyota, Mercedes, …) which extend MyBigClass
  2. The rules for each vehicle type are encapsulated

You could specify an interface, say IValidatable and use reflection to loop through all the properties and sub properties and validate any which implement the interface. You then only need to implement Validate on each small sub property.

Many of the properties are dependent on each other means they have some sort of dependencies.

This is the root of your problem though. Having something thats hard to validate is just the symptom. Your best best is to split your class into smaller more manageable components.

I think you want something like this Fluent Validator for ASP MVC

The idea is the same as with annotations, but you can define rules at runtime, though with much less “if-statements”.

Here is the sample code of validation method:

[Validator(typeof(PersonValidator))]
public class Person {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public int Age { get; set; }
}

public class PersonValidator : AbstractValidator<Person> {
    public PersonValidator() {
        RuleFor(x => x.Id).NotNull();
        RuleFor(x => x.Name).Length(0, 10);
        RuleFor(x => x.Email).EmailAddress();
        RuleFor(x => x.Age).InclusiveBetween(18, 60);
    }
}

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật