-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added EnumConverterFactory and CollectionConverterFactory. Changed fa…
…ctory creation to give back whether it should be added to the cache.
- Loading branch information
Showing
16 changed files
with
323 additions
and
164 deletions.
There are no files selected for viewing
175 changes: 175 additions & 0 deletions
175
src/CsvHelper/TypeConversion/CollectionConverterFactory.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
// Copyright 2009-2022 Josh Close | ||
// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0. | ||
// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0. | ||
// https://github.com/JoshClose/CsvHelper | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Collections.ObjectModel; | ||
using System.Linq; | ||
using System.Reflection; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace CsvHelper.TypeConversion | ||
{ | ||
/// <inheritdoc /> | ||
public class CollectionConverterFactory : ITypeConverterFactory | ||
{ | ||
private int dictionaryTypeHashCode = typeof(IDictionary).GetHashCode(); | ||
private List<int> enumerableTypeHashCodes = new List<int> | ||
{ | ||
typeof(IList).GetHashCode(), | ||
typeof(ICollection).GetHashCode(), | ||
typeof(IEnumerable).GetHashCode(), | ||
}; | ||
|
||
/// <inheritdoc /> | ||
public bool CanCreate(Type type) | ||
{ | ||
switch (type) | ||
{ | ||
case IList: | ||
case IDictionary: | ||
case ICollection: | ||
case IEnumerable: | ||
return true; | ||
} | ||
|
||
if (type.IsArray) | ||
{ | ||
// ArrayConverter | ||
return true; | ||
} | ||
|
||
if (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>)) | ||
{ | ||
// IDictionaryGenericConverter | ||
return true; | ||
} | ||
|
||
if (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>)) | ||
{ | ||
// IDictionaryGenericConverter | ||
return true; | ||
} | ||
|
||
if (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) | ||
{ | ||
// CollectionGenericConverter | ||
return true; | ||
} | ||
|
||
if (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(Collection<>)) | ||
{ | ||
// CollectionGenericConverter | ||
return true; | ||
} | ||
|
||
if (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(IList<>)) | ||
{ | ||
// IEnumerableGenericConverter | ||
return true; | ||
} | ||
|
||
if (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(ICollection<>)) | ||
{ | ||
// IEnumerableGenericConverter | ||
return true; | ||
} | ||
|
||
if (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) | ||
{ | ||
// IEnumerableGenericConverter | ||
return true; | ||
} | ||
|
||
// A specific IEnumerable converter doesn't exist. | ||
if (typeof(IEnumerable).IsAssignableFrom(type)) | ||
{ | ||
// EnumerableConverter | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/// <inheritdoc /> | ||
public bool Create(Type type, TypeConverterCache cache, out ITypeConverter typeConverter) | ||
{ | ||
var typeHashCode = type.GetHashCode(); | ||
|
||
if (typeHashCode == dictionaryTypeHashCode) | ||
{ | ||
typeConverter = new IDictionaryConverter(); | ||
return true; | ||
} | ||
|
||
if (enumerableTypeHashCodes.Contains(typeHashCode)) | ||
{ | ||
typeConverter = new IEnumerableConverter(); | ||
return true; | ||
} | ||
|
||
if (type.IsArray) | ||
{ | ||
typeConverter = new ArrayConverter(); | ||
return true; | ||
} | ||
|
||
var isGenericType = type.GetTypeInfo().IsGenericType; | ||
var genericTypeDefinition = type.GetGenericTypeDefinition(); | ||
|
||
if (isGenericType && genericTypeDefinition == typeof(Dictionary<,>)) | ||
{ | ||
typeConverter = new IDictionaryGenericConverter(); | ||
return true; | ||
} | ||
|
||
if (isGenericType && genericTypeDefinition == typeof(IDictionary<,>)) | ||
{ | ||
typeConverter = new IDictionaryGenericConverter(); | ||
return true; | ||
} | ||
|
||
if (isGenericType && genericTypeDefinition == typeof(List<>)) | ||
{ | ||
typeConverter = new CollectionGenericConverter(); | ||
return true; | ||
} | ||
|
||
if (isGenericType && genericTypeDefinition == typeof(Collection<>)) | ||
{ | ||
typeConverter = new CollectionGenericConverter(); | ||
return true; | ||
} | ||
|
||
if (isGenericType && genericTypeDefinition == typeof(IList<>)) | ||
{ | ||
typeConverter = new IEnumerableGenericConverter(); | ||
return true; | ||
} | ||
|
||
if (isGenericType && genericTypeDefinition == typeof(ICollection<>)) | ||
{ | ||
typeConverter = new IEnumerableGenericConverter(); | ||
return true; | ||
} | ||
|
||
if (isGenericType && genericTypeDefinition == typeof(IEnumerable<>)) | ||
{ | ||
typeConverter = new IEnumerableGenericConverter(); | ||
return true; | ||
} | ||
|
||
// A specific IEnumerable converter doesn't exist. | ||
if (typeof(IEnumerable).IsAssignableFrom(type)) | ||
{ | ||
typeConverter = new EnumerableConverter(); | ||
return true; | ||
} | ||
|
||
throw new InvalidOperationException($"Cannot create collection converter for type '{type.FullName}'."); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright 2009-2022 Josh Close | ||
// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0. | ||
// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0. | ||
// https://github.com/JoshClose/CsvHelper | ||
using System; | ||
|
||
namespace CsvHelper.TypeConversion | ||
{ | ||
/// <inheritdoc /> | ||
public class EnumConverterFactory : ITypeConverterFactory | ||
{ | ||
/// <inheritdoc /> | ||
public bool CanCreate(Type type) | ||
{ | ||
return typeof(Enum).IsAssignableFrom(type); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public bool Create(Type type, TypeConverterCache cache, out ITypeConverter typeConverter) | ||
{ | ||
if (cache.Contains(typeof(Enum))) | ||
{ | ||
// If the user has registered a converter for the generic Enum type, | ||
// that converter will be used as a default for all enums. | ||
typeConverter = cache.GetConverter<Enum>(); | ||
|
||
return false; | ||
} | ||
|
||
typeConverter = new EnumConverter(type); | ||
|
||
return true; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,28 @@ | ||
using System; | ||
// Copyright 2009-2022 Josh Close | ||
// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0. | ||
// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0. | ||
// https://github.com/JoshClose/CsvHelper | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace CsvHelper.TypeConversion | ||
{ | ||
/// <summary> | ||
/// Converter factory for nullable types | ||
/// </summary> | ||
/// <inheritdoc /> | ||
public class NullableConverterFactory : ITypeConverterFactory | ||
{ | ||
/// <summary> | ||
/// Produces <see cref="ITypeConverter"/> for the specified <see cref="System.Type"/>. | ||
/// </summary> | ||
/// <param name="type"><see cref="System.Type"/> we want <see cref="ITypeConverter"/> for</param> | ||
/// <param name="typeConverterCache"><see cref="TypeConverterCache"/> that is used for retrieving already exising type converters that are used to build the new one</param> | ||
/// <returns>Created <see cref="ITypeConverter"/> for the specified <see cref="System.Type"/></returns> | ||
public ITypeConverter CreateTypeConverter(Type type, TypeConverterCache typeConverterCache) | ||
/// <inheritdoc /> | ||
public bool CanCreate(Type type) | ||
{ | ||
return new NullableConverter(type, typeConverterCache); | ||
return (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>))); | ||
} | ||
|
||
/// <summary> | ||
/// Checks whether the type is handled by <see cref="NullableConverterFactory"/>. | ||
/// </summary> | ||
/// <param name="type"><see cref="System.Type"/> to be checked</param> | ||
/// <returns>Whether the type is handled by <see cref="NullableConverterFactory"/></returns> | ||
public bool Handles(Type type) | ||
/// <inheritdoc /> | ||
public bool Create(Type type, TypeConverterCache cache, out ITypeConverter typeConverter) | ||
{ | ||
return (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>))); | ||
typeConverter = new NullableConverter(type, cache); | ||
|
||
return true; | ||
} | ||
} | ||
} |
Oops, something went wrong.