コード例 #1
0
        private static CompatibilityCheckResult CheckAgainsAppCode(DataTypeDescriptor dataTypeDescriptorToTest, bool includeDataTypeDescriptor)
        {
            List <string> filesToCompile = GetAppCodeFiles().ToList();

            if (filesToCompile.Count == 0)
            {
                return(new CompatibilityCheckResult());
            }

            var csCompiler = new CSharpCodeProvider();

            List <Assembly> referencedAssemblies = new List <Assembly>();
            var             codeTypeDeclarations = new Dictionary <string, List <CodeTypeDeclaration> >();

            foreach (var dataTypeDescriptor in DataMetaDataFacade.GeneratedTypeDataTypeDescriptors)
            {
                if (!includeDataTypeDescriptor && dataTypeDescriptor.DataTypeId == dataTypeDescriptorToTest.DataTypeId)
                {
                    continue;
                }

                DataTypeDescriptor dataTypeDescriptorToUse = dataTypeDescriptor;
                if (includeDataTypeDescriptor && dataTypeDescriptor.DataTypeId == dataTypeDescriptorToTest.DataTypeId)
                {
                    dataTypeDescriptorToUse = dataTypeDescriptorToTest;
                }

                referencedAssemblies.AddRange(InterfaceCodeGenerator.GetReferencedAssemblies(dataTypeDescriptorToUse));
                CodeTypeDeclaration codeTypeDeclaration = InterfaceCodeGenerator.CreateCodeTypeDeclaration(dataTypeDescriptorToUse);

                List <CodeTypeDeclaration> declarations;
                if (!codeTypeDeclarations.TryGetValue(dataTypeDescriptorToUse.Namespace, out declarations))
                {
                    declarations = new List <CodeTypeDeclaration>();
                    codeTypeDeclarations.Add(dataTypeDescriptorToUse.Namespace, declarations);
                }
                declarations.Add(codeTypeDeclaration);

                string tempFilePath = GetTempFileName(dataTypeDescriptorToUse);
                filesToCompile.Add(tempFilePath);

                using (FileStream file = File.Create(tempFilePath))
                {
                    using (var sw = new StreamWriter(file))
                    {
                        var codeNamespace = new CodeNamespace(dataTypeDescriptorToUse.Namespace);
                        codeNamespace.Types.Add(codeTypeDeclaration);
                        csCompiler.GenerateCodeFromNamespace(codeNamespace, sw, new CodeGeneratorOptions());
                    }

                    var sb = new StringBuilder();
                    using (var sw = new StringWriter(sb))
                    {
                        csCompiler.GenerateCodeFromMember(codeTypeDeclaration, sw, new CodeGeneratorOptions());
                    }
                }
            }

            filesToCompile.Sort();


            var compilerParameters = new CompilerParameters
            {
                GenerateExecutable = false,
                GenerateInMemory   = true
            };

            compilerParameters.ReferencedAssemblies.AddRangeIfNotContained(referencedAssemblies.Select(f => f.Location).ToArray());
            compilerParameters.ReferencedAssemblies.AddRangeIfNotContained(CodeGenerationManager.CompiledAssemblies.Select(f => f.Location).ToArray());
            compilerParameters.AddLoadedAssemblies(false);
            compilerParameters.AddAssemblyLocationsFromBin();
            compilerParameters.AddCommonAssemblies();
            compilerParameters.RemoveGeneratedAssemblies();


            var codeCompileUnit = new CodeCompileUnit();

            foreach (var kvp in codeTypeDeclarations)
            {
                var codeNamespace = new CodeNamespace(kvp.Key);
                codeNamespace.Types.AddRange(kvp.Value.ToArray());
                codeCompileUnit.Namespaces.Add(codeNamespace);
            }

            var compiler      = new CSharpCodeProvider();
            var compileResult = compiler.CompileAssemblyFromFile(compilerParameters, filesToCompile.ToArray());

            if (compileResult.Errors.Count == 0)
            {
                return(new CompatibilityCheckResult());
            }

            // Checking for a missing assembly error, if it is present, that means that App_Code check isn't applicable due to circular reference
            foreach (CompilerError error in compileResult.Errors)
            {
                if (error.ErrorNumber == "CS0012" && error.ErrorText.Contains("Composite.Generated"))
                {
                    return(new CompatibilityCheckResult());
                }
            }

            return(new CompatibilityCheckResult(compileResult));
        }