3

I have created website using .Net Core 2.0. Now I want to store some values which are not user specific, I want to make those value shareable across all the users which are logged in. So for that I can use Application Variable. But in .Net Core 2.0 there is no built in way to achieve this.

What I have tried

I have created one class as below.

public class ApplicationLevelData
    {
        public Guid TestProperty { get; set; }

        public ApplicationLevelData()
        {
            TestProperty = Guid.NewGuid(); // this data will comes from database (only once)
        }
    }

After that under Startup.cs file under ConfigureServices method I have wrote below line.

services.AddSingleton<ApplicationLevelData>();

And in each Controller I need to inject that service as below.

private ApplicationLevelData _appData;

public HomeController(ApplicationLevelData appData)
{
    _appData = appData;
}

And after that we can user that in entire Controller.

But, I don't want this Inject thing. Can we make application data available using HttpContext?

Can anyone suggest me the way that how can I create Application variable in .Net Core 2.0?

Any help would be highly appreciated.

Thanks.

prog1011
  • 3,425
  • 3
  • 30
  • 57
  • 1
    Can you explain *why* you don't want to use dependency injection? I mean, you could just use the singleton pattern if you really want - I don't see why you'd want to use the `HttpContext` here. – Jon Skeet Apr 19 '18 at 06:21
  • Can you explain *why* you don't want to use dependency injection? I mean, you could just use the singleton pattern if you really want - I don't see why you'd want to use the `HttpContext` here. – Jon Skeet Apr 19 '18 at 06:21
  • Just use static property then? Since you don't want to use dependency injection, drawbacks of using static properties won't be a problem for you I guess. – Evk Apr 19 '18 at 06:26
  • @DaisyShipton I have many controllers in my application and I need to Inject it in each controller. So better is If I can directly get those values from `HttpContext` is better. Because `HttpContext` is by default available in all controllers – prog1011 Apr 19 '18 at 06:27
  • @Evk - can you please paste code in the answer which use `static` property so I can have better idea and use it. That would be more helpful for me – prog1011 Apr 19 '18 at 06:33
  • 2
    But it sounds like the data has nothing to do with the `HttpContext` at all, so why include it there? If you basically want a singleton and don't want the testing and isolation benefits of dependency injection, use the singleton pattern. I wouldn't personally do that myself - I'd use dependency injection to make it clear where you need it, and to enable easy testing - but it's certainly feasible, and makes more sense IMO than using `HttpContext` for something which is unrelated to the actual request. – Jon Skeet Apr 19 '18 at 07:12
  • You can use base class for this if you dont want to use depency injection. – hsyn.ozkara Apr 19 '18 at 07:20

2 Answers2

1

Understand the reasoning behind not wanting to inject, you can still use a singleton and access the value from HttpContext using this:

HttpContext.RequestServices.GetService<ApplicationLevelData>();

To use this function you will have to import Microsoft.Extensions.DependencyInjection.

You can also create an extension function for this if you like:

public static class HttpContextExtensions {
    public static ApplicationLevelData GetAppData(this HttpContext HttpContext)
        => HttpContext.RequestServices.GetService<ApplicationLevelData>();
}

You can now get your ApplicationLevelData within any controller by using HttpContext.GetAppData().

Neville Nazerane
  • 6,622
  • 3
  • 46
  • 79
  • Can you please explain me in details how can I implement it in my project. your little more help would be more helpful for me. Thanks :) – prog1011 Apr 19 '18 at 09:27
  • I have added some more details. I also see you have created the singleton. You simply need to create the class I have shown – Neville Nazerane Apr 19 '18 at 09:53
  • Can you please tell me where do I need to write below line? in which file ? `HttpContext.RequestServices.GetService();` – prog1011 Apr 19 '18 at 10:59
  • That line can be used in any controller as you had asked in your question. However as long as you are making the class I have shown above, you can ignore that first line – Neville Nazerane Apr 19 '18 at 11:01
  • I got error : Method 'object System.IServiceProvider.GetService(Type) dose not have type parameters – prog1011 Apr 19 '18 at 11:17
  • you need to have `using Microsoft.Extensions.DependencyInjection` at the start of the file – Neville Nazerane Apr 19 '18 at 11:22
0
public static class Globals
{
    public static Guid TestProperty { get; set; }
}

Usage (in any place):

var guid = Globals.TestProperty;

You said:

this data will comes from database (only once)

You can also create as private set, like this:

public static Guid TestProperty { get; private set; }

Then it is only possible to set the value inside the class Globals, making this sort of a readonly property.

Also, please see this answer about the constructor. It is a bit different on a static class.

Guilherme
  • 5,143
  • 5
  • 39
  • 60