I am currently developing an API that is dynamically compiled for assembly based on some predefined rules stored in XML documents.
It's hard for me to try to get CodeDOM to generate properties with a public receiver and a private setter, decorated with custom attributes.
Here is what I do after:
[Conditional()]
public E3477 E3477 { get; private set; }
But I get this, which is not good, since I don't want the setter to publicly publish:
[Conditional()]
public E3477 E3477
{
get
{
}
set
{
}
}
This is the code I'm using:
var componentRef = string.Format( "E{0}", component.XPathSelectElement( "Element" ).Value );
CodeMemberProperty prop = new CodeMemberProperty();
prop.Name = componentRef;
prop.Type = new CodeTypeReference( componentRef );
prop.HasSet = true;
prop.HasGet = true;
prop.Attributes = MemberAttributes.Public;
CodeAttributeDeclaration conditionalAttr = new CodeAttributeDeclaration( "Conditional" );
prop.CustomAttributes.Add( conditionalAttr );
compositeElementClass.Members.Add( prop );
Is this what I can do even in CodeDOM?
It was reported that the Qaru community uses CodeDom and creates assemblies, and does not use MSBuild, which I tried to do initially, but could not get it to work.
** EDITED with hard-to-read code to see if it can be simplified **
string GenerateDataElementsCode()
{
CodeNamespace globalNamespace = new CodeNamespace();
globalNamespace.Imports.Add( new CodeNamespaceImport( string.Format( "{0}.DataElements", _project.Target.RootNamespace ) ) );
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add( globalNamespace );
CodeNamespace ns = new CodeNamespace( string.Format( "{0}.DataElements", _project.Target.RootNamespace ) );
var codesDoc = XDocument.Load( string.Format( @"{0}\{1}", _project.Source.RootPath, _project.Source.UNCL ) );
var doc = XDocument.Load( string.Format( @"{0}\{1}", _project.Source.RootPath, _project.Source.EDED ) );
foreach ( XNode node in doc.Descendants( "DataElement" ) )
{
CodeTypeDeclaration dataElementClass = new CodeTypeDeclaration()
{
Name = string.Format( "E{0}", node.XPathSelectElement( "Identifier" ).Value ),
IsClass = true
};
dataElementClass.Comments.Add( new CodeCommentStatement( node.XPathSelectElement( "Description" ).Value, true ) );
dataElementClass.BaseTypes.Add( "SimpleObject" );
CodeAttributeDeclaration dataElementAttr = new CodeAttributeDeclaration( "DataElement" );
dataElementAttr.Arguments.Add(
new CodeAttributeArgument
{
Name = "",
Value = new CodePrimitiveExpression( node.XPathSelectElement( "Identifier" ).Value )
} );
dataElementAttr.Arguments.Add(
new CodeAttributeArgument
{
Name = "",
Value = new CodePrimitiveExpression( node.XPathSelectElement( "Name" ).Value )
} );
dataElementAttr.Arguments.Add(
new CodeAttributeArgument
{
Name = "",
Value = new CodePrimitiveExpression( node.XPathSelectElement( "Description" ).Value )
} );
CodeAttributeDeclaration dataElementFormatAttr = new CodeAttributeDeclaration( "DataElementFormat" );
dataElementFormatAttr.Arguments.Add(
new CodeAttributeArgument
{
Name = "Cardinality",
Value = new CodePrimitiveExpression( node.XPathSelectElement( "Cardinality" ).Value )
} );
dataElementClass.CustomAttributes.Add( dataElementAttr );
dataElementClass.CustomAttributes.Add( dataElementFormatAttr );
var codes = codesDoc.XPathSelectElements( "SimpleDataElements/SimpleDataElement/CodeLists/CodeList" ).Where( a => a.XPathSelectElement( "../../Code" ).Value == node.XPathSelectElement( "Identifier" ).Value );
if ( codes.Count() > 0 )
{
CodeTypeDeclaration codesClass = new CodeTypeDeclaration( "Codes" );
codesClass.Attributes = MemberAttributes.Static;
codesClass.IsClass = true;
foreach ( XNode codeNode in codes )
{
CodeMemberField con = new CodeMemberField( typeof( string ), string.Format( "Code{0}", codeNode.XPathSelectElement( "Code" ).Value ) );
con.Attributes = MemberAttributes.Public | MemberAttributes.Const;
con.InitExpression = new CodePrimitiveExpression( codeNode.XPathSelectElement( "Code" ).Value );
con.Comments.Add( new CodeCommentStatement( codeNode.XPathSelectElement( "Description" ).Value, true ) );
codesClass.Members.Add( con );
}
dataElementClass.Members.Add( codesClass );
}
ns.Types.Add( dataElementClass );
}
unit.Namespaces.Add( ns );
var provider = new Microsoft.CSharp.CSharpCodeProvider();
using ( var sourceCode = new StringWriter() )
using ( var indentedTextWriter = new IndentedTextWriter( sourceCode, " " ) )
{
provider.GenerateCodeFromCompileUnit( unit,
indentedTextWriter,
new CodeGeneratorOptions() { BracingStyle = "C" } );
return sourceCode.GetStringBuilder().ToString();
}
}