10

I have default Program.cs file from Web Api template in .NET 6.0. I am adding variable "test" so I can use its value in controllers.

var builder = WebApplication.CreateBuilder(args);
const string test = "test123";
builder.Configuration.Bind(test);

//rest of the file...

And now I want to use variable "test" outside Program.cs but I have no idea how to do it. I cannot just simply use it because when trying to read it in controller like this:

string localVar = test;

I am getting an error "'test' is not null here. Cannot use local variable or local function declared in a top-level statement in this context". This is probably some stupid mistake but I can't figure it out...

8
  • 1
    is it a variable or a constant? Bind just for binding configuration values. you need to inject a singleton, look into dependency injection Commented Apr 1, 2022 at 10:11
  • @MarkHomer it doesn't matter it its const or var - it gives the same error. And thanks for the tip. Commented Apr 1, 2022 at 10:16
  • @Voyak const is implicitly static, so it does matter. Commented Apr 1, 2022 at 10:18
  • might want to start here: learn.microsoft.com/en-us/aspnet/core/mvc/controllers/… Commented Apr 1, 2022 at 10:23
  • @PeterCsala I want it to be a const (sorry for a mistake, I edited the post). But still error is the same even with const. Commented Apr 1, 2022 at 10:25

5 Answers 5

12

Add public partial class Program { } at the very end of your Program.cs file and add constant, property or whatever you like in there.

Sign up to request clarification or add additional context in comments.

Comments

10

Starting C# 9, we don't need to explicitly mention the Main method in Program.cs file as we can use the top-level statements feature. However, it doesn't mean that we shouldn't use the default Program class in the created file at all. In your case, you have a need to define the static/const property so you can change the newly created structure into the old one.

namespace WebApplication;

public class Program
{
    public static string Test { get; private set; }
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        Program.Test = "approach1";
        builder.Services.Configure<MyOptions>(x => x.Test = "approach2");
        ///
}

public class MyOptions
{
    public string Test { get; set; }
}

I assumed that you have a need to set the value to the Program.Test field during runtime, so in the first approach, I used the static field with a private set; accessor instead of the constant.

In the second approach, I used the C# options feature to configure the MyOptions.Test field value, this will be very flexible and useful to write unit tests later. But, you need to inject the MyOptions class wherever is required.

In the below controller template, I specified how to access the configured values at Program.cs file, inside the Get method

public class TestController : ControllerBase
{
    private readonly MyOptions _myOptions;

    public TestController (IOptions<MyOptions> myOptions)
    {
        _myOptions = myOptions.Value;
    }

    public IActionResult Get()
    {
        string test1 = Program.Test;
        string test2 = _myOptions.Test;
        ///
    }

}

1 Comment

The options feature is supper. Thanks for the info. I was using options patter, but did not know I can used like that.
3

You can create a Globals.cs file:

public static class Globals
{
    public const string Test = "test123";
}

And access it from any class like this:

string localVar = Globals.Test;

You can also put variables in the class, just make sure you mark them as public static.

Comments

1

Just to add my experience - if you remove the "static" attribute from your functions, you can use variables you declare in the program.cs file

using System.IO;
//equivelant to global variable
List<Task> tasks = new List<Task>();
string csv = args[0];
...

List<string> sendBatch(string outputFolder, List<string> files){
  ...
  using (WebClient wclient = new WebClient())
  {
    string file = Path.Combine( outputFolder, file + ".png");

    tasks.Add(wclient.DownloadFileTaskAsync(new Uri(url.Value), file));

    retval.Add(file);
  }
  ...
}

Edit - just realized this was for other files outside program.cs so not revelvant. but I did stumble across this post in my search for trying to do the above.

Comments

0
// An other way to do this is by using a normal Public Class with a normal     
// property and method in the root of your application at the same level 
// as your Program.cs
    
public class StaticDetails
{
    public static string Test { get; private set; }
   
    
    public static void ChangeTest(string testValue)
    {
        Test = testValue;
    }
}
// ***** 
// Program.cs 
//
// Then from Program.cs you would just modify it as shown below:

StaticDetails.ChangeTest("Hello");
    
// Then from your controller you would simply access as normal like 
// this:
    
var temp = StaticDetails.Test;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.