public DelegateData(Type type, TypeName className, TypeName interfaceName, TypeBuildStatus buildStatus, WrapperBuilder builder, HashSet <TypeData> typeDatas) : base(type, className, interfaceName, buildStatus) { var invokeMethod = type.GetMethod("Invoke"); ReturnType = builder.GetTypeData(invokeMethod.ReturnType, typeDatas); DependentTypes.UnionWith(ReturnType.GetPublicTypes()); var parameterInfos = invokeMethod.GetParameters(); if (parameterInfos?.Length > 0) { foreach (var parameter in parameterInfos) { var parameterType = parameter.ParameterType; var parameterTypeData = builder.GetTypeData(parameterType, typeDatas); DependentTypes.UnionWith(parameterTypeData.GetPublicTypes()); Parameters.Add(new ParameterData(parameterTypeData, parameter.Name, parameter.IsOut)); } } }
public override async Task BuildAsync(WrapperBuilder builder, HashSet <TypeData> typeDatas, Func <Type, string, CancellationToken, Task <TextWriter> > writerProvider, CancellationToken cancellationToken = default) { if (builder.BuildCollectionWrappersAsNecessary) { BuildStatus = TypeBuildStatus.Building; using (var writer = await writerProvider(typeof(Array), "WrapIt.Collections.ListWrapperBase", cancellationToken).ConfigureAwait(false)) { await writer.WriteAsync(@"using System.Collections.Generic; namespace WrapIt.Collections { public abstract class ListWrapperBase<T, TWrapped, TInterface> : CollectionWrapper<T, TWrapped, TInterface>, IList<TInterface>, IReadOnlyList<TInterface> where TWrapped : TInterface { internal new IListWrapperBaseInternal InternalWrapper => (IListWrapperBaseInternal)base.InternalWrapper; public TWrapped this[int index] { get => InternalWrapper[index]; set => InternalWrapper[index] = value; } TInterface IList<TInterface>.this[int index] { get => this[index]; set => this[index] = (TWrapped)value; } TInterface IReadOnlyList<TInterface>.this[int index] => this[index]; internal ListWrapperBase(IListWrapperBaseInternal internalWrapper) : base(internalWrapper) { } public int IndexOf(TWrapped item) => InternalWrapper.IndexOf(item); int IList<TInterface>.IndexOf(TInterface item) => IndexOf((TWrapped)item); void IList<TInterface>.Insert(int index, TInterface item) => InternalWrapper.Insert(index, (TWrapped)item); void IList<TInterface>.RemoveAt(int index) => InternalWrapper.RemoveAt(index); internal interface IListWrapperBaseInternal : ICollectionWrapperInternal, IList<TWrapped> { } } }").ConfigureAwait(false); await writer.FlushAsync().ConfigureAwait(false); } } BuildStatus = TypeBuildStatus.Built; var collectionWrapperData = builder.GetTypeData(typeof(CollectionWrapperData), typeDatas); if (collectionWrapperData.BuildStatus != TypeBuildStatus.Built) { await collectionWrapperData.BuildAsync(builder, typeDatas, writerProvider, cancellationToken).ConfigureAwait(false); } }
public ListData(Type type, TypeName className, TypeName interfaceName, TypeData elementType, WrapperBuilder builder, HashSet <TypeData> typeDatas) : base(type, className, interfaceName, TypeBuildStatus.NotYetBuilt) { var listWrapperData = builder.GetTypeData(typeof(ListWrapperData), typeDatas); if (listWrapperData.BuildStatus == TypeBuildStatus.NotBuilding) { listWrapperData.BuildStatus = TypeBuildStatus.NotYetBuilt; } DependentTypes.UnionWith(listWrapperData.GetPublicTypes()); ElementType = elementType; DependentTypes.UnionWith(elementType.GetPublicTypes()); }
public DictionaryData(Type type, TypeName className, TypeName interfaceName, TypeData keyType, TypeData valueType, WrapperBuilder builder, HashSet <TypeData> typeDatas) : base(type, className, interfaceName, TypeBuildStatus.NotYetBuilt) { var dictionaryWrapperData = builder.GetTypeData(typeof(DictionaryWrapperData), typeDatas); if (dictionaryWrapperData.BuildStatus == TypeBuildStatus.NotBuilding) { dictionaryWrapperData.BuildStatus = TypeBuildStatus.NotYetBuilt; } DependentTypes.UnionWith(dictionaryWrapperData.GetPublicTypes()); KeyType = keyType; DependentTypes.UnionWith(keyType.GetPublicTypes()); ValueType = valueType; DependentTypes.UnionWith(valueType.GetPublicTypes()); }
public override async Task BuildAsync(WrapperBuilder builder, HashSet <TypeData> typeDatas, Func <Type, string, CancellationToken, Task <TextWriter> > writerProvider, CancellationToken cancellationToken = default) { if (builder.BuildCollectionWrappersAsNecessary) { BuildStatus = TypeBuildStatus.Building; using (var writer = await writerProvider(typeof(Array), "WrapIt.Collections.ListWrapper", cancellationToken).ConfigureAwait(false)) { await writer.WriteAsync(@"using System; using System.Collections.Generic; using System.Linq; namespace WrapIt.Collections { public sealed class ListWrapper<T, TWrapped, TInterface> : ListWrapperBase<T, TWrapped, TInterface>, IList<TInterface> where TWrapped : TInterface { public static implicit operator ListWrapper<T, TWrapped, TInterface>(List<T> list) => list != null ? new ListWrapper<T, TWrapped, TInterface>(list) : null; public static implicit operator List<T>(ListWrapper<T, TWrapped, TInterface> listWrapper) => listWrapper?.ToList(); public static ListWrapper<T, TWrapped, TInterface> Create(IList<T> list) => list != null ? new ListWrapper<T, TWrapped, TInterface>(list) : null; public static ListWrapper<T, TWrapped, TInterface> Create(IList<TInterface> list) => list != null ? new ListWrapper<T, TWrapped, TInterface>(list) : null; internal new IListWrapperInternal InternalWrapper => (IListWrapperInternal)base.InternalWrapper; public ListWrapper(IList<T> list) : base(new StandardListWrapperInternal(list ?? throw new ArgumentNullException(nameof(list)))) { } public ListWrapper(IList<TInterface> list) : base(new CastedListWrapperInternal(list ?? throw new ArgumentNullException(nameof(list)))) { } public List<T> ToList() => InternalWrapper.ToList(); public void Insert(int index, TWrapped item) => InternalWrapper.Insert(index, item); void IList<TInterface>.Insert(int index, TInterface item) => Insert(index, (TWrapped)item); public void RemoveAt(int index) => InternalWrapper.RemoveAt(index); internal interface IListWrapperInternal : IListWrapperBaseInternal { List<T> ToList(); } private sealed class StandardListWrapperInternal : StandardCollectionWrapperInternal, IListWrapperInternal { private readonly IList<T> _list; public TWrapped this[int index] { get => Conversion<T, TWrapped>.Wrap(_list[index]); set => _list[index] = Conversion<T, TWrapped>.Unwrap(value); } public StandardListWrapperInternal(IList<T> list) : base(list) { _list = list; } public List<T> ToList() => _list as List<T> ?? _list.ToList(); public int IndexOf(TWrapped item) => _list.IndexOf(Conversion<T, TWrapped>.Unwrap(item)); public void Insert(int index, TWrapped item) => _list.Insert(index, Conversion<T, TWrapped>.Unwrap(item)); public void RemoveAt(int index) => _list.RemoveAt(index); } private sealed class CastedListWrapperInternal : CastedCollectionWrapperInternal, IListWrapperInternal { private readonly IList<TInterface> _list; public TWrapped this[int index] { get => (TWrapped)_list[index]; set => _list[index] = value; } public CastedListWrapperInternal(IList<TInterface> list) : base(list) { _list = list; } public List<T> ToList() => (List<T>)ToCollection(); public int IndexOf(TWrapped item) => _list.IndexOf(item); public void Insert(int index, TWrapped item) => _list.Insert(index, item); public void RemoveAt(int index) => _list.RemoveAt(index); } } }").ConfigureAwait(false); await writer.FlushAsync().ConfigureAwait(false); } } BuildStatus = TypeBuildStatus.Built; var listWrapperBaseData = builder.GetTypeData(typeof(ListWrapperBaseData), typeDatas); if (listWrapperBaseData.BuildStatus != TypeBuildStatus.Built) { await listWrapperBaseData.BuildAsync(builder, typeDatas, writerProvider, cancellationToken).ConfigureAwait(false); } }
public override async Task BuildAsync(WrapperBuilder builder, HashSet <TypeData> typeDatas, Func <Type, string, CancellationToken, Task <TextWriter> > writerProvider, CancellationToken cancellationToken = default) { if (builder.BuildCollectionWrappersAsNecessary) { BuildStatus = TypeBuildStatus.Building; using (var writer = await writerProvider(typeof(Array), "WrapIt.Collections.ArrayWrapper", cancellationToken).ConfigureAwait(false)) { await writer.WriteAsync(@"using System; using System.Collections.Generic; namespace WrapIt.Collections { public sealed class ArrayWrapper<T, TWrapped, TInterface> : ListWrapperBase<T, TWrapped, TInterface> where TWrapped : TInterface { public static implicit operator ArrayWrapper<T, TWrapped, TInterface>(T[] array) => array != null ? new ArrayWrapper<T, TWrapped, TInterface>(array) : null; public static implicit operator T[](ArrayWrapper<T, TWrapped, TInterface> arrayWrapper) => arrayWrapper?.ToArray(); public static ArrayWrapper<T, TWrapped, TInterface> Create(T[] array) => array; public static ArrayWrapper<T, TWrapped, TInterface> Create(IList<TInterface> list) => list != null ? new ArrayWrapper<T, TWrapped, TInterface>(list) : null; internal new IArrayWrapperInternal InternalWrapper => (IArrayWrapperInternal)base.InternalWrapper; public ArrayWrapper(T[] array) : base(new StandardArrayWrapperInternal(array ?? throw new ArgumentNullException(nameof(array)))) { } public ArrayWrapper(IList<TInterface> list) : base(new CastedArrayWrapperInternal(list ?? throw new ArgumentNullException(nameof(list)))) { } public T[] ToArray() => InternalWrapper.ToArray(); internal interface IArrayWrapperInternal : IListWrapperBaseInternal { T[] ToArray(); } private sealed class StandardArrayWrapperInternal : StandardCollectionWrapperInternal, IArrayWrapperInternal { private readonly T[] _array; public TWrapped this[int index] { get => Conversion<T, TWrapped>.Wrap(_array[index]); set => _array[index] = Conversion<T, TWrapped>.Unwrap(value); } public StandardArrayWrapperInternal(T[] array) : base(array) { _array = array; } public T[] ToArray() => _array; public int IndexOf(TWrapped item) => Array.IndexOf(_array, Conversion<T, TWrapped>.Unwrap(item)); public void Insert(int index, TWrapped item) => throw new NotSupportedException(); public void RemoveAt(int index) => throw new NotSupportedException(); } private sealed class CastedArrayWrapperInternal : CastedCollectionWrapperInternal, IArrayWrapperInternal { private readonly IList<TInterface> _list; public TWrapped this[int index] { get => (TWrapped)_list[index]; set => _list[index] = value; } public override bool IsReadOnly => true; public CastedArrayWrapperInternal(IList<TInterface> list) : base(list) { _list = list; } public override ICollection<T> ToCollection() => ToArray(); public T[] ToArray() { var array = new T[Count]; var i = 0; foreach (var item in _list) { array[i] = Conversion<T, TWrapped>.Unwrap((TWrapped)item); ++i; } return array; } public int IndexOf(TWrapped item) => _list.IndexOf(item); public void Insert(int index, TWrapped item) => throw new NotSupportedException(); public void RemoveAt(int index) => throw new NotSupportedException(); public override void Add(TWrapped item) => throw new NotSupportedException(); public override void Clear() => throw new NotSupportedException(); public override bool Remove(TWrapped item) => throw new NotSupportedException(); } } }").ConfigureAwait(false); await writer.FlushAsync().ConfigureAwait(false); } } BuildStatus = TypeBuildStatus.Built; var listWrapperBaseData = builder.GetTypeData(typeof(ListWrapperBaseData), typeDatas); if (listWrapperBaseData.BuildStatus != TypeBuildStatus.Built) { await listWrapperBaseData.BuildAsync(builder, typeDatas, writerProvider, cancellationToken).ConfigureAwait(false); } }
public void Initialize(WrapperBuilder builder, HashSet <TypeData> typeDatas, BindingFlags bindingFlags) { if (_initialized) { return; } var isIEnumerable = false; var isGenericIEnumerable = false; foreach (var @interface in Type.GetInterfaces()) { if (@interface.IsPublic && !builder.AssembliesWithTypesToWrap.Contains(@interface.Assembly) && builder.InterfaceResolver?.Invoke(Type, @interface) != false) { if (!isIEnumerable && @interface == typeof(IEnumerable)) { isIEnumerable = true; } if (!isGenericIEnumerable && @interface.IsGenericType && @interface.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { isGenericIEnumerable = true; } var interfaceTypeData = (InterfaceData)builder.GetTypeData(@interface, typeDatas); interfaceTypeData.Initialize(builder, typeDatas, bindingFlags); Interfaces.Add(interfaceTypeData); } } var propertyInfos = Type.GetProperties(bindingFlags); foreach (var property in propertyInfos) { if (property.GetAccessors().All(a => IncludeMethod(builder, a, typeDatas, out _)) && builder.PropertyResolver?.Invoke(Type, property) != false) { var propertyType = property.PropertyType; var propertyTypeData = builder.GetTypeData(propertyType, typeDatas); DependentTypes.UnionWith(propertyTypeData.GetPublicTypes()); var indexParameters = property.GetIndexParameters(); var parameters = new List <ParameterData>(); if (indexParameters?.Length > 0) { foreach (var parameter in indexParameters) { var parameterType = parameter.ParameterType; var parameterTypeData = builder.GetTypeData(parameterType, typeDatas); DependentTypes.UnionWith(parameterTypeData.GetPublicTypes()); parameters.Add(new ParameterData(parameterTypeData, parameter.Name, parameter.IsOut)); } } var propertyData = new PropertyData(propertyTypeData, property.Name, property.GetGetMethod() != null, property.GetSetMethod() != null, parameters); foreach (var @interface in Interfaces) { if (@interface.Properties.Any(p => p.Equals(propertyData))) { propertyData.DeclaringInterfaceType = @interface; } } Properties.Add(propertyData); } } Properties = Properties.Distinct().OrderBy(p => p.Name).ToList(); var methodInfos = Type.GetMethods(bindingFlags); foreach (var method in methodInfos) { if (method.DeclaringType != typeof(object) && !method.IsSpecialName && IncludeMethod(builder, method, typeDatas, out var overrideObject) && builder.MethodResolver?.Invoke(Type, method) != false) { var returnType = method.ReturnType; var returnTypeData = builder.GetTypeData(returnType, typeDatas); DependentTypes.UnionWith(returnTypeData.GetPublicTypes()); var parameterInfos = method.GetParameters(); var parameters = new List <ParameterData>(); if (parameterInfos?.Length > 0) { foreach (var parameter in parameterInfos) { var parameterType = parameter.ParameterType; var parameterTypeData = builder.GetTypeData(parameterType, typeDatas); DependentTypes.UnionWith(parameterTypeData.GetPublicTypes()); parameters.Add(new ParameterData(parameterTypeData, parameter.Name, parameter.IsOut)); } } var methodData = new MethodData(method.Name, returnTypeData, parameters, overrideObject); foreach (var @interface in Interfaces) { if (@interface.Methods.Any(p => p.Equals(methodData))) { methodData.DeclaringInterfaceType = @interface; } } Methods.Add(methodData); } } if (!Type.IsInterface && isIEnumerable && !isGenericIEnumerable) { var addMethod = Methods.SingleOrDefault(m => m.Name == "Add" && m.Parameters.Count == 1); TypeData?genericArg = null; if (addMethod != null) { genericArg = addMethod.Parameters[0].Type; } var indexers = Properties.Where(p => p.Name == "Item").ToList(); if (genericArg != null || indexers.Count > 0) { genericArg ??= indexers[0].Type; if (indexers.All(i => i.Type.Equals(genericArg))) { var interfaceTypeData = (InterfaceData)builder.GetTypeData(typeof(IEnumerable <>).MakeGenericType(genericArg.Type), typeDatas); interfaceTypeData.Initialize(builder, typeDatas, bindingFlags); Interfaces.Add(interfaceTypeData); for (var i = 0; i < Methods.Count; ++i) { if (Methods[i].Name == "GetEnumerator") { Methods.RemoveAt(i); break; } } } } } Interfaces.Sort((x, y) => string.Compare(x.InterfaceName.Name, y.InterfaceName.Name)); Methods = Methods.Distinct().OrderBy(m => m.Name).ToList(); var eventInfos = Type.GetEvents(bindingFlags); foreach (var @event in eventInfos) { if (IncludeMethod(builder, @event.AddMethod, typeDatas, out _) && IncludeMethod(builder, @event.RemoveMethod, typeDatas, out _) && builder.EventResolver?.Invoke(Type, @event) != false) { var eventHandlerType = @event.EventHandlerType; var eventHandlerTypeData = (DelegateData)builder.GetTypeData(eventHandlerType, typeDatas); DependentTypes.UnionWith(eventHandlerTypeData.GetPublicTypes()); var invokeMethod = eventHandlerType.GetMethod("Invoke"); var returnType = invokeMethod.ReturnType; var returnTypeData = builder.GetTypeData(returnType, typeDatas); DependentTypes.UnionWith(returnTypeData.GetPublicTypes()); var parameterInfos = invokeMethod.GetParameters(); var parameters = new List <ParameterData>(); if (parameterInfos?.Length > 0) { foreach (var parameter in parameterInfos) { var parameterType = parameter.ParameterType; var parameterTypeData = builder.GetTypeData(parameterType, typeDatas); DependentTypes.UnionWith(parameterTypeData.GetPublicTypes()); parameters.Add(new ParameterData(parameterTypeData, parameter.Name, parameter.IsOut)); } } var eventData = new EventData(eventHandlerTypeData, @event.Name); foreach (var @interface in Interfaces) { if (@interface.Events.Any(e => e.Equals(eventData))) { eventData.DeclaringInterfaceType = @interface; } } Events.Add(eventData); } } Events = Events.Distinct().OrderBy(e => e.Name).ToList(); _initialized = true; }
public override async Task BuildAsync(WrapperBuilder builder, HashSet <TypeData> typeDatas, Func <Type, string, CancellationToken, Task <TextWriter> > writerProvider, CancellationToken cancellationToken = default) { if (builder.BuildCollectionWrappersAsNecessary) { BuildStatus = TypeBuildStatus.Building; using (var writer = await writerProvider(typeof(Array), "WrapIt.Collections.DictionaryWrapper", cancellationToken).ConfigureAwait(false)) { await writer.WriteAsync(@"using System; using System.Collections; using System.Collections.Generic; namespace WrapIt.Collections { public sealed class DictionaryWrapper<TKey, TValue, TValueWrapped, TValueInterface> : IDictionary<TKey, TValueInterface>, IReadOnlyDictionary<TKey, TValueInterface> where TValueWrapped : TValueInterface { public static implicit operator DictionaryWrapper<TKey, TValue, TValueWrapped, TValueInterface>(Dictionary<TKey, TValue> dictionary) => dictionary != null ? new DictionaryWrapper<TKey, TValue, TValueWrapped, TValueInterface>(dictionary) : null; public static implicit operator Dictionary<TKey, TValue>(DictionaryWrapper<TKey, TValue, TValueWrapped, TValueInterface> dictionaryWrapper) => dictionaryWrapper?.ToDictionary(); public static DictionaryWrapper<TKey, TValue, TValueWrapped, TValueInterface> Create(IDictionary<TKey, TValue> dictionary) => dictionary != null ? new DictionaryWrapper<TKey, TValue, TValueWrapped, TValueInterface>(dictionary) : null; public static DictionaryWrapper<TKey, TValue, TValueWrapped, TValueInterface> Create(IDictionary<TKey, TValueInterface> dictionary) => dictionary != null ? new DictionaryWrapper<TKey, TValue, TValueWrapped, TValueInterface>(dictionary) : null; internal IDictionaryWrapperInternal InternalWrapper { get; } public TValueWrapped this[TKey key] { get => InternalWrapper[key]; set => InternalWrapper[key] = value; } TValueInterface IDictionary<TKey, TValueInterface>.this[TKey key] { get => this[key]; set => this[key] = (TValueWrapped)value; } TValueInterface IReadOnlyDictionary<TKey, TValueInterface>.this[TKey key] => this[key]; public ICollection<TKey> Keys => InternalWrapper.Keys; public CollectionWrapper<TValue, TValueWrapped, TValueInterface> Values => InternalWrapper.Values; IEnumerable<TKey> IReadOnlyDictionary<TKey, TValueInterface>.Keys => Keys; ICollection<TValueInterface> IDictionary<TKey, TValueInterface>.Values => Values; IEnumerable<TValueInterface> IReadOnlyDictionary<TKey, TValueInterface>.Values => Values; public int Count => InternalWrapper.Count; bool ICollection<KeyValuePair<TKey, TValueInterface>>.IsReadOnly => InternalWrapper.IsReadOnly; public DictionaryWrapper(IDictionary<TKey, TValue> dictionary) { InternalWrapper = new StandardDictionaryWrapper(dictionary ?? throw new ArgumentNullException(nameof(dictionary))); } public DictionaryWrapper(IDictionary<TKey, TValueInterface> dictionary) { InternalWrapper = new CastedDictionaryWrapper(dictionary ?? throw new ArgumentNullException(nameof(dictionary))); } public Dictionary<TKey, TValue> ToDictionary() => InternalWrapper.ToDictionary(); public IEnumerator<KeyValuePair<TKey, TValueWrapped>> GetEnumerator() => InternalWrapper.GetEnumerator(); IEnumerator<KeyValuePair<TKey, TValueInterface>> IEnumerable<KeyValuePair<TKey, TValueInterface>>.GetEnumerator() { foreach (var item in this) { yield return new KeyValuePair<TKey, TValueInterface>(item.Key, item.Value); } } IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<KeyValuePair<TKey, TValueInterface>>)this).GetEnumerator(); public void Add(TKey key, TValueWrapped value) => InternalWrapper.Add(key, value); void IDictionary<TKey, TValueInterface>.Add(TKey key, TValueInterface value) => Add(key, (TValueWrapped)value); void ICollection<KeyValuePair<TKey, TValueInterface>>.Add(KeyValuePair<TKey, TValueInterface> item) => Add(item.Key, (TValueWrapped)item.Value); public void Clear() => InternalWrapper.Clear(); bool ICollection<KeyValuePair<TKey, TValueInterface>>.Contains(KeyValuePair<TKey, TValueInterface> item) => TryGetValue(item.Key, out var value) && EqualityComparer<TValue>.Default.Equals(Conversion<TValue, TValueWrapped>.Unwrap(value), Conversion<TValue, TValueWrapped>.Unwrap((TValueWrapped)item.Value)); public bool ContainsKey(TKey key) => InternalWrapper.ContainsKey(key); void ICollection<KeyValuePair<TKey, TValueInterface>>.CopyTo(KeyValuePair<TKey, TValueInterface>[] array, int arrayIndex) { if (arrayIndex + Count > array.Length) { throw new ArgumentOutOfRangeException(""arrayIndex + Count must be less than or equal to array.Length""); } foreach (var pair in this) { array[arrayIndex++] = new KeyValuePair<TKey, TValueInterface>(pair.Key, pair.Value); } } public bool Remove(TKey key) => InternalWrapper.Remove(key); bool ICollection<KeyValuePair<TKey, TValueInterface>>.Remove(KeyValuePair<TKey, TValueInterface> item) => ((ICollection<KeyValuePair<TKey, TValueInterface>>)this).Contains(item) && Remove(item.Key); public bool TryGetValue(TKey key, out TValueWrapped value) => InternalWrapper.TryGetValue(key, out value); bool IDictionary<TKey, TValueInterface>.TryGetValue(TKey key, out TValueInterface value) { var success = TryGetValue(key, out var wrapped); value = wrapped; return success; } bool IReadOnlyDictionary<TKey, TValueInterface>.TryGetValue(TKey key, out TValueInterface value) => ((IDictionary<TKey, TValueInterface>)this).TryGetValue(key, out value); internal interface IDictionaryWrapperInternal : IDictionary<TKey, TValueWrapped> { new CollectionWrapper<TValue, TValueWrapped, TValueInterface> Values { get; } Dictionary<TKey, TValue> ToDictionary(); } private sealed class StandardDictionaryWrapper : IDictionaryWrapperInternal { private readonly IDictionary<TKey, TValue> _dictionary; public TValueWrapped this[TKey key] { get => Conversion<TValue, TValueWrapped>.Wrap(_dictionary[key]); set => _dictionary[key] = Conversion<TValue, TValueWrapped>.Unwrap(value); } public ICollection<TKey> Keys => _dictionary.Keys; public CollectionWrapper<TValue, TValueWrapped, TValueInterface> Values => new CollectionWrapper<TValue, TValueWrapped, TValueInterface>(_dictionary.Values); ICollection<TValueWrapped> IDictionary<TKey, TValueWrapped>.Values => throw new NotSupportedException(); public int Count => _dictionary.Count; public bool IsReadOnly => _dictionary.IsReadOnly; public StandardDictionaryWrapper(IDictionary<TKey, TValue> dictionary) { _dictionary = dictionary; } public void Add(TKey key, TValueWrapped value) => _dictionary.Add(key, Conversion<TValue, TValueWrapped>.Unwrap(value)); public bool ContainsKey(TKey key) => _dictionary.ContainsKey(key); public bool Remove(TKey key) => _dictionary.Remove(key); public bool TryGetValue(TKey key, out TValueWrapped value) { var success = _dictionary.TryGetValue(key, out var actual); value = Conversion<TValue, TValueWrapped>.Wrap(actual); return success; } public Dictionary<TKey, TValue> ToDictionary() => _dictionary as Dictionary<TKey, TValue> ?? new Dictionary<TKey, TValue>(_dictionary); public ICollection<KeyValuePair<TKey, TValue>> ToCollection() => _dictionary; public void Add(KeyValuePair<TKey, TValueWrapped> item) => Add(item.Key, item.Value); public void Clear() => _dictionary.Clear(); public bool Contains(KeyValuePair<TKey, TValueWrapped> item) => throw new NotSupportedException(); public void CopyTo(KeyValuePair<TKey, TValueWrapped>[] array, int arrayIndex) => throw new NotSupportedException(); public bool Remove(KeyValuePair<TKey, TValueWrapped> item) => throw new NotSupportedException(); public IEnumerator<KeyValuePair<TKey, TValueWrapped>> GetEnumerator() { foreach (var pair in _dictionary) { yield return new KeyValuePair<TKey, TValueWrapped>(pair.Key, Conversion<TValue, TValueWrapped>.Wrap(pair.Value)); } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } private sealed class CastedDictionaryWrapper : IDictionaryWrapperInternal { private readonly IDictionary<TKey, TValueInterface> _dictionary; public TValueWrapped this[TKey key] { get => (TValueWrapped)_dictionary[key]; set => _dictionary[key] = value; } public ICollection<TKey> Keys => _dictionary.Keys; public CollectionWrapper<TValue, TValueWrapped, TValueInterface> Values => new CollectionWrapper<TValue, TValueWrapped, TValueInterface>(_dictionary.Values); ICollection<TValueWrapped> IDictionary<TKey, TValueWrapped>.Values => throw new NotSupportedException(); public int Count => _dictionary.Count; public bool IsReadOnly => _dictionary.IsReadOnly; public CastedDictionaryWrapper(IDictionary<TKey, TValueInterface> dictionary) { _dictionary = dictionary; } public ICollection<KeyValuePair<TKey, TValue>> ToCollection() => ToDictionary(); public void Add(TKey key, TValueWrapped value) => _dictionary.Add(key, value); public bool ContainsKey(TKey key) => _dictionary.ContainsKey(key); public bool Remove(TKey key) => _dictionary.Remove(key); public bool TryGetValue(TKey key, out TValueWrapped value) { var success = _dictionary.TryGetValue(key, out var v); value = (TValueWrapped)v; return success; } public Dictionary<TKey, TValue> ToDictionary() { var dictionary = new Dictionary<TKey, TValue>(_dictionary.Count); foreach (var item in _dictionary) { dictionary[item.Key] = Conversion<TValue, TValueWrapped>.Unwrap((TValueWrapped)item.Value); } return dictionary; } public void Add(KeyValuePair<TKey, TValueWrapped> item) => Add(item.Key, item.Value); public void Clear() => _dictionary.Clear(); public bool Contains(KeyValuePair<TKey, TValueWrapped> item) => throw new NotSupportedException(); public void CopyTo(KeyValuePair<TKey, TValueWrapped>[] array, int arrayIndex) => throw new NotSupportedException(); public bool Remove(KeyValuePair<TKey, TValueWrapped> item) => throw new NotSupportedException(); public IEnumerator<KeyValuePair<TKey, TValueWrapped>> GetEnumerator() { foreach (var item in _dictionary) { yield return new KeyValuePair<TKey, TValueWrapped>(item.Key, (TValueWrapped)item.Value); } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } } }").ConfigureAwait(false); await writer.FlushAsync().ConfigureAwait(false); } } BuildStatus = TypeBuildStatus.Built; var collectionWrapperData = builder.GetTypeData(typeof(CollectionWrapperData), typeDatas); if (collectionWrapperData.BuildStatus != TypeBuildStatus.Built) { await collectionWrapperData.BuildAsync(builder, typeDatas, writerProvider, cancellationToken).ConfigureAwait(false); } }
public override async Task BuildAsync(WrapperBuilder builder, HashSet <TypeData> typeDatas, Func <Type, string, CancellationToken, Task <TextWriter> > writerProvider, CancellationToken cancellationToken = default) { if (builder.BuildCollectionWrappersAsNecessary) { BuildStatus = TypeBuildStatus.Building; using (var writer = await writerProvider(typeof(Array), "WrapIt.Collections.CollectionWrapper", cancellationToken).ConfigureAwait(false)) { await writer.WriteAsync(@"using System; using System.Collections.Generic; namespace WrapIt.Collections { public class CollectionWrapper<T, TWrapped, TInterface> : EnumerableWrapper<T, TWrapped, TInterface>, ICollection<TInterface>, IReadOnlyCollection<TInterface> where TWrapped : TInterface { public static CollectionWrapper<T, TWrapped, TInterface> Create(ICollection<T> collection) => collection != null ? new CollectionWrapper<T, TWrapped, TInterface>(collection) : null; public static CollectionWrapper<T, TWrapped, TInterface> Create(ICollection<TInterface> collection) => collection != null ? new CollectionWrapper<T, TWrapped, TInterface>(collection) : null; internal new ICollectionWrapperInternal InternalWrapper => (ICollectionWrapperInternal)base.InternalWrapper; public int Count => InternalWrapper.Count; bool ICollection<TInterface>.IsReadOnly => InternalWrapper.IsReadOnly; public CollectionWrapper(ICollection<T> collection) : base(new StandardCollectionWrapperInternal(collection ?? throw new ArgumentNullException(nameof(collection)))) { } public CollectionWrapper(ICollection<TInterface> collection) : base(new CastedCollectionWrapperInternal(collection ?? throw new ArgumentNullException(nameof(collection)))) { } internal CollectionWrapper(ICollectionWrapperInternal internalWrapper) : base(internalWrapper) { } public ICollection<T> ToCollection() => InternalWrapper.ToCollection(); IEnumerator<TInterface> IEnumerable<TInterface>.GetEnumerator() { foreach (var item in this) { yield return item; } } public bool Contains(TWrapped item) => InternalWrapper.Contains(item); bool ICollection<TInterface>.Contains(TInterface item) => Contains((TWrapped)item); void ICollection<TInterface>.CopyTo(TInterface[] array, int arrayIndex) { if (arrayIndex + Count > array.Length) { throw new ArgumentOutOfRangeException(""arrayIndex + Count must be less than or equal to array.Length""); } foreach (var item in this) { array[arrayIndex++] = item; } } void ICollection<TInterface>.Add(TInterface item) => InternalWrapper.Add((TWrapped) item); void ICollection<TInterface>.Clear() => InternalWrapper.Clear(); bool ICollection<TInterface>.Remove(TInterface item) => InternalWrapper.Remove((TWrapped) item); internal interface ICollectionWrapperInternal : IEnumerableWrapperInternal, ICollection<TWrapped> { ICollection<T> ToCollection(); } internal class StandardCollectionWrapperInternal : StandardEnumerableWrapperInternal, ICollectionWrapperInternal { private readonly ICollection<T> _collection; public int Count => _collection.Count; public virtual bool IsReadOnly => _collection.IsReadOnly; public StandardCollectionWrapperInternal(ICollection<T> collection) : base(collection) { _collection = collection; } public virtual ICollection<T> ToCollection() => _collection; public bool Contains(TWrapped item) => _collection.Contains(Conversion<T, TWrapped>.Unwrap(item)); public virtual void Add(TWrapped item) => _collection.Add(Conversion<T, TWrapped>.Unwrap(item)); public virtual void Clear() => _collection.Clear(); public virtual bool Remove(TWrapped item) => _collection.Remove(Conversion<T, TWrapped>.Unwrap(item)); void ICollection<TWrapped>.CopyTo(TWrapped[] array, int arrayIndex) => throw new NotSupportedException(); } internal class CastedCollectionWrapperInternal : CastedEnumerableWrapperInternal, ICollectionWrapperInternal { private readonly ICollection<TInterface> _collection; public int Count => _collection.Count; public virtual bool IsReadOnly => _collection.IsReadOnly; public CastedCollectionWrapperInternal(ICollection<TInterface> collection) : base(collection) { _collection = collection; } public override IEnumerable<T> ToEnumerable() => ToCollection(); public virtual ICollection<T> ToCollection() { var list = new List<T>(Count); foreach (var item in _collection) { list.Add(Conversion<T, TWrapped>.Unwrap((TWrapped)item)); } return list; } public bool Contains(TWrapped item) => _collection.Contains(item); public virtual void Add(TWrapped item) => _collection.Add(item); public virtual void Clear() => _collection.Clear(); public virtual bool Remove(TWrapped item) => _collection.Remove(item); void ICollection<TWrapped>.CopyTo(TWrapped[] array, int arrayIndex) => throw new NotSupportedException(); } } }").ConfigureAwait(false); await writer.FlushAsync().ConfigureAwait(false); } } BuildStatus = TypeBuildStatus.Built; var enumerableWrapperData = builder.GetTypeData(typeof(EnumerableWrapperData), typeDatas); if (enumerableWrapperData.BuildStatus != TypeBuildStatus.Built) { await enumerableWrapperData.BuildAsync(builder, typeDatas, writerProvider, cancellationToken).ConfigureAwait(false); } }