简体   繁体   中英

How to use IHostingEnvironment in a class file

In .NET framework I would have just used Server.MapPath(). In .NET Core 2.2, I understand I should be using IHostingEnvironment . But every example I can find seems to assume I'm using it in a controller. And these examples say to inject IHostingEnvironment in the controller. But...

In my case, I am using some *.json files as data repositories. I am creating an independent Data Access class that can be called from multiple upstream locations. I'm not grasping how to inject IHostingEnvironment into this class without impacting the upstream callers. The idea is, if we someday swap out the.json files for a SQL table, then we want to only make changes to the Data Access class, and not to any of the sources which call it.

So, how, in the Data Access class, can I map a path to a local.json file?

namespace DataAccess
{
    public class Repository
    {
        private readonly string _connStringName;

        public Repository(string connStringName)
        {
            _connStringName = connStringName;
        }

        public IEnumerable<T> GetList<T>()
        {
            IEnumerable<T> entities;
            using (StreamReader r = new StreamReader(_connStringName)) // <---- ??
            {
                string json = r.ReadToEnd();
                entities = JsonConvert.DeserializeObject<List<T>>(json);
            }
            return entities;
        }
    }
}

This line:

using (StreamReader r = new StreamReader(_connStringName))

wants to map a path to IIS Express, which I understand. But I need it to map a path to the relative location of the file.

Thanks!

EDIT:

Maybe I am doing this wrong? This is how I was trying to follow the examples I saw:

public class Repository
{

    private readonly string _connStringName;
    private IHostingEnvironment _hostingEnvironment;

    public Repository(string connStringName, IHostingEnvironment environment)
    {
        _connStringName = connStringName;
        _hostingEnvironment = environment;
    }

    // rest of the class
}

If I do it this way, every upstream location that creates an instance of Repository now has to pass `IHostingEnvironment' into it.

EDIT 2:

How Repository is being used.

public static class Customers
{
    private static readonly string _connStringName = "customer.json";

    public static string Get()
    {
        DataAccess.Repository repository = new DataAccess.Repository(_connStringName);
        List<Customer> customers = repository.GetList<Customer>().ToList();
        return JsonConvert.SerializeObject(customers);
    }
}

In .NET Core you can register your dependencies to be injected at startup.

If you do it this way, you will need to:

  1. inject Repository into Customers .

  2. pass Repository dependencies in Startup

// Startup.cs
public class Startup
{
    // ...
    public void ConfigureServices(IServiceCollection services, IHostingEnvironment env)
    {
        // [2]
        var connectionString = "customer.json"; // or get from a config file
        services.AddSingleton<Repository>(new Repository(connectionString, env));
    }
    // ...
}

public class Customers
{
    private Repository _repository;
    public Customers(Repository repository)
    {
        // [1]
        _repository = repository;
    }
    public string Get()
    {
        // you can use _repository here without passing stuff in
    }
}

public class Repository
{
    private IHostingEnvironment _env;
    public Repository(string connectionString, IHostingEnvironment env)
    {
        _env = env;
    }
}

.NET Core Dependency Injection - https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM