0

I am using .NET Core 3.1. Let's say that I have the following solution structure:

MySolution
    ClassLibrary
        Files
            a.txt
            b.txt
        GetFile.cs
    Project1
    Project2
    ...

And let's say that GetFile.cs has a function ReadFile which reads the file from Files and returns its content.

public class FileReaderService : IFileReaderService
{
    private readonly IHostEnvironment _env;

    public FileReaderService(IHostEnvironment env)
    {
        _env = env;
    }

    public string ReadFile(string fileName)
    {
        var currentPath = _env.ContentRootPath; // not correct
        return "";
    }
}

However, when I try to get the current directory in ReadFile with _env.ContentRootPath, it returns the directory of calling project. I don't want it to be dependent on calling project.

How can I achieve that each project will be able to call ReadFile and that correct file from Files will be returned? I need to be able to add, remove and change these files while the app is running.

I have found some questions on SO but they all seem to be outdated. I need a solution which will work on .NET Core.

Sam Carlson
  • 1,891
  • 1
  • 17
  • 44
  • I guess you want something like "embedded resources"? Something like here: https://stackoverflow.com/q/433171/982149 – Fildor May 05 '20 at 12:53
  • I need to be able to add, remove and change these files while the app is running. Is this possible with embedded resources? – Sam Carlson May 05 '20 at 12:56
  • That would be an important factor to include in the question. In that case embedded resources is not for you, I believe. – Fildor May 05 '20 at 13:00
  • you can mark them as "copy to output directory always/copy if newer" and it will be in the run directory or even better create a directory tree that holds the files and copied with the build – Amorphis May 05 '20 at 13:08

1 Answers1

0

Instead of using the environment to determine the root file path, set it at the configuration level (ex appSettings.json ) and inject that path into the service itself. Either project can set its own path, use the same one, or both retrieve from some external configuration instead of appSettings.

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.1

Kyle J V
  • 563
  • 5
  • 21
  • How would the path look like? Does it have to be relative to `Project[n]`? – Sam Carlson May 05 '20 at 14:55
  • You could use either a relative path or an explicit one. Even a full network path would work. Ex: An external config contains an absolute folder path. Then your project retrieves that path and places it into the config that is injected into your service. Neither project knows about the other, but the config path is still the same. – Kyle J V May 05 '20 at 14:58
  • How would an absolute folder path targeting `ClassLibrary/Files` look like in `appsettings.json` for let's say `Project1`? – Sam Carlson May 05 '20 at 15:05
  • 1
    What is the explicit reason for having the files live in the ClassLibrary path? When the class library compiles, it gets dumped as a dll in each respective executable project's bin folder - your so-called path doesn't really work in the way you think unless all of your code is JIT. Choose a different location outside of the project for your files and use a configuration for all references to it. – Kyle J V May 05 '20 at 15:15
  • So you mean to place `Files` in the same level as `ClassLibrary`, `Project1` and `Project2`? – Sam Carlson May 05 '20 at 15:19
  • No, place the files outside of the scope of any of these projects and set the absolute path in the config. The csproj does not need to have the text files as part of the project. You can create a path on startup based on the config if you really need to do that. – Kyle J V May 05 '20 at 15:29