String length limit in domain classes

I have an unknown domain model that uses abstract repositories to load domain objects. The specific implementation of my repositories (data access level (DAL)) uses the entity infrastructure to retrieve data from the sql server database. The database has length limits for many varchar columns. Now imagine that I have the following domain class:

public class Case { public Case(int id, string text) { this.Id = id; this.Text = text; } public int Id { get; private set; } public string Text { get; set; } } 

And the abstract repository is defined as follows:

 public abstract class CaseRepository { public abstract void CreateCase(Case item); public abstract Case GetCaseById(int id); } 

The [text] column of a table in sqlserver is defined as nvarchar(100)

Now I know that I mentioned that my domain class ( Case ) was insatiable, but I feel that it is wrong that it allows for text parameter values ​​that ultimately cannot be stored in my specific repository implementation, since the structure entities will throw an exception when assigning the text property to a class of the generated entity environment if it is longer than 100 characters. Therefore, I decided that I want to check this restriction in the domain model, since this allows me to check the validity of the data before trying to transfer it to the DAL and, thus, make the error message more oriented to the domain object. I think you could argue that I can just check the constraint in my constructor and in the property adjuster, but since I have hundreds of classes, all have similar limitations, I wanted a more general way to solve the problem

Now what I came up with is a class called ConstrainedString , which is defined as follows:

 public abstract class ConstrainedString { private string textValue; public ConstrainedString(uint maxLength, string textValue) { if (textValue == null) throw new ArgumentNullException("textValue"); if (textValue.Length > maxLength) throw new ArgumentException("textValue may not be longer than maxLength", "textValue"); this.textValue = textValue; this.MaxLength = maxLength; } public uint MaxLength { get; private set; } public string Value { get { return this.textValue; } set { if (value == null) throw new ArgumentNullException("value"); if (value.Length > this.MaxLength) throw new ArgumentException("value cannot be longer than MaxLength", "value"); this.textValue = value; } } } 

In addition, I have an implementation of ConstrainedString called String100 :

 public class String100 : ConstrainedString { public String100(string textValue) : base(100, textValue) { } } 

Thus, this will lead to another Case implementation that will look like this:

 public class Case { public Case(int id, String100 text) { this.Id = id; this.Text = text; } public int Id { get; private set; } public String100 Text { get; set; } } 

Now, my question is: Can I ignore some built-in classes or some other approach that I could use instead? Or is this a reasonable approach?

Any comments and suggestions are welcome.

Thank you in advance

+6
string c # domain-model
source share
3 answers

I believe your check should be in your domain model. Restrictions on your fields directly represent some business logic. Ultimately, you must pass the test before you persist.

+1
source share

I think it depends on many factors (as well as on some personal preferences). Sometimes the restriction should be part of the domain object - for example, social security numbers / passport numbers ... - they usually have a fixed length and cannot change as a rule of the domain, and not the rule of data storage (although you can limit db as well).

Some people prefer not to have such checks in their domain model and instead have something like a property check attribute that can be checked and performed by a separate validator external from the domain object.

A problem that you may encounter in your method (although it is not difficult to work around) gets any ORM / Mapper - if you use it - to know how to match a string to / from db in ConstrainedString.

ConstrainedString may not cause a problem with a domain object that has additional restriction information, because you may need to build ConstrainedString

0
source share

If you change the restrictions for Case, it makes sense that you will need to create a new one - you have changed the contract, and the old code will no longer know whether it meets the requirements or not.

Instead of worrying about what your repository will or will not allow, determine what you will allow in your class and make sure that you find a way to work with any repository that you changed in the future. You have your own API - your dependencies are not.

0
source share

All Articles