Example #1
0
        public INamedReference GenerateFactoryMethod(
            IServiceSetupRecord setup,
            Dictionary <string, INamedReference> ctorParamValueFactoryFields,
            INamedReference valueFactoryField,
            IClassBuilder locatorBuilder,
            INamedReference previousPluginMethod)
        {
            if (!IsApplicable(setup))
            {
                return(previousPluginMethod);
            }

            var behavior = setup.Behaviors.OfType <EntityBehavior>().Last();

            var entityClass =
                locatorBuilder.HasNestedClass($"{TypeNameHelper.GetTypeMark(setup.InterfaceType)}_Impl_{Guid.NewGuid():N}")
                .WithModifier("private")
                .WithModifier("sealed")
                .Implements <IEntity>()
                .Implements(setup.InterfaceType);

            var locatorField = entityClass.HasField <IServiceLocator>();

            var ctor         = entityClass.WithConstructor().WithModifier("public");
            var locatorParam = ctor.WithParam <IServiceLocator>("locator");

            ctor.Body.Assign(locatorField, a => a.Write(locatorParam)).EndStatement();
            ctor.Body.Write("IsDirty = true").EndStatement();

            var entityProperties = ImplementProperties(entityClass, setup.InterfaceType, behavior).ToList();

            ImplementIsDirtyProperty(entityClass);
            var pkProperty = ImplementReadPrimaryKeyAndGetPkProperty(entityClass, behavior, setup.InterfaceType);

            ImplementGetSaveMethodTypeMethod(entityClass, pkProperty);
            ImplementGetValuesMethod(entityClass, entityProperties, pkProperty);
            ImplementReadSelfMethod(entityClass, locatorField, entityProperties);
            ImplementReferenceEntityProperties(entityClass, setup.InterfaceType, m_setup.EntityNamingConvention);
            ImplementDbEntityNameProperty(entityClass, setup.InterfaceType);
            ImplementPkTypeProperty(entityClass, pkProperty);
            ImplementIsPkAuto(entityClass, pkProperty);

            var collectionMethod = locatorBuilder.HasMethod("GetEntitiesCollection").Returns(typeof(IEnumerable <Type>));

            collectionMethod.Body.Write("yield return typeof(")
            .Write(setup.InterfaceType)
            .Write(")")
            .EndStatement()
            .NewLine();

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

            factoryMethod.Body.Write("return ")
            .InvokeConstructor(entityClass, inv => inv.WithParam("this"))
            .EndStatement();

            return(factoryMethod);
        }
Example #2
0
        private void ImplementReadSelfMethod(IClassBuilder entityClass, IClassFieldBuilder locatorField, List <PropertyInfo> columnProperties)
        {
            var readMethod = entityClass.HasMethod("ReadSelf").WithModifier("public").ReturnsVoid();
            var rowParam   = readMethod.WithParam <IDataRecord>("dataRow");

            readMethod.Body.Write("if(!ReadPrimaryKey(").Write(rowParam).Write(")){ return; }").NewLine();

            foreach (var columnProp in columnProperties)
            {
                readMethod.Body.If(
                    c => c.Write("!").Write(rowParam).Write(".IsNull(\"").Write(columnProp.Name).Write("\")"),
                    then =>
                {
                    then.Write(columnProp.Name)
                    .Write(" = ")
                    .Write(rowParam)
                    .Write(".Get<")
                    .Write(columnProp.PropertyType)
                    .Write(">(\"").Write(columnProp.Name).Write("\")")
                    .EndStatement();
                },
                    els =>
                {
                    els.Write(columnProp.Name)
                    .Write(" = default(")
                    .Write(columnProp.PropertyType)
                    .Write(")")
                    .EndStatement();
                });
            }
        }
        public INamedReference GenerateFactoryMethod(
            IServiceSetupRecord setup,
            Dictionary <string, INamedReference> ctorParamValueFactoryFields,
            INamedReference valueFactoryField,
            IClassBuilder locatorBuilder,
            INamedReference previousPluginMethod)
        {
            var implementingType = setup.ImplementingType ?? setup.InterfaceType;

            var methodName = $"Factory{TypeNameHelper.GetTypeMark(setup.InterfaceType)}_{Guid.NewGuid():N}";

            var method = locatorBuilder.HasMethod(methodName).WithModifier("private").Returns(setup.InterfaceType);

            method.Body.Write("return ").InvokeConstructor(implementingType,
                                                           invocation =>
            {
                foreach (var constructorParameter in setup.PreferredConstructor.GetParameters())
                {
                    INamedReference factoryField;
                    if (ctorParamValueFactoryFields.TryGetValue(constructorParameter.Name, out factoryField))
                    {
                        invocation.WithParam(b => b.Write("(").Write(constructorParameter.ParameterType).Write(")").Write(factoryField).Write("(this)"));
                    }
                    else
                    {
                        invocation.WithParam(b => b.Write("(").Write(constructorParameter.ParameterType).Write(")").Write("Get(typeof(").Write(constructorParameter.ParameterType).Write("))"));
                    }
                }
            }).EndStatement();

            return(method);
        }
Example #4
0
            public INamedReference GenerateFactoryMethod(IServiceSetupRecord setup, Dictionary <string, INamedReference> ctorParamValueFactoryFields, INamedReference valueFactoryField, IClassBuilder locatorBuilder, INamedReference previousPluginMethod)
            {
                var fm = locatorBuilder.HasMethod($"ControllerIndexFactory_{Guid.NewGuid():N}").Returns <ControllerIndex>().WithModifier("private");

                fm.Body.Write("return new ").Write(typeof(ControllerIndex)).Write("(this.GetRoboapiControllerIndexFactory())").EndStatement();

                return(fm);
            }
Example #5
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 #6
0
        public INamedReference GenerateFactoryMethod(
            IServiceSetupRecord setup,
            Dictionary <string, INamedReference> ctorParamValueFactoryFields,
            INamedReference valueFactoryField,
            IClassBuilder locatorBuilder,
            INamedReference previousPluginMethod)
        {
            var behavior = setup.Behaviors.OfType <ControllerBehavior>().FirstOrDefault();

            if (behavior == null)
            {
                return(previousPluginMethod);
            }

            var indexFactory =
                locatorBuilder.HasMethod("GetRoboapiControllerIndexFactory")
                .Returns <IEnumerable <KeyValuePair <string, Type> > >()
                .WithModifier("private");

            indexFactory.Body.Write("yield return new ")
            .Write(typeof(KeyValuePair <string, Type>))
            .Write("(")
            .String(behavior.ControllerName)
            .Write(", ")
            .Typeof(setup.ImplementingType)
            .Write(")")
            .EndStatement();

            var builder = Activator.CreateInstance(behavior.ProxyBuilderType) as ControllerProxyBuilder;

            var proxy = builder.BuildProxyClass(locatorBuilder, setup.ImplementingType, behavior.CallBuilderType);

            var factoryMethod =
                locatorBuilder.HasMethod($"factory{setup.ImplementingType.Name}").Returns(setup.ImplementingType);

            factoryMethod.Body.Write("return new ").Write(proxy).Write("(this)").EndStatement();

            return(factoryMethod);
        }
Example #7
0
            public INamedReference GenerateFactoryMethod(
                IServiceSetupRecord setup,
                Dictionary <string, INamedReference> ctorParamValueFactoryFields,
                INamedReference valueFactoryField,
                IClassBuilder locatorBuilder,
                INamedReference previousPluginMethod)
            {
                var method = locatorBuilder.HasMethod("error");

                method.Body.Write("cannot compile this");

                return(method);
            }
Example #8
0
        public INamedReference GenerateFactoryMethod(
            IServiceSetupRecord setup,
            Dictionary <string, INamedReference> ctorParamValueFactoryFields,
            INamedReference valueFactoryField,
            IClassBuilder locatorBuilder,
            INamedReference previousPluginMethod)
        {
            var implClass =
                locatorBuilder.HasNestedClass(
                    $"{TypeNameHelper.GetTypeMark(this.GetType())}_implements_{TypeNameHelper.GetTypeMark(setup.InterfaceType)}_{Guid.NewGuid():N}")
                .Implements(setup.InterfaceType)
                .WithModifier("private")
                .WithModifier("sealed");

            var locatorField = implClass.HasField <IServiceLocator>();
            var locatorParam = implClass.WithConstructor().WithModifier("public").WithParam("locator", typeof(IServiceLocator));

            implClass.WithConstructor().Body.Assign(locatorField, a => a.Write(locatorParam));

            foreach (var property in setup.InterfaceType.GetProperties())
            {
                if (!ImplementProperty(implClass, property, locatorField))
                {
                    DefaultImplementProperty(implClass, property);
                }
            }

            foreach (var method in setup.InterfaceType.GetMethods())
            {
                if (method.IsSpecialName)
                {
                    continue;
                }

                if (!ImplementMethod(implClass, method, locatorField))
                {
                    DefaultImplementMethod(implClass, method);
                }
            }

            var factoryMethod =
                locatorBuilder.HasMethod($"factory_{TypeNameHelper.GetTypeMark(setup.InterfaceType)}_{Guid.NewGuid():N}").Returns(setup.InterfaceType).WithModifier("private");

            factoryMethod.Body.Write(" return ")
            .InvokeConstructor(implClass, i => i.WithParam(p => p.Write("this")))
            .EndStatement();

            return(factoryMethod);
        }
Example #9
0
        public INamedReference GenerateFactoryMethod(
            IServiceSetupRecord setup,
            Dictionary <string, INamedReference> ctorParamValueFactoryFields,
            INamedReference valueFactoryField,
            IClassBuilder locatorBuilder,
            INamedReference previousPluginMethod)
        {
            var collectionMethod = locatorBuilder.HasMethod("GetCollectionItems");

            collectionMethod.Body.If(
                condition => condition.Write("collectionType == typeof(").Write(CollectionType).Write(")"),
                then => then.Write("yield return Get(typeof(").Write(setup.InterfaceType).Write("))").EndStatement()).NewLine();

            return(previousPluginMethod);
        }
Example #10
0
        public INamedReference GenerateFactoryMethod(
            IServiceSetupRecord setup,
            Dictionary <string, INamedReference> ctorParamValueFactoryFields,
            INamedReference valueFactoryField,
            IClassBuilder locatorBuilder,
            INamedReference previousPluginMethod)
        {
            var methodName = $"Factory{TypeNameHelper.GetTypeMark(setup.InterfaceType)}_{Guid.NewGuid():N}";

            var method = locatorBuilder.HasMethod(methodName).WithModifier("private").Returns(setup.InterfaceType);

            method.Body.Write("return ").Write("(").Write(setup.InterfaceType).Write(")").Write(valueFactoryField).Write("(this)").EndStatement();

            return(method);
        }
Example #11
0
        public INamedReference GenerateFactoryMethod(
            IServiceSetupRecord setup,
            Dictionary <string, INamedReference> ctorParamValueFactoryFields,
            INamedReference valueFactoryField,
            IClassBuilder locatorBuilder,
            INamedReference previousPluginMethod)
        {
            var factory = locatorBuilder.HasMethod("GetEntityCollectorInstance").Returns(typeof(IEntityCollector));

            factory.WithModifier("private");

            factory.Body.Write("return new ")
            .Write(typeof(EntityCollector))
            .Write("(System.Linq.Enumerable.ToList(this.GetEntitiesCollection()))")
            .EndStatement();

            return(factory);
        }
Example #12
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 #13
0
        public INamedReference GenerateFactoryMethod(
            IServiceSetupRecord setup,
            Dictionary <string, INamedReference> ctorParamValueFactoryFields,
            INamedReference valueFactoryField,
            IClassBuilder locatorBuilder,
            INamedReference previousPluginMethod)
        {
            if (!setup.GetBehavior(s_defaultBehavior).Dispose)
            {
                return(previousPluginMethod);
            }

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

            method.Body.Write("return ")
            .Invoke("TryRegisterDisposable", invocation => invocation.WithParam(p => p.Invoke(previousPluginMethod,
                                                                                              inv => { })))
            .EndStatement();

            return(method);
        }
Example #14
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 #15
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();
        }