private static TypeActivator ClassActivator(Type expectedType)
        {
            var constructors =
                expectedType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                .Where(c => c.IsDefined(typeof(ConstructorAttribute), true))
                .ToList();

            if (constructors.Count == 0)
            {
                throw new DeserializationException(
                          $"No constructors found for {expectedType} found with AiWen.Db.Constructor attribute");
            }
            if (constructors.Count > 1)
            {
                throw new DeserializationException(
                          $"More than one constructor found for {expectedType} found with AiWen.Db/Constructor attribute");
            }

            var constructor    = constructors[0];
            var parameters     = constructor.GetParameters();
            var paramNameTypes = new Dictionary <byte[], ParameterInfo>(new ByteArrayEqualityComparer());
            var injectables    = new Dictionary <string, ParameterInfo>();
            var networkParams  = new List <ParameterInfo>();
            var alwaysCreated  = new List <ParameterInfo>();

            foreach (var param in parameters)
            {
                var injectableAttribute = param.GetCustomAttributes <InjectAttribute>().FirstOrDefault();
                if (injectableAttribute != null)
                {
                    injectables.Add(injectableAttribute.ParameterName, param);
                }
                var networkAttribute = param.GetCustomAttributes <NetworkAttribute>().FirstOrDefault();
                if (networkAttribute != null)
                {
                    networkParams.Add(param);
                }
                var    paramAttribute = param.GetCustomAttributes <ParameterAttribute>().FirstOrDefault();
                string name;
                if (paramAttribute != null)
                {
                    name = paramAttribute.ParameterName;
                    if (paramAttribute.AlwaysCreate)
                    {
                        alwaysCreated.Add(param);
                    }
                }
                else
                {
                    name = param.Name;
                }
                paramNameTypes.Add(Encoding.UTF8.GetBytes(name), param);
            }
            var activator      = ReflectionUtil.CreateActivator(constructor);
            var clsConstructor = new TypeActivator(activator, paramNameTypes, injectables, networkParams, alwaysCreated);

            return(clsConstructor);
        }
Beispiel #2
0
 private static void SetNetwork(TypeActivator constructor, object?[] parameters, Network?network)
 {
     foreach (var item in constructor.NetworkParameters)
     {
         // We don't check that we have a non-null network as we want to
         // allow enumeration to use the same models as normal lookups. We
         // cannot support the network field for enumeration as the objects
         // are cached.
         parameters[item.Position] = network;
     }
 }
Beispiel #3
0
        private static void SetInjectables(TypeActivator constructor, object[] parameters, InjectableValues?injectables)
        {
            foreach (var item in constructor.InjectableParameters)
            {
                if (injectables == null || !injectables.Values.ContainsKey(item.Key))
                {
                    throw new DeserializationException($"No injectable value found for {item.Key}");
                }

                parameters[item.Value.Position] = injectables.Values[item.Key];
            }
        }
Beispiel #4
0
        private void SetAlwaysCreatedParams(
            TypeActivator constructor,
            object[] parameters,
            InjectableValues?injectables,
            Network?network
            )
        {
            foreach (var param in constructor.AlwaysCreatedParameters)
            {
                if (parameters[param.Position] != null)
                {
                    continue;
                }

                var activator   = _typeAcivatorCreator.GetActivator(param.ParameterType);
                var cstorParams = activator.DefaultParameters();
                SetInjectables(activator, cstorParams, injectables);
                SetNetwork(activator, cstorParams, network);
                SetAlwaysCreatedParams(activator, cstorParams, injectables, network);
                parameters[param.Position] = activator.Activator(cstorParams);
            }
        }