Tengo un modelo de dominio ignorante de persistencia que usa repositorios abstractos para cargar objetos de dominio. La implementación concreta de mis repositorios (la capa de acceso a datos (DAL)) utiliza el marco de entidades para obtener datos de una base de datos de servidor SQL. La base de datos tiene restricciones de longitud en muchas de sus columnas varchar. Ahora imagina que tengo la siguiente clase de dominio:Restringir longitud de cadena en las clases de dominio
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; }
}
Y un repositorio abstracta definida de la siguiente manera:
public abstract class CaseRepository
{
public abstract void CreateCase(Case item);
public abstract Case GetCaseById(int id);
}
La columna [text]
de la tabla en SQL Server se define como nvarchar(100)
Ahora Sé que mencioné que mi clase de dominio (Case
) era persistente ignorante, sin embargo, creo que está mal que permita para los valores de text
parámetro que no puede ser salvado por mi implementación concreta de repositorio porque la estructura de entidad arrojará una excepción al asignar la propiedad text
a la clase generada por el marco de entidad cuando tiene más de 100 caracteres. Así que he decidido que deseo verificar esta restricción en el modelo de dominio, porque esto me permite verificar la validez de los datos antes de intentar pasarlos al DAL, y así hacer que los informes de error sean más centrados en el objeto de dominio. Creo que se puede argumentar que solo yo pueda comprobar la restricción en mi constructor y en la incubadora propiedad, pero ya que tengo cientos de clases que todos tienen las mismas limitaciones que quería una manera más genérico para resolver el problema
Ahora , lo que yo he llegado con una clase llamada ConstrainedString
, que se define de la siguiente manera:
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;
}
}
}
Además tengo una implementación de ConstrainedString
llamada String100
:
public class String100 : ConstrainedString
{
public String100(string textValue) : base(100, textValue) { }
}
Lo que conduce a una implementación diferente de Case
que se vería así:
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; }
}
Ahora, mi pregunta es; ¿Estoy pasando por alto algunas clases incorporadas o algún otro enfoque que podría usar en su lugar? ¿O es este un enfoque razonable?
Cualquier comentario y sugerencia son bienvenidos.
gracias de antemano
+1 Buena pregunta - A menudo me he preguntado por qué tales tipos no existen en el BCL. Sin embargo, creo que huele a Leaky Abstraction que está permitiendo que la base de datos relacional influya de esa manera en el Modelo de Dominio, o ¿existe un motivo convincente de dominio para estas restricciones? –
@Mark Seemann Estoy de acuerdo contigo en que huele, y no, en la mayoría de las partes no hay una razón de dominio convincente para las restricciones. Básicamente, es un esquema de base de datos heredado que probablemente podría beneficiarse de algunas refactorizaciones, pero eso está fuera de nuestro alcance actual. Sin embargo, no creo que pueda ignorar estas limitaciones en el modelo porque quiero hacer de la validación de datos una parte del modelo y NO una parte de la implementación del repositorio (que creo que es una buena ambición) –
¡Ah, el maravilloso mundo de aplicaciones heredadas ... Considere la posibilidad de crear una capa Decorator para su Modelo de dominio que implemente estas restricciones para mantener limpio su Modelo de dominio. Consulte aquí para obtener más detalles: http://community.ative.dk/blogs/ative/archive/2006/09/29/Migration-_2D00_-Bug_2D00_by_2D00_Bug-Compatibility.aspx –