Skip to content

Commit 31e2722

Browse files
authored
Merge pull request #584 from igotinfected/fix/flaky-codedomprovider-tests
Make calls to CodeDomProvider thread-safe (fixes flaky tests)
2 parents 4f526b8 + e8a83e3 commit 31e2722

3 files changed

Lines changed: 19 additions & 20 deletions

File tree

XmlSchemaClassGenerator/Models/ClassModel.cs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.CodeDom;
33
using System.CodeDom.Compiler;
44
using System.Collections.Generic;
@@ -345,19 +345,8 @@ public override CodeExpression GetDefaultValueFor(string defaultString, bool att
345345

346346
if (rootClass is SimpleModel || rootClass is EnumModel)
347347
{
348-
string reference, val;
349-
350-
using (var writer = new System.IO.StringWriter())
351-
{
352-
CSharpProvider.GenerateCodeFromExpression(rootClass.GetDefaultValueFor(defaultString, attribute), writer, new CodeGeneratorOptions());
353-
val = writer.ToString();
354-
}
355-
356-
using (var writer = new System.IO.StringWriter())
357-
{
358-
CSharpProvider.GenerateCodeFromExpression(new CodeTypeReferenceExpression(GetReferenceFor(referencingNamespace: null)), writer, new CodeGeneratorOptions());
359-
reference = writer.ToString();
360-
}
348+
var val = GenerateCSharpCodeFromExpression(rootClass.GetDefaultValueFor(defaultString, attribute));
349+
var reference = GenerateCSharpCodeFromExpression(new CodeTypeReferenceExpression(GetReferenceFor(referencingNamespace: null)));
361350

362351
return new CodeSnippetExpression($"new {reference} {{ {Configuration.TextValuePropertyName} = {val} }};");
363352
}

XmlSchemaClassGenerator/Models/SimpleModel.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.CodeDom;
33
using System.CodeDom.Compiler;
44
using System.Collections.Generic;
@@ -45,9 +45,7 @@ private static string GetFullTypeName(string typeName, CodeTypeReference typeRef
4545
{
4646
Type = { Options = CodeTypeReferenceOptions.GenericTypeParameter }
4747
};
48-
using var writer = new System.IO.StringWriter();
49-
CSharpProvider.GenerateCodeFromExpression(typeOfExpr, writer, new CodeGeneratorOptions());
50-
var fullTypeName = writer.ToString();
48+
var fullTypeName = GenerateCSharpCodeFromExpression(typeOfExpr);
5149
Debug.Assert(fullTypeName.StartsWith("typeof(") && fullTypeName.EndsWith(")"), $"Expected typeof expression, got: {fullTypeName}");
5250
return fullTypeName.Substring(7, fullTypeName.Length - 8);
5351
}

XmlSchemaClassGenerator/Models/TypeModel.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.CodeDom;
33
using System.CodeDom.Compiler;
44
using System.Collections.Generic;
@@ -16,7 +16,19 @@ namespace XmlSchemaClassGenerator;
1616
[DebuggerDisplay("{Name}")]
1717
public abstract class TypeModel(GeneratorConfiguration configuration) : GeneratorModel(configuration)
1818
{
19-
protected static readonly CodeDomProvider CSharpProvider = CodeDomProvider.CreateProvider("CSharp");
19+
private static readonly CodeDomProvider CSharpProvider = CodeDomProvider.CreateProvider("CSharp");
20+
private static readonly object CSharpProviderLock = new();
21+
22+
// prevents simultaneous access to the static CodeDomProvider, which is not thread-safe
23+
protected static string GenerateCSharpCodeFromExpression(CodeExpression expression)
24+
{
25+
lock (CSharpProviderLock)
26+
{
27+
using var writer = new System.IO.StringWriter();
28+
CSharpProvider.GenerateCodeFromExpression(expression, writer, new CodeGeneratorOptions());
29+
return writer.ToString();
30+
}
31+
}
2032

2133
public NamespaceModel Namespace { get; set; }
2234
public XmlSchemaElement RootElement { get; set; }

0 commit comments

Comments
 (0)