How to use "IWebHostEnvironment" inside static class in ASP Core

7.3k Views Asked by At

Is there a way to use "IWebHostEnvironment" inside static class in ASP Core?

My class :

public class MainHelper
{
    private readonly IWebHostEnvironment _hostingEnvironment;

    public MainHelper(IWebHostEnvironment hostingEnvironment)
    {
        _hostingEnvironment = hostingEnvironment;
    }    

    public static void SaveFile(IFormFile file)
    {
            var path = Path.Combine(_hostingEnvironment.WebRootPath, "uploads");
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);

            using (var fileStream = System.IO.File.Create(Path.Combine(path, file.FileName)))
            {
                file.CopyTo(fileStream);
            }
    }
}

I have error in line:

var path = Path.Combine(_hostingEnvironment.WebRootPath, "uploads");

Error: c# session an object reference is required for the non-static field method or property 'MainHelper._hostingEnvironment'

Please Advise

4

There are 4 best solutions below

2
On BEST ANSWER

Maybe something like that can help you:

public static class MainHelper
{
    private static IWebHostEnvironment _hostingEnvironment;

    public static bool IsInitialized { get; private set; }

    public static void Initialize(IWebHostEnvironment hostEnvironment)
    {
        if(IsInitialized)
            throw new InvalidOperationException("Object already initialized");
        
        _hostingEnvironment = hostEnvironment;
        IsInitialized = true;
    }

    public static void SaveFile(IFormFile file)
    {
        if(!IsInitialized)
            throw new InvalidOperationException("Object is not initialized");

        var path = Path.Combine(_hostingEnvironment.WebRootPath, "uploads");
        if (!Directory.Exists(path))
            Directory.CreateDirectory(path);

        using (var fileStream = System.IO.File.Create(Path.Combine(path, file.FileName)))
        {
            file.CopyTo(fileStream);
        }
    }
}

It this sample you should call MainHelper.Initialize with your IWebHostEnvironment instance at your Startup.cs, etc. instead calling constructor. In this sample you can initialize MainHelper just once. (Not tested)

0
On
   var environment = app.ApplicationServices
                .CreateScope()
                .ServiceProvider
                .GetRequiredService<IWebHostEnvironment>();
0
On

There is already an accepted answer but one similar solution to @sambath999 answers is as follows:

public static class MainHelper
{
    public static HttpContext _httpContext => new HttpContextAccessor().HttpContext;
    public static IWebHostEnvironment _webHostEnvironment => (IWebHostEnvironment)_httpContext.RequestServices.GetService(typeof(IWebHostEnvironment));
}

Register HttpcontextAccessor in Program.cs

builder.Services.AddHttpContextAccessor();

Now you can use _webHostEnvironment in your static class:

var path = MainHelper._webHostEnvironment.WebRootPath;

I hope this would be helpful.

0
On

As the accepted answer was one. But in case anyone refers using without intialization in static class:

    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.DependencyInjection;

    public class Common{
          public static IWebHostEnvironment WebEnv()
            {
                var _accessor = new HttpContextAccessor();
                return _accessor.HttpContext.RequestServices.GetRequiredService<IWebHostEnvironment>();
            }
        }

Usage:

var path = Common.WebEnv().WebRootPath;