Example #1
0
        private PropertyInfo ImplementReadPrimaryKeyAndGetPkProperty(
            IClassBuilder entityClass,
            EntityBehavior behavior,
            Type entityType)
        {
            var pkProperty = ReflectionUtil.GetProperty(entityType, behavior.PrimaryKeyProperty);

            if (pkProperty == null)
            {
                throw new InvalidOperationException($"{entityType.Name} is missing {behavior.PrimaryKeyProperty} property");
            }

            var idField = entityClass.HasField(pkProperty.PropertyType);

            var idProp = entityClass.HasProperty(pkProperty.Name, pkProperty.PropertyType).WithModifier("public");

            idProp.HasGetter().Write("return ").Write(idField).EndStatement();
            idProp.HasSetter().Assign(idField, a => a.Write("value")).EndStatement();

            var primaryKeyValueProperty = entityClass.HasProperty(nameof(IEntity.PrimaryKeyValue), typeof(object))
                                          .WithModifier("public");

            primaryKeyValueProperty.HasGetter().Write("return ").Write(idProp).EndStatement();

            var primaryKeyValueSetter = primaryKeyValueProperty.HasSetter();

            primaryKeyValueSetter.Write(idProp).Write(" = ").Write("(").Write(pkProperty.PropertyType).Write(")").Write(primaryKeyValueSetter.ValueParameter).EndStatement();

            var readPkMethod = entityClass.HasMethod(nameof(IEntity.ReadPrimaryKey)).WithModifier("public").Returns <bool>();
            var readerParam  = readPkMethod.WithParam <IDataRecord>("reader");

            readPkMethod.Body.If(
                c =>
                c.Write(readerParam)
                .Write(".")
                .Invoke(
                    nameof(IDataRecord.IsNull),
                    p => p.WithParam(code => code.Write("\"").Write(pkProperty.Name).Write("\""))),
                then => then.Write("return false").EndStatement()).NewLine();

            readPkMethod.Body.Assign(
                idField,
                a =>
                a.Write(readerParam)
                .Write(".Get<")
                .Write(pkProperty.PropertyType)
                .Write(">(\"")
                .Write(pkProperty.Name)
                .Write("\")")).EndStatement();

            readPkMethod.Body.Write("return true").EndStatement();

            return(pkProperty);
        }
Example #2
0
        private void ImplementIsDirtyProperty(IClassBuilder entityClass)
        {
            var isDirtyField = entityClass.HasField <bool>("isDirty");

            var prop = entityClass.HasProperty <bool>("IsDirty").WithModifier("public");

            prop.HasGetter().Write("return ").Write(isDirtyField).EndStatement();

            var setter = prop.HasSetter();

            setter.Assign(isDirtyField, asi => asi.Write(setter.ValueParameter));
        }
Example #3
0
        private void DefaultImplementProperty(IClassBuilder cls, PropertyInfo property)
        {
            var storageField = cls.HasField($"storage{property.Name}_{Guid.NewGuid():N}", property.PropertyType);

            cls.WithConstructor()
            .Body.Assign(
                storageField,
                assignment => assignment.Write("default(").Write(property.PropertyType).Write(")"));

            var prop = cls.HasProperty(property.Name, property.PropertyType).WithModifier("public");

            prop.HasGetter().Write("return ").Write(storageField).EndStatement();
            prop.HasSetter().Assign(storageField, a => a.Write("value"));
        }
Example #4
0
        private Dictionary <string, INamedReference> ProjectFactories(IEnumerable <InstanceRecord> records, IClassBuilder locator, out IConstructorBuilder ctor)
        {
            var result = new Dictionary <string, INamedReference>();

            ctor = locator.WithConstructor().WithModifier("public");

            var parentLocatorParam = ctor.WithParam <IServiceLocator>("parentLocator");

            ctor.CallsBase().WithParam(parentLocatorParam);

            var factoriesParam = ctor.WithParam("factories", typeof(Dictionary <string, Func <IServiceLocator, object> >));

            var constructor = ctor;

            Action <NamedFactory> addFactory = factory =>
            {
                var field =
                    locator.HasField <Func <IServiceLocator, object> >()
                    .WithModifier("readonly")
                    .WithModifier("private");

                constructor.Body.Assign(
                    field,
                    a => a.Write(factoriesParam).Write("[\"").Write(factory.Name).Write("\"]"));

                result.Add(factory.Name, field);
            };

            foreach (var record in records)
            {
                if (record.Factory != null)
                {
                    addFactory(record.Factory);
                }

                if (record.ConstructorParameters != null)
                {
                    foreach (var ctorFactory in record.ConstructorParameters.Where(p => p.ValueProvider != null).Select(p => p.ValueProvider))
                    {
                        addFactory(ctorFactory);
                    }
                }
            }

            return(result);
        }
Example #5
0
        protected virtual void ImplementExecuteMethod(IClassBuilder proxyclass, Type controllerType, Type callBuilderType, INamedReference interceptorField)
        {
            var execMethod = proxyclass.HasMethod(nameof(IController.Execute)).WithModifier("public").ReturnsVoid();

            var contextParam = execMethod.WithParam("__context", typeof(RequestContext));

            execMethod.Body.If(
                condition =>
                condition.Invoke(
                    interceptorField,
                    nameof(IControllerInterceptor.OnRequest),
                    inv => inv.WithParam("this").WithParam(contextParam)),
                then => then.Write("return").EndStatement());

            var factories = new Dictionary <Type, INamedReference>();

            Func <Type, INamedReference> fieldsFactory = type =>
            {
                INamedReference result;
                if (!factories.TryGetValue(type, out result))
                {
                    result =
                        proxyclass.HasField(type)
                        .WithModifier("private")
                        .WithModifier("static")
                        .WithModifier("readonly")
                        .WithAssignment(asg => asg.Write("new ").Write(type).Write("()"));
                    factories[type] = result;
                }

                return(result);
            };

            var writer = Activator.CreateInstance(callBuilderType) as IControllerMethodCallBuilder;

            if (writer == null)
            {
                throw new InvalidOperationException($"{callBuilderType.Name} is not of type {nameof(IControllerMethodCallBuilder)}");
            }

            writer.BuildCall(proxyclass, execMethod, contextParam, controllerType, fieldsFactory, interceptorField);
        }
Example #6
0
        private void ImplementDefaultProperty(IClassBuilder entityClass, PropertyInfo sourceProperty, bool setDirtyFlag = false)
        {
            var backingField = entityClass.HasField(sourceProperty.PropertyType);

            var property = entityClass.HasProperty(sourceProperty.Name, sourceProperty.PropertyType).WithModifier("public");

            property.HasGetter().Write("return ").Write(backingField).EndStatement();

            var setter = property.HasSetter();

            if (setDirtyFlag)
            {
                setter.If(
                    c => c.Write(backingField).Write(" == ").Write(setter.ValueParameter),
                    then => then.Write("return").EndStatement());

                setter.Write("IsDirty = true").EndStatement();
            }

            setter.Assign(backingField, a => a.Write(setter.ValueParameter)).EndStatement();
        }
Example #7
0
        public INamedReference GenerateFactoryMethod(
            IServiceSetupRecord setup,
            Dictionary <string, INamedReference> ctorParamValueFactoryFields,
            INamedReference valueFactoryField,
            IClassBuilder locatorBuilder,
            INamedReference previousPluginMethod)
        {
            if (setup.GetBehavior(s_defaultBehavior).AlwaysNewInstance)
            {
                return(previousPluginMethod);
            }

            var field = locatorBuilder.HasField(setup.InterfaceType).WithModifier("private");

            var fMethod = locatorBuilder.HasMethod($"Singleton_{TypeNameHelper.GetTypeMark(setup.InterfaceType)}_{Guid.NewGuid():N}").Returns(setup.InterfaceType);

            fMethod.Body.Write(" return ")
            .LazyReadOrAssign(field, a => a.Invoke(previousPluginMethod, inv => { }))
            .EndStatement();

            return(fMethod);
        }
Example #8
0
        private void ImplementReferenceEntityProperties(IClassBuilder entityClass, Type entityType, IEntityNamingConvention convention)
        {
            var getReferencePropertiesMethod =
                entityClass.HasMethod(nameof(IEntity.GetReferenceProperties))
                .Returns <IEnumerable <Tuple <string, Type> > >()
                .WithModifier("public");

            var openPropertyMethod =
                entityClass.HasMethod(nameof(IEntity.OpenProperty)).Returns <IEntitySet>().WithModifier("public");
            var openPropertyNameParam = openPropertyMethod.WithParam <string>("propertyName");

            foreach (var property in ReflectionUtil.GetAllProperties(entityType))
            {
                var foreignEntityType = convention.TryGetRefEntityType(property);
                if (foreignEntityType == null)
                {
                    continue;
                }

                var refNameTypeField =
                    entityClass.HasField <Tuple <string, Type> >().WithModifier("private").WithModifier("readonly").WithAssignment(a =>
                                                                                                                                   a.InvokeConstructor(
                                                                                                                                       typeof(Tuple <string, Type>),
                                                                                                                                       inv =>
                                                                                                                                       inv.WithParam(p => p.String(property.Name))
                                                                                                                                       .WithParam(p => p.Typeof(foreignEntityType))));

                getReferencePropertiesMethod.Body.Write("yield return ").Write(refNameTypeField).EndStatement();

                INamedReference backingField;
                if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
                {
                    backingField =
                        entityClass.HasField <EntityList>()
                        .WithAssignment(a => a.InvokeConstructor(typeof(EntityList), x => { }));



                    entityClass.HasProperty(property.Name, property.PropertyType)
                    .WithModifier("public")
                    .HasGetter()
                    .Write("return ")
                    .Write(typeof(System.Linq.Enumerable))
                    .Write(".")
                    .Write("OfType<")
                    .Write(foreignEntityType)
                    .Write(">(")
                    .Write(backingField)
                    .Write(")")
                    .EndStatement();
                }
                else
                {
                    backingField =
                        entityClass.HasField <EntityHolder>()
                        .WithAssignment(a => a.InvokeConstructor(typeof(EntityHolder), x => { }));

                    entityClass.HasProperty(property.Name, property.PropertyType)
                    .WithModifier("public")
                    .HasGetter()
                    .Write("return ")
                    .Write(backingField)
                    .Write(".Value")
                    .Write(" as ")
                    .Write(foreignEntityType)
                    .EndStatement();
                }

                openPropertyMethod.Body.If(
                    c => c.Compare(openPropertyNameParam, b => b.String(property.Name)),
                    then => then.Write("return ").Write(backingField).EndStatement()).NewLine();
            }

            openPropertyMethod.Body.Write("throw ")
            .InvokeConstructor(
                typeof(InvalidOperationException),
                i => i.WithParam(p => p.String("Unknown property requested")))
            .EndStatement();

            getReferencePropertiesMethod.Body.Write("yield break").EndStatement();
        }
Example #9
0
        protected virtual void ImplementCall(
            Type controllerType,
            MethodInfo method,
            INamedReference contextParameter,
            INamedReference resultVar,
            Func <Type, INamedReference> privateObjectsFactory,
            IClassBuilder proxyBuilder,
            INamedReference interceptorField,
            ICodeBlockBuilder block)
        {
            var argumentsArray = block.Var(ini => ini.Write($"new System.Object[{method.GetParameters().Length}]"));

            block.Write("try {\r\n");

            var methodInfoField =
                proxyBuilder.HasField(typeof(MethodInfo))
                .WithModifier("static")
                .WithModifier("private")
                .WithModifier("readonly")
                .WithAssignment(
                    asg =>
                    asg.Write(typeof(ReflectonWrapper))
                    .Write(".")
                    .Write(nameof(ReflectonWrapper.GetMethodInfo))
                    .Write("(")
                    .Typeof(controllerType)
                    .Write(",")
                    .String(method.Name)
                    .Write(")"));

            var paramVars = new List <INamedReference>(method.GetParameters().Length);

            var parameterIndex = 0;

            foreach (var param in method.GetParameters())
            {
                var paramInfoField =
                    proxyBuilder.HasField(typeof(ParameterInfo))
                    .WithModifier("static")
                    .WithModifier("private")
                    .WithModifier("readonly")
                    .WithAssignment(
                        asg =>
                        asg.Write(typeof(ReflectonWrapper))
                        .Write(".")
                        .Write(nameof(ReflectonWrapper.GetParameterInfo))
                        .Write("(")
                        .Typeof(controllerType)
                        .Write(",")
                        .String(method.Name)
                        .Write(",")
                        .String(param.Name)
                        .Write(")"));


                var paramReaderType = GetParameterReaderType(param);
                var readerField     = privateObjectsFactory(paramReaderType);

                var paramVar = block.Var(asg => ComposeParameterRead(asg, readerField, param, methodInfoField, paramInfoField, contextParameter, interceptorField));

                paramVars.Add(paramVar);

                block.Write(argumentsArray).Write($"[{parameterIndex}] = ").Write(paramVar).EndStatement();

                parameterIndex++;
            }


            var isVoid            = method.ReturnType == typeof(void);
            var resultWriterField = privateObjectsFactory(GetResultWriterType(method));

            block.Invoke(
                interceptorField,
                nameof(IControllerInterceptor.Call),
                args =>
                args.WithParam("this")
                .WithParam(methodInfoField)
                .WithParam(contextParameter)
                .WithParam(argumentsArray)
                .WithParam(isVoid ? "true" : "false")
                .WithParam(
                    call =>
            {
                call.Write("() => {");

                if (!isVoid)
                {
                    call.Write("return ");
                }

                call.Invoke(
                    method.Name,
                    argu =>
                {
                    foreach (var argument in paramVars)
                    {
                        argu.WithParam(argument);
                    }
                }).EndStatement();

                if (isVoid)
                {
                    call.Write("return null").EndStatement();
                }

                call.Write(" }");
            }).WithParam(
                    result =>
            {
                result.Write("__r => ")
                .Invoke(
                    resultWriterField,
                    nameof(IResultWriter.WriteResult),
                    rinvo =>
                    rinvo.WithParam(methodInfoField)
                    .WithParam(contextParameter)
                    .WithParam("__r")
                    .WithParam(isVoid ? "true" : "false"));
            })).EndStatement();



            block.Write("} catch(System.Exception callException) {\r\n");

            block.Invoke(
                interceptorField,
                nameof(IControllerInterceptor.OnException),
                arguments =>
                arguments.WithParam("this")
                .WithParam(methodInfoField)
                .WithParam(contextParameter)
                .WithParam(argumentsArray)
                .WithParam("callException")).EndStatement();

            block.Write("}\r\n");

            block.Write("return").EndStatement();
        }