示例#1
0
        public DependentPropertyMap(
            Serializer serializer,
            ModelMap <TModel> modelMap,
            PropertyInfo propInfo,
            ModelPropertyAttribute attr,
            List <ModelTypeSelectorAttribute> typeSelectorAttrs,
            Dictionary <string, PropertyMap <TModel> > props)
            : base(serializer, modelMap, propInfo, attr)
        {
            GetFunc = propInfo.GetMethod?.CreateDelegate(typeof(Func <TModel, TValue>)) as Func <TModel, TValue>;
            SetFunc = propInfo.SetMethod?.CreateDelegate(typeof(Action <TModel, TValue>)) as Action <TModel, TValue>;

            var  dependencyDict     = new MemoryDictionary <PropertyMap>();
            var  dependencies       = new List <PropertyMap>();
            var  converterProviders = new List <ConverterProvider <TModel, TValue> >();
            uint depsMask           = 0;

            for (int i = 0; i < typeSelectorAttrs.Count; i++)
            {
                var typeSelectorAttr = typeSelectorAttrs[i];
                if (!props.TryGetValue(typeSelectorAttr.KeyProperty, out var keyProp))
                {
                    throw new InvalidOperationException($"Unable to find dependency \"{typeSelectorAttr.KeyProperty}\"");
                }
                var keyType = keyProp.ValueType;

                // TODO: Does this search subtypes?
                var mapProp = typeof(TModel).GetTypeInfo().GetDeclaredProperty(typeSelectorAttr.MapProperty);
                if (mapProp == null)
                {
                    throw new InvalidOperationException($"Unable to find map \"{typeSelectorAttr.MapProperty}\"");
                }

                var converterProviderType = typeof(ConverterProvider <, ,>).MakeGenericType(typeof(TModel), keyType, typeof(TValue)).GetTypeInfo();
                var converterConstructor  = converterProviderType.DeclaredConstructors.Single();
                var converterProvider     = converterConstructor.Invoke(new object[] { serializer, propInfo, keyProp, mapProp }) as ConverterProvider <TModel, TValue>;
                converterProviders.Add(converterProvider);

                if (keyProp.Index == null)
                {
                    modelMap.RegisterDependency(keyProp);
                }

                if (dependencyDict.TryAdd(converterProvider.KeyProperty.Key, converterProvider.KeyProperty))
                {
                    dependencies.Add(converterProvider.KeyProperty);
                }

                depsMask |= converterProvider.KeyProperty.IndexMask;
            }
            ConverterProviders = converterProviders;
            _dependencies      = dependencies;
            _depMask           = depsMask;
        }
 internal ModelMap()
 {
     _propDict = new MemoryDictionary <PropertyMap>();
     _propList = new List <KeyValuePair <ReadOnlyMemory <byte>, PropertyMap> >();
 }