Mercurial > pub > ImplabNet
view Implab.ServiceHost/Unity/TypeResolutionContext.cs @ 280:f07be402ab02 v3
Added Trace<T>.Debug(...) method for debug messages
Added ContainerBuilde.LoadConfig(Uri) method
author | cin |
---|---|
date | Fri, 25 May 2018 19:15:26 +0300 |
parents | 6691aff01de1 |
children |
line wrap: on
line source
using System; using System.Collections.Generic; using Implab.Diagnostics; namespace Implab.ServiceHost.Unity { using static Trace<TypeResolver>; /// <summary> /// Позволяет обойти вложенные типы и собрать цеочку из типов и параметров генериков, которые они предлагают /// </summary> internal class TypeResolutionContext { readonly TypeResolver m_resolver; readonly List<Type> m_genericParameters = new List<Type>(); public IEnumerable<Type> GenericParameters { get { return m_genericParameters; } } public Type ResolvedType { get; private set; } public int ArrayRank { get; private set; } public bool ThrowOnFail { get; private set; } public TypeResolutionContext(TypeResolver resolver, bool throwOnFail) { m_resolver = resolver; ThrowOnFail = throwOnFail; } public Type MakeType() { return m_genericParameters.Count > 0 ? ResolvedType?.MakeGenericType(m_genericParameters.ToArray()) : ResolvedType; } public void Visit(SpecializedTypeReference typeReference) { typeReference.GenericType.Visit(this); if (ResolvedType != null) { foreach (var genericParamRef in typeReference.GenericParameters) { var context = new TypeResolutionContext(m_resolver, ThrowOnFail); genericParamRef.Visit(context); m_genericParameters.Add(context.MakeType()); } } } public void Visit(NestedTypeReference typeReference) { typeReference.DeclaringType.Visit(this); if (ResolvedType != null) ResolvedType = ResolvedType?.GetNestedType(typeReference.ClrName) ?? Failed(typeReference); } public void Visit(RootTypeReference typeReference) { ResolvedType = m_resolver.Resolve(typeReference.Namespace, typeReference.ClrName) ?? Failed(typeReference); } public void Visit(ArrayTypeReference typeReference) { var context = new TypeResolutionContext(m_resolver, ThrowOnFail); typeReference.ItemsType.Visit(context); ResolvedType = typeReference.Rank == 1 ? context.MakeType()?.MakeArrayType() : context.MakeType()?.MakeArrayType(typeReference.Rank); } Type Failed(TypeReference reference) { Log($"Falied to resolve {reference}"); if (ThrowOnFail) throw new Exception($"Failed to resolve {reference}"); return null; } } }