public class DependencyResolverBuilder
{
//
// 요약:
// 모듈식 등록 프로세스를 위한 도우미 구조체입니다.
public struct DependencyRegistrar
{
private readonly DependencyResolverBuilder m_builder;
private readonly Type m_dependencyType;
internal DependencyRegistrar(DependencyResolverBuilder builder, Type dependencyType)
{
MBiHIp97M4MqqbtZOh.BibDvtQbp();
m_builder = builder.CheckNotNull();
m_dependencyType = dependencyType.CheckNotNull();
}
public DependencyRegistrar AsSelf()
{
m_builder.registerDependency(m_dependencyType, m_dependencyType);
return this;
}
public DependencyRegistrar AsAllInterfaces(bool ignoreNoInterfaces = false)
{
if (m_dependencyType.IsGenericTypeDefinition)
{
throw new DependencyResolverException($"Registering all interface of a generic type definition '{m_dependencyType}' is dangerous.");
}
Type[] interfaces = m_dependencyType.GetInterfaces();
if (interfaces.Length == 0)
{
if (!ignoreNoInterfaces)
{
Log.Error($"Registering all interfaces of type '{m_dependencyType}' that does not implement any " + "interfaces.");
}
return this;
}
Type[] array = interfaces;
foreach (Type type in array)
{
if (type.GetCustomAttributes(typeof(NotGlobalDependencyAttribute), inherit: false).Length == 0)
{
m_builder.registerDependency(m_dependencyType, type);
}
}
return this;
}
public DependencyRegistrar As<T>() where T : class
{
m_builder.registerDependency(m_dependencyType, typeof(T));
return this;
}
public DependencyRegistrar As(Type t)
{
m_builder.registerDependency(m_dependencyType, t);
return this;
}
}
//
// 요약:
// 모듈식 등록 프로세스를 위한 도우미 구조체입니다.
public struct DependencyInstanceRegistrar<T> where T : class
{
private readonly DependencyResolverBuilder m_builder;
private readonly T m_impl;
internal DependencyInstanceRegistrar(DependencyResolverBuilder builder, T implementation)
{
MBiHIp97M4MqqbtZOh.BibDvtQbp();
m_builder = builder.CheckNotNull();
m_impl = implementation.CheckNotNull();
}
public DependencyInstanceRegistrar<T> AsSelf()
{
m_builder.registerDependencyInstance(m_impl, m_impl.GetType());
return this;
}
public DependencyInstanceRegistrar<T> AsSelfAndAllBaseClasses()
{
Type type = m_impl.GetType();
if (type.BaseType == null || type.BaseType == typeof(object))
{
Log.Error($"Registering type '{typeof(T)}' as self and all base classes but the type has no " + "base classes.");
return this;
}
Type type2 = m_impl.GetType();
while (type2 != typeof(object))
{
m_builder.registerDependencyInstance(m_impl, type2);
type2 = type2.BaseType;
}
return this;
}
public DependencyInstanceRegistrar<T> AsAllInterfaces()
{
Type[] interfaces = m_impl.GetType().GetInterfaces();
if (interfaces.Length == 0)
{
Log.Error($"Registering all interfaces of type '{typeof(T)}' that does not implement any interfaces.");
return this;
}
Type[] array = interfaces;
foreach (Type type in array)
{
if (type.GetCustomAttributes(typeof(NotGlobalDependencyAttribute), inherit: false).Length == 0)
{
m_builder.registerDependencyInstance(m_impl, type);
}
}
return this;
}
public DependencyInstanceRegistrar<T> As<U>() where U : class
{
m_builder.registerDependencyInstance(m_impl, typeof(U));
return this;
}
}
//
// 요약:
// 종속성 등록. 키는 종속성 유형이고 값은 인스턴스 유형입니다.
// 하나의 종속성 유형에 여러 유형을 등록할 수 있습니다.
private Dict<Type, Lyst<Type>> m_dependencyRegistrations;
//
// 요약:
// 종속성 유형에 둘 이상의 구현이 등록된 경우 해결할 구현을 지정할 수 있습니다.
// 기본적으로 마지막 것이 해결됩니다.
private Dict<Type, Type> m_dependencyResolvePreferences;
//
// 요약:
// 제네릭 형식 정의에 대한 종속성 등록. 키는 종속성 유형이고 값은 인스턴스 유형입니다.
// 하나의 종속성 유형에 여러 유형을 등록할 수 있습니다.
// 값 배열의 키와 항목은 모두 일반 유형 정의입니다.
private Dict<Type, Lyst<Type>> m_genericDependencyRegistrations;
//
// 요약:
// 이미 인스턴스화된 종속성. 키는 종속성 유형이며 일반적으로 일부 인터페이스입니다.
private Dict<Type, object> m_instancesByRegisteredType;
//
// 요약:
// 이미 인스턴스화된 종속성. 키는 종속성 인스턴스의 실제 유형입니다.
private Dict<Type, object> m_instancesByRealType;
//
// 요약:
// 하나의 어셈블리에 두 개의 모드를 정의하려는 멍청한 프로그래머로 인한 다중 등록을
// 방지하기 위해 전역 종속성이 이미 처리된 어셈블리 목록입니다.
private readonly Set<Assembly> m_registeredGlobalDeps;
private Dict<Type, int> m_registrationOrder;
private readonly Lyst<Func<ParameterInfo, Option<object>>> m_resolvingFunctions;
private Predicate<Type> m_shouldSerialize;
//
// 요약:
// 등록된 데이터에서 Mafi.DependencyResolver를 생성합니다.
public DependencyResolver BuildAndClear()
{
object[] array = new object[0];
object[] array2 = OBqe2IUAeSpOmlOQ4O.TyOaFSuuHy(0, array, this);
return (DependencyResolver)array2[0];
}
public void RegisterExtraResolver(Func<ParameterInfo, Option<object>> resolvingFunction)
{
m_resolvingFunctions.Add(resolvingFunction);
}
public void SetShouldSerializePredicate(Predicate<Type> shouldSerialize)
{
Assert.That(m_shouldSerialize).IsNull("The 'should serialize' predicate can be set only once.");
m_shouldSerialize = shouldSerialize;
}
//
// 요약:
// 모든 종속성 유형 등록을 반환합니다.
// 일부 종속성은 인스턴스로 추가되었을 수 있으며 여기에 나열되지 않습니다.
// 제네릭 형식 정의의 등록을 반환하지 않습니다.
public KeyValuePair<Type, Type[]>[] GetRegistrations()
{
return m_dependencyRegistrations.Select((KeyValuePair<Type, Lyst<Type>> kvp) => new KeyValuePair<Type, Type[]>(kvp.Key, kvp.Value.ToArray())).ToArray();
}
//
// 요약:
// 종속성 유형별로 등록된 모든 인스턴스를 반환합니다.
public KeyValuePair<Type, object>[] GetRegisteredInstancesByDepType()
{
return m_instancesByRegisteredType.ToArray();
}
//
// 요약:
// 등록된 모든 인스턴스를 실제 유형으로 반환합니다.
public KeyValuePair<Type, object>[] GetRegisteredInstancesByRealType()
{
return m_instancesByRealType.ToArray();
}
//
// 요약:
// 종속성이 T에 등록되어 있는지 여부.
public bool IsAnythingRegisteredAs<T>()
{
return IsAnythingRegisteredAs(typeof(T));
}
public bool IsAnythingRegisteredAs(Type t)
{
if (!m_dependencyRegistrations.ContainsKey(t))
{
return m_genericDependencyRegistrations.ContainsKey(t);
}
return true;
}
//
// 요약:
// 주어진 유형 TInst가 TDep로 등록되는지 여부.
public bool IsTypeRegisteredAs<TInst, TDep>()
{
return IsTypeRegisteredAs(typeof(TInst), typeof(TDep));
}
public bool IsTypeRegisteredAs<TDep>(Type tInst)
{
return IsTypeRegisteredAs(tInst, typeof(TDep));
}
public bool IsTypeRegisteredAs(Type tInst, Type tDep)
{
if (m_dependencyRegistrations.TryGetValue(tDep, out var value))
{
return value.Contains(tInst);
}
return false;
}
public void SetPreferredImplementationFor(Type implType, Type depType)
{
Assert.That(implType.IsClass).IsTrue("Global dependency implementation should be a class.");
Assert.That(implType.IsAbstract).IsFalse("Global dependency implementation should not be abstract.");
m_dependencyResolvePreferences[depType] = implType;
}
public void SetPreferredImplementationForAllInterfaces(Type implType)
{
Type[] interfaces = implType.GetInterfaces();
if (interfaces.Length == 0)
{
Log.Error($"Setting preferred implementation for all interfaces of type `{implType}` that does not " + "implement any interfaces.");
return;
}
Type[] array = interfaces;
foreach (Type type in array)
{
if (type.GetCustomAttributes(typeof(NotGlobalDependencyAttribute), inherit: false).Length == 0)
{
Assert.That(type.Name.EndsWith("Friend")).IsFalse("Registering under friend!");
SetPreferredImplementationFor(implType, type);
}
}
}
//
// 요약:
// 지정된 T의 종속성 등록 프로세스를 시작합니다.
// 이 호출은 아직 아무 것도 등록하지 않습니다.
[MustUseReturnValue]
public DependencyRegistrar RegisterDependency<T>() where T : class
{
return RegisterDependency(typeof(T));
}
//
// 요약:
// 주어진 유형의 종속성 등록 프로세스를 시작합니다.
// 이 호출은 아직 아무 것도 등록하지 않습니다.
[MustUseReturnValue]
public DependencyRegistrar RegisterDependency(Type type)
{
return new DependencyRegistrar(this, type.CheckNotNull());
}
private void registerDependency(Type implementationType, Type dependencyType, bool ignoreCtors = false)
{
Assert.That(dependencyType.IsInterface && dependencyType.Name.EndsWith("Friend")).IsFalse("Registering friend interface as dependency? You might want to use [NotGlobalDependency] attribute.");
if (dependencyType.IsGenericTypeDefinition)
{
if (!implementationType.IsGenericTypeDefinition)
{
Log.Error($"Non-generic type '{implementationType}' cannot be registered as generic " + $"'{dependencyType}'.");
return;
}
}
else
{
if (!dependencyType.IsAssignableFrom(implementationType))
{
Log.Error($"Dependency implementation '{implementationType}' is not assignable to registered " + $"type '{dependencyType}'.");
return;
}
if (dependencyType.ContainsGenericParameters || implementationType.ContainsGenericParameters)
{
Log.Error("If registering type (and not generic type definition), the dependency type " + $"'{dependencyType}' implementation type '{implementationType}' may not contain generic " + "parameters.");
return;
}
}
if (implementationType.IsAbstract)
{
Log.Error($"Dependency implementation '{implementationType}' can not be abstract type.");
return;
}
if (!ignoreCtors)
{
ConstructorInfo[] constructors = implementationType.GetConstructors();
if (constructors.Length == 0)
{
constructors = implementationType.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
}
if (constructors.Length != 1)
{
Log.Error($"Dependency implementation '{implementationType}' does not have one public constructor " + "(or one non-public constructor).");
return;
}
}
Dict<Type, Lyst<Type>> dict = (dependencyType.IsGenericTypeDefinition ? m_genericDependencyRegistrations : m_dependencyRegistrations);
if (!dict.TryGetValue(dependencyType, out var value))
{
value = new Lyst<Type>();
dict.Add(dependencyType, value);
}
if (value.Contains(implementationType))
{
Log.Warning($"Dependency implementation '{implementationType}' is already registered for type " + $"'{dependencyType}'.");
return;
}
value.Add(implementationType);
m_registrationOrder.AddIfNotPresent(implementationType, m_registrationOrder.Count);
m_registrationOrder.AddIfNotPresent(dependencyType, m_registrationOrder.Count);
}
private void unregisterDependency(Type implementationType, Type dependencyType)
{
Dict<Type, Lyst<Type>> dict = (dependencyType.IsGenericTypeDefinition ? m_genericDependencyRegistrations : m_dependencyRegistrations);
if (dict.TryGetValue(dependencyType, out var value))
{
value.Remove(implementationType);
if (value.Count == 0)
{
dict.Remove(dependencyType);
}
}
}
//
// 요약:
// 주어진 인스턴스의 종속성 등록 프로세스를 시작합니다.
// 이 호출은 아직 아무 것도 등록하지 않습니다.
[MustUseReturnValue]
public DependencyInstanceRegistrar<T> RegisterInstance<T>(T instance) where T : class
{
if (instance == null)
{
throw new DependencyResolverException($"Registering null instance of '{typeof(T)}'.");
}
return new DependencyInstanceRegistrar<T>(this, instance);
}
private void registerDependencyInstance<T>(T implementation, Type dependencyType)
{
Type type = implementation.GetType();
registerDependency(type, dependencyType, ignoreCtors: true);
m_instancesByRegisteredType.ContainsKey(dependencyType);
m_instancesByRegisteredType[dependencyType] = implementation;
m_instancesByRealType[type] = implementation;
}
//
// 요약:
// Mafi.GlobalDependencyAttribute의 등록을 기반으로 지정된 유형의 모든 등록을 제거합니다.
public DependencyResolverBuilder UnregisterGlobalDependency<T>() where T : class
{
unregisterGlobalDependency(typeof(T));
return this;
}
//
// 요약:
// 지정된 T 아래에 등록된 모든 구현을 제거합니다.
public void ClearRegistrations<T>() where T : class
{
ClearRegistrations(typeof(T));
}
//
// 요약:
// 지정된 dependencyType 아래에 등록된 모든 유형 및 인스턴스를 제거합니다.
public void ClearRegistrations(Type dependencyType)
{
_003C_003Ec__DisplayClass30_0 CS_0024_003C_003E8__locals0 = new _003C_003Ec__DisplayClass30_0();
CS_0024_003C_003E8__locals0.dependencyType = dependencyType;
m_dependencyRegistrations.Remove(CS_0024_003C_003E8__locals0.dependencyType);
foreach (Lyst<Type> value in m_dependencyRegistrations.Values)
{
value.RemoveFirst((Type x) => x == CS_0024_003C_003E8__locals0.dependencyType);
}
m_genericDependencyRegistrations.Remove(CS_0024_003C_003E8__locals0.dependencyType);
foreach (KeyValuePair<Type, Lyst<Type>> genericDependencyRegistration in m_genericDependencyRegistrations)
{
genericDependencyRegistration.Value.RemoveFirst((Type x) => x == CS_0024_003C_003E8__locals0.dependencyType);
}
m_instancesByRegisteredType.Remove(CS_0024_003C_003E8__locals0.dependencyType);
m_instancesByRealType.RemoveValues((object x) => x.GetType() == CS_0024_003C_003E8__locals0.dependencyType);
}
public void ClearAllDepsImplementing<T>() where T : class
{
ClearAllDepsImplementing(typeof(T));
}
public void ClearAllDepsImplementing(Type type)
{
_003C_003Ec__DisplayClass32_0 CS_0024_003C_003E8__locals0 = new _003C_003Ec__DisplayClass32_0();
CS_0024_003C_003E8__locals0.type = type;
ClearRegistrations(CS_0024_003C_003E8__locals0.type);
foreach (Lyst<Type> value in m_dependencyRegistrations.Values)
{
value.RemoveWhere((Type x) => x.IsAssignableTo(CS_0024_003C_003E8__locals0.type));
}
foreach (KeyValuePair<Type, Lyst<Type>> genericDependencyRegistration in m_genericDependencyRegistrations)
{
genericDependencyRegistration.Value.RemoveFirst((Type x) => x.IsAssignableTo(CS_0024_003C_003E8__locals0.type));
}
m_instancesByRegisteredType.RemoveKeys((Type x) => x.IsAssignableTo(CS_0024_003C_003E8__locals0.type));
m_instancesByRealType.RemoveValues((object x) => x.GetType().IsAssignableTo(CS_0024_003C_003E8__locals0.type));
}
public void ClearRegisteredType<T>() where T : class
{
ClearRegisteredType(typeof(T));
}
public void ClearRegisteredType(Type instanceType)
{
_003C_003Ec__DisplayClass34_0 CS_0024_003C_003E8__locals0 = new _003C_003Ec__DisplayClass34_0();
CS_0024_003C_003E8__locals0.instanceType = instanceType;
foreach (KeyValuePair<Type, Lyst<Type>> dependencyRegistration in m_dependencyRegistrations)
{
dependencyRegistration.Value.RemoveAll((Type x) => x == CS_0024_003C_003E8__locals0.instanceType);
}
}
//
// 요약:
// 지정된 T에 할당할 수 있는 지정된 어셈블리의 모든 형식을 T로 등록합니다.
public void RegisterAllTypesImplementing<T>(Assembly assembly, bool ignoreCtors = false, bool alsoRegisterAsSelf = false)
{
Type[] types = assembly.GetTypes();
Type[] array = types;
foreach (Type type in array)
{
if (type.IsClass && !type.IsAbstract && type.IsAssignableTo<T>())
{
registerDependency(type, typeof(T), ignoreCtors);
if (alsoRegisterAsSelf)
{
registerDependency(type, type, ignoreCtors);
}
}
}
}
//
// 요약:
// Mafi.GlobalDependencyAttribute로 표시된 지정된 어셈블리의 모든 유형을 등록합니다.
// shouldRegisterPredicate는 등록된 유형을 필터링하는 데 사용할 수 있습니다.
public void RegisterAllGlobalDependencies(Assembly assembly, Predicate<Type> shouldRegisterPredicate = null)
{
if (!m_registeredGlobalDeps.Add(assembly))
{
return;
}
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
if (type.IsClass && !type.IsAbstract && (shouldRegisterPredicate == null || shouldRegisterPredicate(type)))
{
tryRegisterAllGlobalDependencies(type);
}
}
}
//
// 요약:
// 경고: 이 메서드는 System.Reflection.Assembly를 인수로 사용하는 부모 공개 메서드
// Mafi.DependencyResolverBuilder.RegisterAllGlobalDependencies(System.Reflection.Assembly,System.Predicate{System.Type})를
// 테스트하기가 정말 어렵기 때문에 테스트에서 리플렉션을 통해 호출됩니다. .
private void tryRegisterAllGlobalDependencies(Type implType)
{
Assert.That(implType.IsClass).IsTrue("Global dependency should be a class.");
Assert.That(implType.IsAbstract).IsFalse("Global dependency should not be abstract.");
object[] customAttributes = implType.GetCustomAttributes(typeof(GlobalDependencyAttribute), inherit: false);
if (customAttributes.Length == 0)
{
return;
}
if (customAttributes.Length > 1)
{
throw new DependencyResolverException(string.Format("Class implements more than one `{0}`: {1}", "GlobalDependencyAttribute", implType));
}
GlobalDependencyAttribute globalDependencyAttribute = (GlobalDependencyAttribute)customAttributes[0];
if (globalDependencyAttribute.OnlyInDebug || globalDependencyAttribute.OnlyInDevOnly)
{
return;
}
RegistrationMode registrationMode = globalDependencyAttribute.RegistrationMode;
if ((registrationMode & RegistrationMode.AsSelf) != 0)
{
registerDependency(implType, implType);
}
if ((registrationMode & RegistrationMode.AsAllInterfaces) != 0)
{
Type[] interfaces = implType.GetInterfaces();
if (interfaces.Length == 0)
{
Log.Error($"Registering all interfaces of type {implType} that does not implement any " + "interfaces.");
}
else
{
Type[] array = interfaces;
foreach (Type type in array)
{
if (type.GetCustomAttributes(typeof(NotGlobalDependencyAttribute), inherit: false).Length == 0)
{
Assert.That(type.Name.EndsWith("Friend")).IsFalse("Registering under friend!");
registerDependency(implType, type);
}
}
}
}
if (registrationMode == (RegistrationMode)0)
{
Log.Warning($"No registration mode specified for global dependency {implType} and no explicit " + "registration types were given.");
}
}
private void unregisterGlobalDependency(Type implType)
{
object[] customAttributes = implType.GetCustomAttributes(typeof(GlobalDependencyAttribute), inherit: false);
if (customAttributes.Length != 1)
{
Log.Warning($"Trying to unregister global dependency registrations of '{implType}' but it does not " + "have the GlobalDependencyAttribute.");
return;
}
GlobalDependencyAttribute globalDependencyAttribute = (GlobalDependencyAttribute)customAttributes[0];
if (globalDependencyAttribute.OnlyInDebug || globalDependencyAttribute.OnlyInDevOnly)
{
return;
}
RegistrationMode registrationMode = globalDependencyAttribute.RegistrationMode;
if ((registrationMode & RegistrationMode.AsSelf) != 0)
{
unregisterDependency(implType, implType);
}
if ((registrationMode & RegistrationMode.AsAllInterfaces) == 0)
{
return;
}
Type[] interfaces = implType.GetInterfaces();
foreach (Type type in interfaces)
{
if (type.GetCustomAttributes(typeof(NotGlobalDependencyAttribute), inherit: false).Length == 0)
{
Assert.That(type.Name.EndsWith("Friend")).IsFalse("Registering under friend!");
unregisterDependency(implType, type);
}
}
}
public string PrintCurrentRegistrations()
{
StringBuilder stringBuilder = new StringBuilder(4096);
stringBuilder.AppendLine("Dependency registrations");
foreach (KeyValuePair<Type, Lyst<Type>> dependencyRegistration in m_dependencyRegistrations)
{
if (dependencyRegistration.Value.Count == 1)
{
stringBuilder.AppendLine(" " + dependencyRegistration.Key.Name + ": " + dependencyRegistration.Value.First.FullName);
continue;
}
stringBuilder.AppendLine(" " + dependencyRegistration.Key.Name + ":");
Lyst<Type>.Enumerator enumerator2 = dependencyRegistration.Value.GetEnumerator();
while (enumerator2.MoveNext())
{
Type current2 = enumerator2.Current;
stringBuilder.AppendLine(" " + current2.FullName);
}
}
stringBuilder.AppendLine("\n\n");
stringBuilder.AppendLine("Generic dependency registrations");
foreach (KeyValuePair<Type, Lyst<Type>> genericDependencyRegistration in m_genericDependencyRegistrations)
{
if (genericDependencyRegistration.Value.Count == 1)
{
stringBuilder.AppendLine(" " + genericDependencyRegistration.Key.Name + ": " + genericDependencyRegistration.Value.First.Name);
continue;
}
stringBuilder.AppendLine(" " + genericDependencyRegistration.Key.Name + ":");
Lyst<Type>.Enumerator enumerator4 = genericDependencyRegistration.Value.GetEnumerator();
while (enumerator4.MoveNext())
{
Type current4 = enumerator4.Current;
stringBuilder.AppendLine(" " + current4.FullName);
}
}
stringBuilder.AppendLine("\n\n");
stringBuilder.AppendLine("Instances by registered type");
foreach (KeyValuePair<Type, object> item in m_instancesByRegisteredType)
{
stringBuilder.AppendLine($" {item.Key.Name}: {item.Value}");
}
stringBuilder.AppendLine("\n\n");
stringBuilder.AppendLine("Instances by real type");
foreach (KeyValuePair<Type, object> item2 in m_instancesByRealType)
{
stringBuilder.AppendLine($" {item2.Key.Name}: {item2.Value}");
}
return stringBuilder.ToString();
}
public DependencyResolverBuilder()
{
MBiHIp97M4MqqbtZOh.BibDvtQbp();
m_dependencyRegistrations = new Dict<Type, Lyst<Type>>();
m_dependencyResolvePreferences = new Dict<Type, Type>();
m_genericDependencyRegistrations = new Dict<Type, Lyst<Type>>();
m_instancesByRegisteredType = new Dict<Type, object>();
m_instancesByRealType = new Dict<Type, object>();
m_registeredGlobalDeps = new Set<Assembly>();
m_registrationOrder = new Dict<Type, int>();
m_resolvingFunctions = new Lyst<Func<ParameterInfo, Option<object>>>();
base._002Ector();
}
}