Esempio n. 1
0
        public void FinalizeAndAddToAssembly()
        {
            if (IsFinalized)
            {
                LogHelper.Context.Log.WarnFormat("The dynamic class '{0}.{1}' was already to dynamic assembly.",
                                                 ClassNamespace, ClassName);
                return;
            }

            IsFinalized = true;

            foreach (var inProgressFunctionData in _inProgressConstructorsData)
            {
                _sharpCode.Append(inProgressFunctionData.GetCode());
                _sharpCode.AppendLine();
            }

            foreach (var inProgressFunctionData in _inProgressMethodsData)
            {
                _sharpCode.Append(inProgressFunctionData.GetCode());
                _sharpCode.AppendLine();
            }

            _sharpCode.AppendLine("}");
            _sharpCode.AppendLine("}");


            StringBuilder sharpCodeWithUsingStamentes;

            if (_usingStatments.Count > 0)
            {
                sharpCodeWithUsingStamentes = new StringBuilder();

                foreach (var referencedNamespace in _usingStatments)
                {
                    sharpCodeWithUsingStamentes.AppendLine($"using {referencedNamespace};");
                }

                sharpCodeWithUsingStamentes.Append(_sharpCode);
            }
            else
            {
                sharpCodeWithUsingStamentes = _sharpCode;
            }

            _dynamicAssemblyBuilder.AddCSharpFile(sharpCodeWithUsingStamentes.ToString());
        }
        public override void GenerateAutoImplementedServiceClassCSharp(IDynamicAssemblyBuilder dynamicAssemblyBuilder,
                                                                       string dynamicImplementationsNamespace,
                                                                       out string generatedClassFullName)
        {
            // Add assemblies referenced by service
            var className = $"{ImplementedInterfaceTypeInfo.Type.Name}_{GlobalsCoreAmbientContext.Context.GenerateUniqueId()}";

            generatedClassFullName = $"{dynamicImplementationsNamespace}.{className}";

            var classStrBldr = new StringBuilder(5000);
            var classMemberVariablesStrBldr = new StringBuilder(1000);

            classStrBldr.AppendLine();
            classStrBldr.AppendLine("using System;");

            classStrBldr.AppendLine($"namespace {dynamicImplementationsNamespace}");
            classStrBldr.AppendLine("{");
            classStrBldr.AppendLine($"public sealed class {className}: {ImplementedInterfaceTypeInfo.TypeCSharpFullName}");
            classStrBldr.AppendLine("{");

            void ProcessType(Type type, ref bool stopProcessingParam)
            {
                foreach (var methodInfo in type.GetMethods())
                {
                    if ((methodInfo.Attributes & MethodAttributes.SpecialName) > 0)
                    {
                        continue;
                    }

                    var methodSignature = GetMethodSignature(methodInfo);

                    classStrBldr.Append(methodSignature);

                    if (_methodInfoToSimilarOrSameAutoGeneratedServiceMethodElementMap.TryGetValue(methodInfo, out var autoGeneratedServiceMethodElement))
                    {
                        if (autoGeneratedServiceMethodElement.ImplementedMehodInfo == methodInfo)
                        {
                            AddMethodBodyForImplementedMethod(dynamicAssemblyBuilder, autoGeneratedServiceMethodElement,
                                                              classStrBldr, classMemberVariablesStrBldr);
                        }
                        else
                        {
                            AddMethodBodyForNonImplementedMethodWithSimilarImplementedMethod(dynamicAssemblyBuilder, methodInfo,
                                                                                             autoGeneratedServiceMethodElement, classStrBldr);
                        }
                    }
                    else
                    {
                        classStrBldr.AppendLine("{");

                        foreach (var outParameterInfo in methodInfo.GetParameters().Where(x => x.IsOut))
                        {
                            classStrBldr.AppendLine($"{outParameterInfo.Name}=default({outParameterInfo.ParameterType.GetTypeNameInCSharpClass()});");
                        }

                        if (methodInfo.ReturnType != typeof(void))
                        {
                            classStrBldr.Append($"return default({methodInfo.ReturnType.GetTypeNameInCSharpClass()});");
                            classStrBldr.AppendLine();
                        }

                        classStrBldr.AppendLine("}");
                    }

                    classStrBldr.AppendLine();
                }

                foreach (var propertyInfo in type.GetProperties())
                {
                    var propertyHeader = GetPropertyHeader(propertyInfo);

                    void AddGetSet()
                    {
                        classStrBldr.Append(" { get;");

                        if (propertyInfo.SetMethod != null)
                        {
                            classStrBldr.Append(" set;");
                        }

                        classStrBldr.Append("}");
                    }

                    classStrBldr.Append(propertyHeader);

                    if (_propertyInfoToSimilarOrSameAutoGeneratedServicePropertyElementMap.TryGetValue(propertyInfo,
                                                                                                       out var similarOrSameAutoGeneratedServicePropertyElement))
                    {
                        var similarPropertyInfo = similarOrSameAutoGeneratedServicePropertyElement.ImplementedPropertyInfo;
                        if (similarPropertyInfo == propertyInfo)
                        {
                            AddGetSet();
                            classStrBldr.AppendLine($"={similarOrSameAutoGeneratedServicePropertyElement.ReturnValueElement.GenerateValueCSharp(dynamicAssemblyBuilder)};");
                        }
                        else
                        {
                            var privateVariableName = $"_{propertyInfo.DeclaringType.Name}_{propertyInfo.Name}_{GlobalsCoreAmbientContext.Context.GenerateUniqueId()}";

                            // Not, for nullable values and reference types, we can check for null, to set if the value was initialized.
                            // however, to make it simple, and also to avoid calling the other class property every time, in case the other property
                            // value is null, lets use the valueWasSet variable for all cases.
                            var valueWasSetVariableName = $"{privateVariableName}_ValueWasSet";


                            classStrBldr.AppendLine();
                            classStrBldr.AppendLine("{");

                            classStrBldr.AppendLine("get");
                            classStrBldr.AppendLine("{");

                            classStrBldr.AppendLine($"if ({valueWasSetVariableName}) return {privateVariableName};");

                            classStrBldr.Append($"{privateVariableName}=(({similarPropertyInfo.DeclaringType.GetTypeNameInCSharpClass()})this)");
                            classStrBldr.AppendLine($".{similarPropertyInfo.Name};");
                            classStrBldr.AppendLine($"{valueWasSetVariableName}=true;");
                            classStrBldr.AppendLine($"return {privateVariableName};");
                            classStrBldr.AppendLine("}");

                            if (propertyInfo.SetMethod != null)
                            {
                                classStrBldr.AppendLine("set");
                                classStrBldr.AppendLine("{");
                                classStrBldr.AppendLine($"{privateVariableName}=value;");
                                classStrBldr.AppendLine($"{valueWasSetVariableName}=true;");

                                classStrBldr.AppendLine("}");
                            }

                            classStrBldr.AppendLine("}");
                            classStrBldr.AppendLine($"private bool {valueWasSetVariableName};");
                            classStrBldr.AppendLine($"private {propertyInfo.PropertyType.GetTypeNameInCSharpClass()} {privateVariableName};");
                        }
                    }
                    else
                    {
                        AddGetSet();
                        classStrBldr.AppendLine();
                    }
                }
            }

            var stopProcessing = false;

            TypeMemberLookupHelper.ProcessTypeImplementedInterfacesAndBaseTypes(ImplementedInterfaceTypeInfo.Type,
                                                                                ProcessType, ref stopProcessing);

            classStrBldr.Append(classMemberVariablesStrBldr);

            // Close class
            classStrBldr.AppendLine("}");

            // Close namespace
            classStrBldr.AppendLine("}");

            dynamicAssemblyBuilder.AddCSharpFile(classStrBldr.ToString());
        }