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

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

            CSharpCodeProvider csCompiler = new CSharpCodeProvider();

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

            foreach (DataTypeDescriptor 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))
                    {
                        CodeNamespace codeNamespace = new CodeNamespace(dataTypeDescriptorToUse.Namespace);
                        codeNamespace.Types.Add(codeTypeDeclaration);
                        csCompiler.GenerateCodeFromNamespace(codeNamespace, sw, new CodeGeneratorOptions());
                    }

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

            filesToCompile.Sort();


            CompilerParameters compilerParameters = new CompilerParameters();
            compilerParameters.GenerateExecutable = false;
            compilerParameters.GenerateInMemory = true;

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

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

            CSharpCodeProvider compiler = new CSharpCodeProvider();
            CompilerResults 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);
        }