1

I have custom attribute like below

public class PageUrlAttribute : Attribute
{


    public PageUrlAttribute(string host)
    {
        Host = host;
        Path = string.Empty;
        Protocol = "http";
    }

    public string Protocol { get; set; }

    public string Path { get; set; }

    public string Host { get; private set; }
 }

I use it in another class like below

[PageUrl("test.com", Protocol = "https")]
public class LoginPage : AbstractPage
{
}

Now i want to set this value "test.com" from app.config file.

I tried to set like below

[PageUrl(ConfigurationManager.AppSettings["URL"], Protocol = "https")]

but this throws error saying Attribute expects constant. How to resolve this issue or any other idea?

James
  • 1,827
  • 5
  • 39
  • 69
  • the error states you need a constant value. That means e.g. a hardcoded string. The App config is loaded at runtime and therefore is not constant, which means you cannot use it for that. – Brezelmann Apr 03 '19 at 14:59
  • @Brezelmann i understood that but i need some other solution – James Apr 03 '19 at 15:01
  • Possible duplicate of [Change Attribute's parameter at runtime](https://stackoverflow.com/questions/51269/change-attributes-parameter-at-runtime) – Rainbow Apr 03 '19 at 15:06
  • what do you want to achieve with this Attribute? In which context are you using it? Are these Values constant at runtime or are they able to change? – Brezelmann Apr 04 '19 at 06:28
  • @brezelmann yes those value will be constant during run time. I am running automated tests so url will change as per environment – James Apr 05 '19 at 04:46
  • then you could create two classes with these Values as const and use the Preprocessor Directives to generate the Attribute based on your Environment – Brezelmann Apr 05 '19 at 06:17
  • @brezelmann do you have example for it or can you post code? – James Apr 05 '19 at 07:23
  • @James see if my answer can help you a little bit :). – Brezelmann Apr 05 '19 at 08:05

2 Answers2

2

In the comments you stated the Variables you need there are runtime constant. That means they won't change during execution, so you could declare them in a public static class with const Fields:

public static class DebugVariables
    {
        public const string TEST_URL = "test.com";

        public const string HTTPS_PROTOCOL = "https";
    }

You can now use this class to in your Attribute like this:

[PageUrl(DebugVariables.TEST_URL, Protocol = DebugVariables.HTTPS_PROTOCOL)]

And now to combine that knowledge to your case: First of all check your Project Settings (right click on your Project and the Tab Build) if you have set the checkbox to Define DEBUG Constant. if you've set this one (or any other Symbol you wanted) in the Debug build and removed it in your Release Build you can now use this together with the Preprocessor Directive #if, #else and #endif to define the following:

#if DEBUG
    [PageUrl(DebugVariables.TEST_URL, Protocol = DebugVariables.HTTPS_PROTOCOL)]
#else
    [PageUrl(ProductionVariables.TEST_URL, Protocol = ProductionVariables.HTTPS_PROTOCOL)]
#endif
    public class LoginPage : AbstractPage
    {
    }

If you set the DEBUG Constant correctly you should see that one of the Paths is greyed out and the other is not. If you now switch to your Release Build you should see the Change that the DEBUG is greyed out and the other one is correctly highlighted.

That means you could create as many static classes with const Fields as you need and then use the syntax above to set the Value depending on your Environment.

Brezelmann
  • 359
  • 3
  • 16
  • i tried like this public const string TEST_URL = ConfigurationManager.AppSettings["URL"]; – James Apr 05 '19 at 11:51
  • No and that’s why i need help – James Apr 06 '19 at 13:23
  • Well the problems remains the same. You cannot use a Value that is theoretically able to change so you can never use an input from a File. My Idea here was to change your problem. Instead of having to Appsettings files that you have to read in that cannot be (from the pov of the programm) constant you have two constant classes that serve as the Input for your Attributes. With this you could at least simulate something similar. Otherwise your Approach with reading from a file is impossible. – Brezelmann Apr 07 '19 at 14:29
0

Attribute arguments must be compile-time constants but configuration settings are not compile time.

this could be possible, where reading config values in the constructor

Host = ConfigurationManager.AppSettings["URL"];

If you have multiple URLs, send key as a parameter to the constructor.

Host = ConfigurationManager.AppSettings[parameter];

cubcoder00
  • 55
  • 2
  • 9