0

I am trying to generate auto propery using codedom but with no luck. I tried different solutions and each one causing issue. I am trying to generate something like below

        [FindsBy(How = How.Id, Using = "AllTabs")]
        public IWebElement SaveButton { get; set; }

I was able to create attribute with no issue but unable to create auto property.

if I try to use the solution listed from here autoproperty i.e

        CodeTypeDeclaration newType = new CodeTypeDeclaration("TestType");
        CodeSnippetTypeMember snippet = new CodeSnippetTypeMember();

        snippet.Comments.Add(new CodeCommentStatement("this is integer property", true));
        snippet.Text="public int IntergerProperty { get; set; }";

        newType.Members.Add(snippet);

Then I am unable to add the attribute over the Property, it just prints out the property without the attribute. Is there any way to generate auto property and also use attributes?

  • 1
    https://learn.microsoft.com/en-us/dotnet/api/system.codedom.codeattributedeclaration?redirectedfrom=MSDN&view=net-5.0 – TheGeneral Aug 23 '21 at 05:22

2 Answers2

0

Evidently you did not understand the answer you refer to. It is inserting literal text into the source stream, so the following should work for you:

        var newType = new CodeTypeDeclaration("TestType");
        var snippet = new CodeSnippetTypeMember();

        snippet.Text = @"
[FindsBy(How = How.Id, Using = ""AllTabs"")]
public IWebElement SaveButton { get; set; }
";

        newType.Members.Add(snippet);

Just be very aware that CodeSnippetTypeMember completely ignores the validation that CodeDom provides, so it's very easy to generate non-compiling code using this mechanism. Roslyn does support auto-properties natively when in a C# context.

As the accepted answer on the linked question states, the reason that CodeDom does not support auto-properties is that they are syntactic sugar that do not exist in all .NET languages, and CodeDom is intended to be as language-agnostic as possible. Therefore, CodeDom cannot know about or support the concept of an auto-property.

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
0

To avoid using a snippet with its risk of errors uncaught until actually compiling, you can use a method to automatically create properties with a backing field (which is what the compiler internally does with an auto-property anyway):

private static CodeMemberProperty makeAutoProperty(CodeTypeDeclaration containingClass, CodeTypeReference propertyType, string propertyName )
        {
            CodeMemberField backingField = new CodeMemberField();
            backingField.Name = propertyName + "_";
            backingField.Type = propertyType;
            CodeVariableReferenceExpression backingFieldRef = new CodeVariableReferenceExpression(backingField.Name);
            containingClass.Members.Add(backingField);

            CodeMemberProperty property = new CodeMemberProperty();
            property.Name = propertyName;
            property.Type = propertyType;
            property.HasGet = true;
            property.HasSet = true;
            property.GetStatements.Add(new CodeMethodReturnStatement(backingFieldRef));
            property.SetStatements.Add(new CodeAssignStatement(backingFieldRef, new CodeVariableReferenceExpression("value")));
            containingClass.Members.Add(property);

            return property;
        }

This makes it just as easy to add as an autoproperty. You can use the method like this:

            // Make the property
            CodeMemberProperty saveButtonField = makeAutoProperty(_class, new CodeTypeReference("IWebElement"), "saveButton");
            // Modify the access
            saveButtonField.Attributes = MemberAttributes.Public | MemberAttributes.Final;
            // Add the attribute decorator
            var attr = new CodeAttributeDeclaration(new CodeTypeReference("FindsBy"));
            saveButtonField.CustomAttributes.Add(attr);

This is the output:

        private IWebElement saveButton_;
        [FindsBy()]
        public IWebElement saveButton
        {
            get
            {
                return saveButton_;
            }
            set
            {
                saveButton_ = value;
            }
        }
Christopher Hamkins
  • 1,442
  • 9
  • 18