internal AutoServiceClassInfo(IActivityMonitor m,
                                      IServiceProvider serviceProvider,
                                      AutoServiceClassInfo?parent,
                                      Type t,
                                      bool isExcluded,
                                      RealObjectClassInfo?objectInfo)
        {
            Debug.Assert(objectInfo == null || objectInfo.ServiceClass == null, "If we are the associated Service, we must be the only one.");
            if (objectInfo != null)
            {
                TypeInfo = objectInfo;
                objectInfo.ServiceClass = this;
            }
            else
            {
                TypeInfo = new CKTypeInfo(m, parent?.TypeInfo, t, serviceProvider, isExcluded, this);
            }
            Debug.Assert(parent == null || ReferenceEquals(TypeInfo.Generalization, parent.TypeInfo), $"Gen={TypeInfo.Generalization}/Par={parent?.TypeInfo}");

            if (parent != null)
            {
                SpecializationDepth = parent.SpecializationDepth + 1;
            }

            // Used only when this service is eventually a simple one.
            SimpleMappingListIndex = -1;
        }
Beispiel #2
0
        internal void RegisterServiceFinalObjectMapping(Type t, CKTypeInfo typeInfo)
        {
            Debug.Assert(typeInfo is RealObjectClassInfo);
            var         c       = (RealObjectClassInfo)typeInfo;
            MutableItem mapping = c.AutoServiceImpl;

            if (mapping == null)
            {
                c.AutoServiceImpl = mapping = _map[typeInfo.Type];
                _serviceRealObjects.Add(mapping);
            }
            _serviceToObjectMap.Add(t, mapping);
        }
        internal bool IsAssignableFrom(CKTypeInfo child)
        {
            Debug.Assert(child != null);
            CKTypeInfo?c = child;

            do
            {
                if (c == this)
                {
                    return(true);
                }
            }while((c = c.Generalization) != null);
            return(false);
        }
 internal void RemoveSpecialization(CKTypeInfo child)
 {
     Debug.Assert(child.Generalization == this);
     if (_firstChild == child)
     {
         _firstChild = child._nextSibling;
         --_specializationCount;
     }
     else
     {
         var c = _firstChild;
         while (c != null && c._nextSibling != child)
         {
             c = c._nextSibling;
         }
         if (c != null)
         {
             c._nextSibling = child._nextSibling;
             --_specializationCount;
         }
     }
 }
Beispiel #5
0
 internal void RegisterMultipleInterfaces(Type tI, CKTypeKind enumeratedKind, CKTypeInfo final)
 {
     if (!_multipleMappings.TryGetValue(tI, out var multiple))
     {
         Debug.Assert(enumeratedKind.GetCombinationError(false) == null);
         // A IEnumerable of IScoped is scoped, a IEnumerable of ISingleton is singleton, a IEnumerable of IFrontProcessService is
         // itself a front process service. Even a IEnumerable of an interface that has been marked [IsMarshallable] is de facto marshallable.
         // We rely on this here.
         Type tEnumerable = typeof(IEnumerable <>).MakeGenericType(tI);
         if ((enumeratedKind & (CKTypeKind.IsFrontService | CKTypeKind.IsMarshallable)) == (CKTypeKind.IsFrontService | CKTypeKind.IsMarshallable))
         {
             // Only if the T interface is a IFrontService (and hence a Scoped) and is marked with IsMarshallable attribute
             // can we avoid the implementations analyzis. Even if a IFrontService interface marked with IsMarshallable attribute should be rare,
             // we can benefit here from this minor (but logical) optimization.
             _multipleMappings.Add(tI, new MultipleImpl(tEnumerable, tI));
         }
         else
         {
             // The IEnumerable itself may have been explicitly registered via SetAutoServiceKind.
             // We check its compatibility with its enumerated interface (there may be incoherences) later in the DoComputeFinalTypeKind.
             // Here we just check the "worst case":
             CKTypeKind enumKind = KindDetector.GetValidKind(_monitor, tEnumerable);
             Debug.Assert(enumKind.GetCombinationError(false) == null);
             if ((enumKind & (CKTypeKind.IsFrontService | CKTypeKind.IsMarshallable)) == (CKTypeKind.IsFrontService | CKTypeKind.IsMarshallable))
             {
                 _multipleMappings.Add(tI, new MultipleImpl(tEnumerable, tI));
             }
             else
             {
                 _multipleMappings.Add(tI, new MultipleImpl(tEnumerable, enumKind, tI, enumeratedKind, final));
             }
         }
     }
     else
     {
         multiple.AddImpl(final);
     }
 }
Beispiel #6
0
 internal MultipleImpl(Type tEnum, CKTypeKind enumerabledKind, Type tI, CKTypeKind iKind, CKTypeInfo first)
 {
     EnumerableType   = tEnum;
     _enumerabledKind = enumerabledKind;
     EnumeratedType   = tI;
     _itemKind        = iKind;
     _rawImpls        = new List <CKTypeInfo>();
     _rawImpls.Add(first);
     // These properties are null until ComputeFinalTypeKind is called.
     // (Offensive) I prefer assuming this nullity here rather than setting empty arrays.
     MarshallableTypes          = null !;
     MarshallableInProcessTypes = null !;
 }
Beispiel #7
0
 internal void AddImpl(CKTypeInfo final) => _rawImpls?.Add(final);