Los objetos de trasferencia de datos (DTO) pueden ser de mucha utilidad al momento de desarrollar software. Basicamente son un molde para la información, donde el esquema se encuentra fuertemente tipeado
Algunas de las ventajas de utilizar diseños que implementen este tipo de objetos son:
Aunque estos objetos pueden darnos una gran cantidad de ventajas, tienen una enorme desventaja la cual es la causante de su poco uso, y es el tiempo de desarrollo, ya que obliga al programador a tipear cada una de las entidades logicas del sistema.
Es por esta razón por la cual muchas de las compañias que utilizan este tipo de diseño, o que elaboración frameworks para lo mismo, utilizan herramientas de generación automatica de código.
En lo que respecta a .NET, Microsoft deposito toda su confianza en los famosos objetos denominados Dataset, con los cuales se puede trabajar de una manera muy grafica y sencilla, es muy facil crear un esquma de información a partir de una base de datos de casi cualquier tipo (SQL, OLEDB, XML, etc.).
Pero estos objetos Dataset tienen una desventaja tan grande como sus ventajas… no les importa el diseño del sistema, puedes continuar utilizando los asistentes del VS y ver como terminas juntando el acceso a datos, juntos con las reglas de negocio y la interfaz grafica, tienen tanta funcionalidad que resulta practicamente inutil tratar de heredarlos e incrementar funcionalidad.
Aunque es posible crear objetos DTO usando un Dataset, muchas veces resulta inapropiado, ya que se perdio la razón de ser de estos mismos que es: asegurarse que el transporte de la información se lleve acabo de manera practica y segura, y solo eso.Es por eso que me decidi a crear mi propia estructura para objetos DTO, la cual aunque muy simple tambien es muy concreta y eficaz.
Aún no acabo de hacer todo lo que eh querido (una aplicación de auto-generación de código, y la funcionalidad de serialización en XML), pero por lo pronto ya tiene la funcionalidad que deberia tener para poder trabajar con el.
Les muestro el diagrama de clases, y el código, si alguien tiene alguna de idea de alguna modificación, escribanlo en los comentarios
using System;
using System.Collections.Generic;
/// <summary>
/// Domain. Representa la gama de valores en que cierto objeto debe pertenecer
/// </summary>
public struct Range<type> where type : struct
{
#region Campos
private System.Nullable<type> minValue;
private System.Nullable<type> maxValue;
private bool applyMinValue;
private bool applyMaxValue;
#endregion
#region Constructores
internal Range(System.Nullable<type> minValue, System.Nullable<type> maxValue) {
this.minValue = minValue;
this.maxValue = maxValue;
this.applyMinValue = true;
this.applyMaxValue = true;
}
internal Range(System.Nullable<type> minValue, System.Nullable<type> maxValue, bool applyMinValue, bool applyMaxValue)
{
this.minValue = minValue;
this.maxValue = maxValue;
this.applyMinValue = applyMinValue;
this.applyMaxValue = applyMaxValue;
}
#endregion
#region Propiedades
public object MinValue {
get { return minValue; }
}
public object MaxValue {
get { return maxValue; }
}
public bool ApplyMinValue {
get { return applyMinValue; }
}
public bool ApplyMaxValue {
get { return applyMaxValue; }
}
#endregion
}
/// <summary>
/// Metada. Representa un metadato (Información de un campo)
/// </summary>
public class MetaData
{
#region Campos
private Type netType; //Default. NETTypes.String
private int length; //Default. 0
private int maxLength; //Default. 0
private bool isNullable; //Default. false
private bool isReadOnly; //Default. false
private bool isUnique; //Default. false
private int numericPrecision; //Default. 0
private int numericScale; //Default. 0
#endregion
#region Constructores
/// <summary>
/// MetaData. Constructor Generico
/// </summary>
public MetaData() {
this.netType = Type.GetType("System.String");
this.length = 0;
this.isNullable = false;
this.isReadOnly = false;
this.isUnique = false;
this.numericPrecision = 0;
this.numericScale = 0;
}
/// <summary>
/// Metadata. Constructor por tipo
/// </summary>
public MetaData(Type nettype) : this(){
this.netType = nettype;
}
#endregion
#region Propiedades
public Type NetType {
get {
return this.netType;
}
set {
this.netType = value;
}
}
public int Length {
get {
return this.length;
}
set {
this.length = value;
}
}
public int MaxLength{
get {
return this.maxLength;
}
set {
this.maxLength = value;
}
}
public bool IsNullable {
get {
return this.isNullable;
}
set{
this.isNullable = value;
}
}
public bool IsReadOnly {
get {
return this.isReadOnly;
}
set {
this.isReadOnly = value;
}
}
public bool IsUnique {
get {
return this.isUnique;
}
set {
this.isUnique = value;
}
}
public int NumericPrecision {
get {
return this.numericPrecision;
}
set {
this.numericPrecision = value;
}
}
public int NumericScale {
get {
return this.numericScale;
}
set {
this.numericScale = value;
}
}
#endregion
}
/// <summary>
/// FieldMeta. Clase abstracta basica de Field
/// </summary>
public abstract class BaseField : MarshalByRefObject
{
#region Campos
private MetaData meta;
private string name;
#endregion
#region Constructores
public BaseField(string name, MetaData meta) {;
this.name = name;
this.meta = meta;
}
public BaseField(string name, MetaData meta, bool isLocked){
this.name = name;
this.meta = meta;
}
#endregion
#region Propiedades
internal MetaData Meta{
get { return this.meta; }
set { this.meta = value; }
}
public string Name{
get { return name; }
set { name = value; }
}
#endregion
#region Delegados & Eventos
internal delegate void ValueChange(BaseField field, object value);
internal event ValueChange valueChange;
internal void OnValueChange(BaseField field, object value) {
if (valueChange != null) {
valueChange(field, value);
}
}
#endregion
}
/// <summary>
/// Field. Representa un campo
/// </summary>
public class Field<type> : BaseField where type : struct
{
#region Campos
private System.Nullable<type> value;
private System.Nullable<Range<type>> range;
private string regEx;
#endregion
#region Constructores
public Field(string name, MetaData meta) : base(name, meta) { }
public Field(string name, MetaData meta, bool isLocked) : base(name, meta, isLocked) { }
#endregion
#region Propiedades
public type Value{
get { return this.value.Value; }
set { this.value = value; }
}
public Range<type> Range {
get { return this.range.Value; }
set { this.range = value; }
}
public string RegEx {
get { return this.regEx; }
set { this.regEx = value; }
}
public bool HasValue {
get { return value.HasValue; }
}
public bool HasRange{
get { return range.HasValue; }
}
public bool HasRegEx {
get { return !string.IsNullOrEmpty(this.regEx); }
}
#endregion
#region Metodos
#region General
public override string ToString() {
if (value.HasValue){
return Value.ToString();
}
else{
return string.Empty;
}
}
#endregion
#region Dominio
public void SetRange(type minValue, type maxValue)
{
this.range = new Range<type>(minValue, maxValue);
}
public void SetRange(type minValue, type maxValue, bool applyMinValue, bool applyMaxValue)
{
this.range = new Range<type>(minValue, maxValue, applyMinValue, applyMaxValue);
}
#endregion
#endregion
}
/// <summary>
/// DTObject. Representaun objeto tipo DTO
/// </summary>
public abstract class DTObject : MarshalByRefObject
{
#region Campos
private Dictionary<string, BaseField> internalCollection;
#endregion
#region Propiedades
public BaseField this[string name]{
get { return this.internalCollection[name]; }
}
#endregion
#region Constructores
public DTObject() {
this.internalCollection = new Dictionary<string,BaseField>();
SetFields();
}
#endregion
#region Metodos
protected abstract void SetFields();
protected void AddField(string name, BaseField field) {
field.valueChange += new BaseField.ValueChange(OnValueChange);
this.internalCollection.Add(name, field);
}
#endregion
#region Delegados & Eventos
public delegate void ValueChange(BaseField field, object value);
public event ValueChange fieldValueChange;
protected void OnValueChange(BaseField field, object value){
if (fieldValueChange != null){
fieldValueChange(field, value);
}
}
#endregion
}
Is anyone aware if there is as cheap pro reputation service than ReputationUP.com? AmerisourceBergen? They only cost 49 dollars which is not much, unfortunately my co-worker Christopher said me there is, unfortunately he could not remember its name. 1 indeed start to get feeling that he recalled wrongly. Please reply