[C#] File exporter for IEnumerable of T

Scope

This article has the goal to show a solution for have a file exporter based in a list of items but not matter which type.

Introduction

Sometime ago was published the sample Export To CSV for Windows Store apps, this solution is generic, is dynamic because uses reflection and It allow to export a list of items to a csv file. In Windows Store apps uses Windows Runtime and reflection is a bit different from reflection in WPF, Asp.Net, …

In this sample ww will create the sample for a common .Net project.

Description

For help in the sample, let’s create a specific class Person.

    /// 
    /// Define the Person.
    /// 
    public class Person
    {
        /// 
        /// Gets or sets the name.
        /// 
        /// The name.
        public string Name { get; set; }

        /// 
        /// Gets or sets the age.
        /// 
        /// The age.
        public int Age { get; set; }

        /// 
        /// Gets or sets the birthday.
        /// 
        /// The birthday.
        public DateTime Birthday { get; set; }

        /// 
        /// Gets or sets the country.
        /// 
        /// The country.
        public string Country { get; set; }
    }

in class diagram we will have

person
After it, we will create the Export class that will have a generic method, that uses a generic type T. Something like as following

 

    /// 
    /// Define the Export File.
    /// 
    public static class Export
    {
        /// 
        /// Exporters the list of items that can include the specified include header line.
        /// 
        /// <typeparam name="T">The generic type.
        ///If set totrue [include header line].
        ///The separator.
        ///The items.
        /// The content file.
        public static string Exporter(bool includeHeaderLine, string separator, IEnumerable items) where T : class
        {
            var sb = new StringBuilder();

            // Get properties using reflection. 
            var properties = typeof(T).GetProperties();

            if (includeHeaderLine)
            {
                // add header line
                foreach (var property in properties)
                {
                    sb.Append(property.Name).Append(separator);
                }
                sb.Remove(sb.Length - 1, 1).AppendLine();
            }

            // add value for each property. 
            foreach (T item in items)
            {
                foreach (var property in properties)
                {
                    sb.Append(MakeValueFriendly(property.GetValue(item, null))).Append(separator);
                }
                sb.Remove(sb.Length - 1, 1).AppendLine();
            }

            return sb.ToString();
        }

        /// 
        /// Makes the value friendly.
        /// 
        ///The value.
        /// The string converted.
        private static string MakeValueFriendly(object value)
        {
            if (value == null)
            {
                return string.Empty;
            }

            if (value is DateTime)
            {
                if (((DateTime)value).TimeOfDay.TotalSeconds == 0)
                {
                    return ((DateTime)value).ToString("yyyy-MM-dd");
                }
                return ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
            }
            var output = value.ToString();

            if (output.Contains(",") || output.Contains("\""))
            {
                output = '"' + output.Replace("\"", "\"\"") + '"';
            }

            return output;
        } 
    }

The method Exporter will allow to include a header with the properties name and allow to define the separador between each field value. It is very interesting because I can use the ListSeparator ( , or  ; ), |, + or other we define.

The method MakeValueFriendly is only useful for format specific type like DateTime.

Now we can create a list of person and write it to a file, let’s see how!

    /// 
    /// Define the Program.
    /// 
    public class Program
    {
        /// 
        /// Defines the entry point of the application.
        /// 
        /// args">The arguments.
        static void Main(string[] args)
        {
            var people = GetPeople();
            var basePath = Directory.GetCurrentDirectory();

            var fullPath = Path.Combine(basePath, "mycsvfile_includeHeader.csv");

            // to cvs file
            File.WriteAllText(fullPath, Export.Exporter(true, System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator, people));

            fullPath = Path.Combine(basePath, "myfile_includeHeader.txt");

            // to a txt file
            File.WriteAllText(fullPath, Export.Exporter(true, "+", people));


            fullPath = Path.Combine(basePath, "mycsvfile.csv");

            // to cvs file
            File.WriteAllText(fullPath, Export.Exporter(true, System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator, people));

            fullPath = Path.Combine(basePath, "myfile.txt");

            // to a txt file
            File.WriteAllText(fullPath, Export.Exporter(true, "|", people));
        }

        /// 
        /// Gets the people.
        /// 
        /// The IEnumerable.
        private static IEnumerable GetPeople()
        {
            return new List
            {
                new Person { Name = "Mary", Age = 22, Birthday = new DateTime(1992, 03, 24), Country = "Ireland" },
                new Person { Name = "Peter", Age = 10, Birthday = new DateTime(2004, 01, 05), Country = "Portugal" },
                new Person { Name = "Anne", Age = 50, Birthday = new DateTime(1964, 11, 03), Country = "Spain" }
            };
        }
    }

In the sample provided, we get the people and then wrote it in a CSV file and a TXT file, where we selected the both cases (with header and without).

The ouput

Running the console application we will get the output

folder

The CSV file with header

The CSV file without header

The txt file with header

The CSV file without header

Source Code

The source code can be found in MSDN Samples.

Adding SQLite SDK Extension to the project without installation requeriment

Today, in the Xamarin.Forms.Labs we find an error in a WP Demo, the Cache sample throw an exception each time the application try to get the implementation of ISimpleCAche

_cacheService = Resolver.Resolve<ISimpleCache> ();

But the code is right because we do this:

private void SetIoc()
        {
            var resolverContainer = new SimpleContainer();

			var app = new XFormsAppiOS();
			app.Init(this);

			var documents = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
			var pathToDatabase = "xforms.db";

			resolverContainer.Register<IDevice> (t => AppleDevice.CurrentDevice)
                .Register<IDisplay> (t => t.Resolve<IDevice> ().Display)
				.Register<IJsonSerializer, Services.Serialization.ServiceStackV3.JsonSerializer> ()
				.Register<IXFormsApp> (app)
				.Register<ISimpleCache> (t => new SQLiteSimpleCache(new SQLite.Net.Platform.XamarinIOS.SQLitePlatformIOS(),
					new SQLite.Net.SQLiteConnectionString(pathToDatabase,true), t.Resolve<IJsonSerializer> () ));
				

            Resolver.SetResolver(resolverContainer.GetResolver());
        }

The problem is, we need to add reference to SQLite for Windows Phone, without it we cannot use SQLite engine.

But it is installed in a folder in PC, and if we change the PC or share with other person, is a requirement to have it installed.
For avoid this problem i opened the cproj in notepad++ and added the lines:

  <PropertyGroup>
    <SDKReferenceDirectoryRoot>$(SolutionDir)\Sdks;$(SDKReferenceDirectoryRoot)</SDKReferenceDirectoryRoot>
  </PropertyGroup>

 

and then I went to the folder that contain all SDK extensions and got it, and create my own folder in project (called SDK), here is the tree:

folders

then when I added this to the project the path is for my folder:

path

Note: This SDK Extension must be updated manually!!

See my old article about similar problem, here.

[Visual Studio] Help make Edit and Continue better!

Do you get tired of seeing this box (I know I do)?

Tell us about it!

The Visual Studio team would like your anonymous feedback on improving Edit and Continue (E&C) when developing .NET applications. This survey can take as little as 3 minutes to complete (I’ve saved you some time already by copying all the words on that page to this page so you don’t have to read it twice) and will guide ongoing support and making it work in more places. If you consider yourself a regular E&C user or would like to see improvements that let you use it more often – we need to hear from you!

Please take a few minutes to complete the survey @ http://aka.ms/encsurvey and if it’s not too much trouble tell all of your developer pals about it. Blog, wall, and tweet the link to anyone who’ll listen!

The information you provide is entirely voluntary. If you do not wish to provide us with any information, please disregard this survey. By filling out and returning this survey, you agree that we can use, disclose, reproduce, or otherwise distribute your feedback at the aggregated level. Your personal information will remain confidential. Please check http://privacy.microsoft.com/en-us/default.aspx for Microsoft Privacy Statements.