MixinData
using Castle.DynamicProxy.Generators;
using Castle.DynamicProxy.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace Castle.DynamicProxy
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public class MixinData
{
private readonly Dictionary<Type, int> mixinPositions = new Dictionary<Type, int>();
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})]
private readonly List<object> mixinsImpl = new List<object>();
private int delegateMixinCount;
public IEnumerable<Type> MixinInterfaces => mixinPositions.Keys;
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})]
public IEnumerable<object> Mixins {
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})]
get {
return mixinsImpl;
}
}
public MixinData([System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})] IEnumerable<object> mixinInstances)
{
if (mixinInstances != null) {
List<Type> list = new List<Type>();
Dictionary<Type, object> dictionary = new Dictionary<Type, object>();
delegateMixinCount = 0;
foreach (object mixinInstance in mixinInstances) {
Type[] array;
object value;
if (mixinInstance is Delegate) {
delegateMixinCount++;
array = new Type[1] {
mixinInstance.GetType()
};
value = mixinInstance;
} else {
Type type = mixinInstance as Type;
if ((object)type != null && type.IsDelegateType()) {
delegateMixinCount++;
array = new Type[1] {
type
};
value = null;
} else {
array = mixinInstance.GetType().GetInterfaces();
value = mixinInstance;
}
}
Type[] array2 = array;
foreach (Type type2 in array2) {
list.Add(type2);
if (dictionary.TryGetValue(type2, out object value2)) {
string message = (value2 == null) ? $"""{type2.FullName}""" : $"""{type2.FullName}""{value2.GetType().Name}""{mixinInstance.GetType().Name}""";
throw new ArgumentException(message, "mixinInstances");
}
dictionary[type2] = value;
}
}
if (delegateMixinCount > 1) {
HashSet<MethodInfo> hashSet = new HashSet<MethodInfo>();
foreach (Type key2 in dictionary.Keys) {
if (key2.IsDelegateType()) {
MethodInfo method = key2.GetMethod("Invoke");
if (hashSet.Contains(method, MethodSignatureComparer.Instance))
throw new ArgumentException("The list of mixins contains at least two delegate mixins for the same delegate signature.", "mixinInstances");
hashSet.Add(method);
}
}
}
list.Sort((Type x, Type y) => string.CompareOrdinal(x.FullName, y.FullName));
for (int j = 0; j < list.Count; j++) {
Type key = list[j];
object item = dictionary[key];
mixinPositions[key] = j;
mixinsImpl.Add(item);
}
}
}
public bool ContainsMixin(Type mixinInterfaceType)
{
return mixinPositions.ContainsKey(mixinInterfaceType);
}
[System.Runtime.CompilerServices.NullableContext(2)]
public override bool Equals(object obj)
{
if (this == obj)
return true;
MixinData mixinData = obj as MixinData;
if (mixinData == null)
return false;
if (mixinsImpl.Count != mixinData.mixinsImpl.Count)
return false;
if (delegateMixinCount != mixinData.delegateMixinCount)
return false;
for (int i = 0; i < mixinsImpl.Count; i++) {
if (mixinsImpl[i]?.GetType() != mixinData.mixinsImpl[i]?.GetType())
return false;
}
if (delegateMixinCount > 0) {
IEnumerable<Type> first = (from m in mixinPositions
select m.Key).Where(TypeUtil.IsDelegateType);
IEnumerable<Type> second = (from m in mixinData.mixinPositions
select m.Key).Where(TypeUtil.IsDelegateType);
return first.SequenceEqual(second);
}
return true;
}
public override int GetHashCode()
{
int num = 0;
foreach (object item in mixinsImpl) {
num = (29 * num + item?.GetType().GetHashCode()).GetValueOrDefault(307);
}
return num;
}
[return: System.Runtime.CompilerServices.Nullable(2)]
public object GetMixinInstance(Type mixinInterfaceType)
{
return mixinsImpl[mixinPositions[mixinInterfaceType]];
}
public int GetMixinPosition(Type mixinInterfaceType)
{
return mixinPositions[mixinInterfaceType];
}
}
}