diff --git a/GBase/DataHandling/XmlDataReader.cs b/GBase/DataHandling/XmlDataReader.cs index 04b78c0..3586d76 100644 --- a/GBase/DataHandling/XmlDataReader.cs +++ b/GBase/DataHandling/XmlDataReader.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; +using GBase.Helpers; using GBase.Interfaces.DataHandling; using GBase.Interfaces.DataHandling.Xml; @@ -90,10 +91,8 @@ namespace GBase.DataHandling IEnumerable values = valueElements.Select(v => v.Value); - if (typeof(TProperty) != typeof(string) && typeof(TProperty).GetInterfaces().Contains(typeof(IEnumerable))) - { - return null; //FixMe: Implement handling for IEnumerables - } + if (typeof(TProperty) != typeof(string) && typeof(TProperty).GetInterfaces().Contains(typeof(IEnumerable))) //read property is an IEnumerable + return values.Select(Enumerables.ConvertToGBaseEnumerable).ToList(); return values.Select(value => (TProperty)Convert.ChangeType(value, typeof(TProperty))).ToList(); }, _cancellationToken); diff --git a/GBase/Exceptions/InterfaceEnumerablePassedException.cs b/GBase/Exceptions/InterfaceEnumerablePassedException.cs new file mode 100644 index 0000000..c23f19f --- /dev/null +++ b/GBase/Exceptions/InterfaceEnumerablePassedException.cs @@ -0,0 +1,27 @@ +// Author: Gockner, Simon +// Created: 2020-02-14 +// Copyright(c) 2020 SimonG. All Rights Reserved. + +using System; +using System.Collections.Generic; + +namespace GBase.Exceptions +{ + /// + /// that an interface was passed as the generic type of an + /// + public class InterfaceEnumerablePassedException : Exception + { + /// + /// that an interface was passed as the generic type of an + /// + /// + public InterfaceEnumerablePassedException(Type interfaceType) + : base($"Interface {interfaceType.FullName} was passed to an IEnumerable. This is not allowed.") + { + InterfaceType = interfaceType; + } + + public Type InterfaceType { get; } + } +} \ No newline at end of file diff --git a/GBase/GBase.csproj b/GBase/GBase.csproj index 183b47a..42b1313 100644 --- a/GBase/GBase.csproj +++ b/GBase/GBase.csproj @@ -25,4 +25,8 @@ + + + + diff --git a/GBase/GBase.xml b/GBase/GBase.xml index 2335a4e..ea83f33 100644 --- a/GBase/GBase.xml +++ b/GBase/GBase.xml @@ -344,6 +344,17 @@ A to await + + + that an interface was passed as the generic type of an + + + + + that an interface was passed as the generic type of an + + + Factory for the @@ -539,6 +550,14 @@ The + + + Convert a given to an of + + The + The given + An of + for the data handling diff --git a/GBase/Helpers/Enumerables.cs b/GBase/Helpers/Enumerables.cs index 097eb1a..6068a65 100644 --- a/GBase/Helpers/Enumerables.cs +++ b/GBase/Helpers/Enumerables.cs @@ -2,13 +2,20 @@ // Created: 2020-02-13 // Copyright(c) 2020 SimonG. All Rights Reserved. +using System; using System.Collections; +using System.Collections.Generic; +using System.Linq; using System.Text; +using GBase.Api; +using GBase.Exceptions; namespace GBase.Helpers { internal static class Enumerables { + private const char ENUMERABLE_STRING_DIVIDER = ','; + /// /// Convert an to a GBase /// @@ -19,14 +26,51 @@ namespace GBase.Helpers StringBuilder @string = new StringBuilder(); foreach (var item in enumerable) { - @string.Append($"{item},"); + @string.Append($"{item}{ENUMERABLE_STRING_DIVIDER}"); } char lastChar = @string[^1]; - if (lastChar == ',') + if (lastChar == ENUMERABLE_STRING_DIVIDER) @string.Remove(@string.Length - 1, 1); return @string.ToString(); } + + /// + /// Convert a given to an of + /// + /// The + /// The given + /// An of + public static TEnumerable ConvertToGBaseEnumerable(string @string) + { + //get generic type parameter of TEnumerable + Type genericType = typeof(TEnumerable).GetGenericArguments()[0]; + + Type listType = typeof(List<>); + Type genericList = listType.MakeGenericType(genericType); + IList enumerable = (IList) Activator.CreateInstance(genericList); + + foreach (var value in @string.Split(ENUMERABLE_STRING_DIVIDER)) + { + object item; + + if (genericType.GetInterfaces().Contains(typeof(IGBaseObject))) + { + if (genericType.IsInterface) + throw new InterfaceEnumerablePassedException(genericType); + + IGBaseObject gBaseObject = (IGBaseObject) Activator.CreateInstance(genericType); + gBaseObject.InitializeFromString(value); + item = gBaseObject; + } + else + item = Convert.ChangeType(value, genericType); + + enumerable.Add(item); + } + + return (TEnumerable) enumerable; + } } } \ No newline at end of file diff --git a/GBase/Properties/AssemblyInfo.cs b/GBase/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..48b1ffc --- /dev/null +++ b/GBase/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ +// Author: Gockner, Simon +// Created: 2020-02-14 +// Copyright(c) 2020 SimonG. All Rights Reserved. + +using System.Runtime.CompilerServices; + +[assembly:InternalsVisibleTo("Test.GBase")]