GenericDictionaryConverter
using Castle.Core.Configuration;
using Castle.Core.Internal;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
namespace Castle.MicroKernel.SubSystems.Conversion
{
[Serializable]
public class GenericDictionaryConverter : AbstractTypeConverter
{
private class DictionaryHelper<TKey, TValue> : IGenericCollectionConverterHelper
{
private readonly GenericDictionaryConverter parent;
public DictionaryHelper(GenericDictionaryConverter parent)
{
this.parent = parent;
}
public object ConvertConfigurationToCollection(IConfiguration configuration)
{
Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>();
foreach (IConfiguration item in (List<IConfiguration>)configuration.get_Children()) {
string text = ((NameValueCollection)item.get_Attributes())["key"];
if (text == null)
throw new ConverterException("You must provide a key for the dictionary entry");
Type type = typeof(TKey);
if (((NameValueCollection)item.get_Attributes())["keyType"] != null)
type = parent.Context.Composition.PerformConversion<Type>(((NameValueCollection)item.get_Attributes())["keyType"]);
if (!ReflectionUtil.Is<TKey>(type))
throw new ArgumentException(string.Format("Could not create dictionary<{0},{1}> because {2} is not assignable to key type {0}", typeof(TKey), typeof(TValue), type));
TKey key = (TKey)parent.Context.Composition.PerformConversion(text, type);
Type type2 = typeof(TValue);
if (((NameValueCollection)item.get_Attributes())["valueType"] != null)
type2 = parent.Context.Composition.PerformConversion<Type>(((NameValueCollection)item.get_Attributes())["valueType"]);
if (!ReflectionUtil.Is<TValue>(type2))
throw new ArgumentException(string.Format("Could not create dictionary<{0},{1}> because {2} is not assignable to value type {1}", typeof(TKey), typeof(TValue), type2));
if (((List<IConfiguration>)item.get_Children()).Count == 1)
dictionary.Add(key, (TValue)parent.Context.Composition.PerformConversion(((List<IConfiguration>)item.get_Children())[0], type2));
else
dictionary.Add(key, (TValue)parent.Context.Composition.PerformConversion(item.get_Value(), type2));
}
return dictionary;
}
}
public override bool CanHandleType(Type type)
{
if (!type.GetTypeInfo().IsGenericType)
return false;
Type genericTypeDefinition = type.GetGenericTypeDefinition();
if (!(genericTypeDefinition == typeof(IDictionary<, >)))
return genericTypeDefinition == typeof(Dictionary<, >);
return true;
}
public override object PerformConversion(string value, Type targetType)
{
throw new NotImplementedException();
}
public override object PerformConversion(IConfiguration configuration, Type targetType)
{
Type[] genericArguments = targetType.GetGenericArguments();
if (genericArguments.Length != 2)
throw new ConverterException("Expected type with two generic arguments.");
string text = ((NameValueCollection)configuration.get_Attributes())["keyType"];
Type type = genericArguments[0];
string text2 = ((NameValueCollection)configuration.get_Attributes())["valueType"];
Type type2 = genericArguments[1];
if (text != null)
type = base.Context.Composition.PerformConversion<Type>(text);
if (text2 != null)
type2 = base.Context.Composition.PerformConversion<Type>(text2);
return typeof(DictionaryHelper<, >).MakeGenericType(type, type2).CreateInstance<IGenericCollectionConverterHelper>(new object[1] {
this
}).ConvertConfigurationToCollection(configuration);
}
}
}