No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Aplicando el principio de responsabilidad única

6/16
Recursos

Aportes 7

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

Dejo mi propuesta de clase ExportHelper (clase que reemplaza a ExportStudents) usando generics de modo que se pueda reutilizar con otros modelos.
Tiene una restriccion y es que solo podria ser usada con modelos que internamente tengan como mucho colecciones de tipos basicos (listas de enteros, listas de dobles, arreglos de enteros, etc).

using System.Collections;
using System.Text;

namespace SingleResponsability
{
    public class ExportHelper<T>
    {
        public void ExportToCSV(IEnumerable<T> items)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            string header = "";
            string[] dataRows = new string[items.Count()];
            foreach (var prop in typeof(T).GetProperties())
            {
                header += $"{prop.Name};";
                for (int i = 0; i < items.Count(); i++)
                {
                    var propValue = prop.GetValue(items.ToArray()[i]);
                    var propType = propValue.GetType();
                    if(propType.Name != nameof(String) 
                        && propType.GetInterface(nameof(IEnumerable)) != null)
                    {
                        dataRows[i] += $"{String.Join("|", (propValue as IEnumerable).Cast<object>().Select(x => x.ToString()))};";

                    }
                    else
                    {
                        dataRows[i] += $"{propValue};";
                    }
                }
            }
            sb.AppendLine(header.Trim(';'));
            foreach (var dataRow in dataRows)
            {
                sb.AppendLine(dataRow.Trim(';'));
            }
            System.IO.File.WriteAllText(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"Export_{typeof(T).ToString()}.csv"), sb.ToString(), Encoding.Unicode);
        }
    }
}

La implementacion en la clase program seria asi

using SingleResponsability;

StudentRepository studentRepository = new();
ExportHelper<Student> studentExport = new();
studentExport.ExportToCSV(studentRepository.GetAll());
Console.WriteLine("Proceso Completado");

Al crear la clase ExportHelper me aparecía un error CS0101, estuve revisando un rato, pero el error se resolvió cerrando y volviendo a abrir el VSCode.

Espero que les sirva. 😄

Dejo mi propuesta de clase ExportHelper

using System.Collections;
using System.Text;

namespace SingleResponsability
{
    public class ExportHelper
    {
        public static void ExportCSV<T>(IEnumerable<T> items) where T : class
        {

            StringBuilder sb = new StringBuilder();
            string csvHeader = String.Join(";", typeof(T).GetProperties().Select(x => x.Name.ToString()));
            sb.AppendLine(csvHeader);

            foreach (var item in items)
            {
                string csvData = String.Join(";", typeof(T).GetProperties().Select(x => 
                {
                    object? valueProperty = x.GetValue(item);
                    if (valueProperty is null) return string.Empty;
                    else if (valueProperty is not String && valueProperty is IEnumerable valuesListProperty)
                    {
                        string line = string.Empty;
                        var valores = valuesListProperty.Cast<object>().ToList().Select(x => x);
                        line += string.Join("|", valores);
                        return line;
                    }
                    else return valueProperty;
                }));
                
                sb.AppendLine(csvData);
            }
            System.IO.File.WriteAllText(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"{typeof(T).Name}.csv"), sb.ToString(), Encoding.Unicode);

        }
    }
}

Esta es mi propuesta de la case ExportHelper:

using System.Collections;
using System.Reflection;
using System.Text;

namespace SingleResponsability
{
    public class ExportHelper<T> where T : class 
    {
        public void ExportToCSV(IEnumerable<T> items )
        {
            Type type = typeof(T);
            string classNme =  type.Name;

            string csv = String.Join(",", items.Select(x => x.ToString()).ToArray());
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            //Obten las propiedades de la clase
            PropertyInfo[] properties = type.GetProperties();
            string appentLine = string.Empty;
            foreach (PropertyInfo property in properties)
            {
                appentLine+=$"{property.Name};";
            }
            sb.AppendLine(appentLine);

            foreach (var item in items)
            {
                string valueOfProperty = string.Empty;
                foreach (PropertyInfo property in properties)
                {
                    Type propertyType = property.PropertyType;
                    if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(List<>))
                    {
                        IList list = (IList)property.GetValue(item);
                        if (list != null)
                        {
                            
                            foreach (object listItem in list)
                            {
                                valueOfProperty += $"{(listItem != null ? listItem.ToString() : "null")}|";
                            }
                            valueOfProperty += ";";
                        }
                        else
                        {
                            valueOfProperty += "null";
                        }
                    }
                    else{
                        object value = property.GetValue(item);
                        valueOfProperty += $"{(value != null ? value.ToString() : "null")};";

                    }
                }
                sb.AppendLine(valueOfProperty);
                //sb.AppendLine($"{item.Id};{item.Fullname};{string.Join("|", item.Grades)}");
            }
            System.IO.File.WriteAllText(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"{classNme}.csv"), sb.ToString(), Encoding.Unicode);
        }
    }
}

Y la implementación:

using SingleResponsability;

StudentRepository studentRepository = new();
ExportHelper<Student> exportStudent = new ();
exportStudent.ExportToCSV(studentRepository.GetAll());
Console.WriteLine("Proceso Completado");

Siendo un helper convertí la función en estática para no crear una instancia

public static void ExportStudents(IEnumerable<Student> students)
        {
            functionCode
        }

Y así lo invoco en program

StudentRepository studentRepository = new();
ExportHelper.ExportStudents(studentRepository.GetAll());
Console.WriteLine("Proceso Completado");

Podría ser esto una mala práctica??

Mi propuesta:

        public void Export<T>(string header, IEnumerable<T> registers) 
        {

            System.Text.StringBuilder sb = new System.Text.StringBuilder();

            sb.AppendLine(header);
            
            foreach (var item in registers)
            {
                if (item == null) continue;
                Type type = item.GetType();
                PropertyInfo[] props = type.GetProperties();
                string lineaCsv = "";
                foreach (var prop in props)
                {
                    lineaCsv+= prop.GetValue(item) + ";";
                }

                sb.AppendLine(lineaCsv);
            }
            System.IO.File.WriteAllText(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Registers.csv"), sb.ToString(), Encoding.UTF8);
        }

Comparto mi propuesta para ExportHelper

Básicamente lo que realice fue que fuera un extended method, y le agregue un constraint para que solo aplique para clases, adicionalmente utilice refelection para recuperar el nombre de las propiedades del genérico y así mismo obtener los valores.

using System.Text;
using System.Collections;
namespace SingleResponsability
{
    public static class ExportHelper
    {

        public static void Export<T>(this IEnumerable<T> source) where T : class
        {
            var sb = new StringBuilder();
            var properties = typeof(T).GetProperties();
            var headers = string.Join(";",properties.Select(p => p.Name));
            sb.AppendLine(headers);
            foreach (var item in source)
            {
                string line = string.Empty;
                foreach (var prop in properties)
                {
                    object? value = prop.GetValue(item, null);

                    if (value is null) continue;
                    
                    if (value is not string && value is IEnumerable valuearray){
                        var values = valuearray.Cast<object>().Select(v => v); 
                        line += string.Join("|",values);
                        continue;
                    }

                    line += $"{value};";
                }
                sb.AppendLine(line);
                System.IO.File.WriteAllText(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Students.csv"), sb.ToString(), Encoding.Unicode);
            }
        }
    }
}