What’s the best way to add assembly attributes when code is compiled using CodeDom?
We are using CodeDomProvider to generate and execute the business code layer and now I wanted to add some assembly attributes. (I know, some attributes can be specified via CompilerAttributes.)
I tried the following piece of test code, something I would do under C#:
namespace CodeGen;
interface
uses
System.CodeDom.*,
System.IO,
System.Reflection;
type
Program = class
public
class method Main(args: array of String): Int32;
end;
implementation
class method Program.Main(args: array of String): Int32;
begin
var compileUnit := new CodeCompileUnit();
var versionAttribute := new CodeTypeReference(typeOf(AssemblyVersionAttribute));
var declaration: CodeAttributeDeclaration := new CodeAttributeDeclaration(versionAttribute, new CodeAttributeArgument(new CodePrimitiveExpression("1.0.2.42")));
compileUnit.AssemblyCustomAttributes.Add(declaration);
var provider := CodeDomProvider.CreateProvider("Oxygene");
var writer: StringWriter := new StringWriter();
provider.GenerateCodeFromCompileUnit(compileUnit, writer, new CodeGeneratorOptions());
Console.WriteLine(writer.ToString());
end;
end.
But it seems like the assembly attribute is not generated. I realized then that
provider.Supports(GeneratorSupport.Resources)
is not set.
So, what is your recommendation to automatically build attribute resources? I assume, you need to do something similar when you generate the property file AssemblyInfo.pas
Just realized, in contrary to C#, Oxygene needs the namespace in the AssemblyInfo.pas.
When added the namespace:
compileUnit.Namespaces.Add( new CodeNamespace("MyNamespace") );
GenerateCodeFromCompileUnit will actually produce the expected attribute.
Sorry, still one problem I have overseen: the attribute is added before the interface and uses section instead of after. Any ideas / hints?
Also, extra
{$HIDE H7}
{$HIDE W1}
{$HIDE W27}
{$HIDE H11}
get added. Why?
I played a bit more with generating the “AssemblyInfo.pas” file for the CodeDom Compilation and I had no luck in generating a file which works.
The code above produces the following item:
//------------------------------------------------------------------------------
// <autogenerated>
// This Oxygene source code was generated by a tool.
// Runtime Version: 4.0.30319.42000
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------------
{$HIDE H7}
{$HIDE W1}
{$HIDE W27}
{$HIDE H11}
namespace MyNamespace;
[assembly: System.Reflection.AssemblyVersionAttribute('1.0.2.42')]
interface
uses
System.Reflection,
System.Resources,
System.Runtime.InteropServices;
implementation
end.
but this does not set the attribute!
- The Assembly attributes have to be after in the interface section!
- At least the namespace is not relevant
So, when I change the generated output to the following, then the pas file compiled together with this “AssemblyInfo.pas” will have the proper attributes set in the DLL:
//------------------------------------------------------------------------------
// <autogenerated>
// This Oxygene source code was generated by a tool.
// Runtime Version: 4.0.30319.42000
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------------
{$HIDE H7}
{$HIDE W1}
{$HIDE W27}
{$HIDE H11}
namespace MyNameSpace;
interface
uses
System.Reflection,
System.Resources,
System.Runtime.InteropServices;
[assembly: AssemblyVersionAttribute('1.0.2.42')]
implementation
end.
So, I have no clue, how to bring GenerateCodeFromCompileUnit from the Oxygene Code Provider to produce a proper file containing Assembly Attributes.
And hint / idea is welcome.
Thanks, logged as bugs://75581
bugs://75581 got closed with status nochangereq.
bugs://75581 got reopened.
bugs://75581 got closed with status fixed.
bugs://i63547 was closed as fixed.