martes, 6 de octubre de 2015

Llenar atributos de una clase de forma dinámica. [Borrador]

private object ExcelRowToObject(DataColumnCollection pColumns, DataRow pRow, object pObjecto)
        {
            object wRt = pObjecto;
            foreach (DataColumn dc in pColumns)
            {
                //http://stackoverflow.com/questions/12970353/c-sharp-dynamically-set-property
                //-->objName.GetType().GetProperty("nameOfProperty").SetValue(objName, objValue, null)
                // Llamamos a las columnas en el excel como en las propiedades para hacer más fácil la automatización
                if (dc.ColumnName != null)
                {
                    if (dc.ColumnName != string.Empty && dc.ColumnName != c_ID)
                    {
                        try
                        {
                            System.Reflection.PropertyInfo wPI = pObjecto.GetType().GetProperty(dc.ColumnName.Trim());
                            if (wPI.PropertyType == Type.GetType("System.Decimal"))//si evoluciona a más, mejor hacer un swicht
                            {
                                if (pRow[dc.ColumnName.Trim()].ToString() != string.Empty)
                                {
                                    wPI.SetValue(wRt, decimal.Parse(pRow[dc.ColumnName.Trim()].ToString()), null);
                                }
                            }
                            else
                            {
                                wPI.SetValue(wRt, pRow[dc.ColumnName.Trim()].ToString(), null);
                            }
                        }
                        catch (Exception wExc)
                        {
                            //GestionError(wExc);
                            //throw wExc;
                            throw new Exception(dc.ColumnName.Trim() + ": " + wExc.Message);
                        }
                    }
                }
            }
            return wRt;
        }

        private bool ExcelValidarColumnas(Type pTypeToTest, string pTableName, DataColumnCollection pColumns)
        {
            //https://msdn.microsoft.com/en-us/library/system.type(v=vs.110).aspx
            //http://stackoverflow.com/questions/12970353/c-sharp-dynamically-set-property
            //-->objName.GetType().GetProperty("nameOfProperty").SetValue(objName, objValue, null)  

            string wMsgAux = string.Empty;
            foreach (DataColumn dc in pColumns)
            {
                try
                {
                    if (dc.ColumnName != null)
                    {
                        if (dc.ColumnName != string.Empty && dc.ColumnName != "_ID")
                        {
                            //System.Reflection.PropertyInfo wPI = wpinTest.GetType().GetProperty(dc.ColumnName.Trim());
                            System.Reflection.PropertyInfo wPI = pTypeToTest.GetProperty(dc.ColumnName.Trim());

                            if (wPI == null)
                            {
                                wMsgAux += dc.ColumnName + "; ";
                            }
                        }
                    }
                }
                catch
                {
                    wMsgAux += dc.ColumnName;
                }
            }
            if (wMsgAux != string.Empty)
            {
                wMsgAux = "Columnas en el Excel (" + pTableName + ") con nombre incorrecto: " + wMsgAux;
                GestionError(wMsgAux);
                return false;
            }
            else
            {
                return true;
            }

        }


Y las uso así
 foreach (DataRow row in P_IN.Rows)
                {
Miclase wpin = Miclase();

 wpin = (Miclase)ExcelRowToObject(P_IN.Columns, row, wpin);
}
Donde P_IN es una DataTable con los mismos nombres de columna que los atributos. De hecho el DataTable lo he creado cargando un Excel.