2017-07-21 23 views
0

Asp.net Core 1.1のクラスからjsonファイルを読み込む必要があります。ファイルは私のmvcプロジェクトの "wwwroot"にあります。 コントローラにIHostingEnvironmentの依存性注入を行い、クラスに渡してWebRootPathにアクセスできることは知っていますが、別のクラスのように、コントローラの外部でクラスをインスタンス化できるようにしたいと考えています。 クラス内のwwwrootフォルダにあるファイルを読むにはどうすればよいですか? 宛先フォルダの例:モデルasp.netコア1.1のファイルを読み込みます。

wwwroot/keywords/keywords.json

私のクラスのコンストラクタにIHostingEnvironmentを注入しようとすると、クラスをインスタンス化するときにHostingEnvironmentインスタンスを渡す必要があります。

public class AppTweet 
{ 
    private readonly IHostingEnvironment _hostingEnvironment; 
    public AppTweet(ITweet tweet, ICollection<string> keyWords, IHostingEnvironment hostingEnvironment) 
    { 
    _hostingEnvironment = hostingEnvironment; 
    } 
} 

私はhostingEnvironmentをダウン渡すコントローラに私のクラスを呼び出すことが、私は、コントローラの外に、このクラスをインスタンス化する必要があるので、私は、この動作を分離します。私はこの方法を行う場合例えば:

public class Article() 
{ 
    public Article() 
    { 
    var appTweet = new AppTweet(new Tweet(), new List<string>, new HostingEnvironment()); 
    } 
} 

、HostingEnvironment.WebRootPathは

EDIT

たぶん私は依存性の注入を必要としないnullです。私はwwwrootフォルダ内のファイルを読みたいが、私は、ファイルvarがでプロジェクトフォルダを読み取らない

`var file = System.IO.File.ReadAllText(@"..\wwwroot\keywords\keywords.json")`; 

をしようとすると、開発中に、サーバ の両方で、このパスにアクセスする方法がわかりません私の開発マシン。私がフォームを読みたいパスはE:\ SOLUTION_FOLDER \ PROJECT_FOLDER \ wwwroot \ keywordsですが、E:\ SOLUTION_FOLDER \ wwwroot \ keywordsから読み込み、プロジェクトフォルダは含まれていません。

EDIT 2

私はDIが、この場合は適切ではないと思います。 これは私の個人的なプロジェクトです。私がしようとしているのは、このクラスのいくつかのプロパティを設定することです。例えば:私のクラスの概要:

public class AppTweet 
{ 
    public AppTweet (ITweet tweet, ICollection<string> keyWords) 
    { 
    //Read a json file from wwwroot and populate NotDesiredKeyWords property 
    } 
    [NotMapped] 
    public IEnumerable<string> NotDesiredKeyWords { get; set; } 
} 

このクラスAppTweetは、常にこれらの値を読み取ることがありますので、設定ファイルのようなものです。このJSONファイルへのアクセス権を持っている必要があります。私はクラスの値をハードコードすることができます(もっと速くなります)が、私はjsonファイルでそれを行うことを好むので、私はいくつかの値を追加すると、プロジェクトをコンパイルする必要はありません。 私がhereを読むことができたので、Dependency Injectionがあなたのクラスをインスタンス化します。デフォルト値を持たないコンストラクタではparamsを持つことはできません。 私はこのクラスを自分でインスタンス化する必要はありませんが、それはもっと合理的な方法です。そして、おそらくこのクラスをコントローラの外の別のクラスの中でインスタンス化してください。だから、私が望む唯一のことは、このjsonファイルを置くことができるWebルートフォルダwwwroot(または他のフォルダ)にアクセスすることだけで、マシンとサーバの両方で動作する必要があります。このファイルを読み取るためにはに私はpathを渡すことができますか?

+0

AppTweetが知る必要があるのは、パス自体または完全なファイル名を渡すだけではどうですか? –

+0

またはAppTweetに 'Dependency Injection'を使用し、新しいものをインスタンス化する代わりに' HostingEnvironment'を渡してください。 –

+0

@PeterB、開発と運用の両方で動作するパスをどのように渡すことができますか? var file = System.IO.File.ReadAllText(@ ".. \ wwwroot \ keywords \ keywords.json");を実行すると、パス内のプロジェクトフォルダがスキップされ、ソリューションフォルダが読み込まれます。私は生産でこれをテストしなかった。それは働くことができますか? – Porkopek

答えて

1

ASP.NETコアは、このような場合にはFile Providerを提供します。シナリオでは、PhysicalFileProviderクラスのインスタンスが必要です(システムの実際のファイルまたは物理ファイルにアクセスするために使用されます)。それ

IFileProvider provider = new PhysicalFileProvider("root path"); 

またはwwwroot内のファイルにアクセスするにはあなたの必要性などとして直接作成することができ、IHostingEnvironment.WebRootFileProvider拡張プロパティを使用することができる。

// 
// Summary: 
//  /// Gets or sets an Microsoft.Extensions.FileProviders.IFileProvider pointing 
//  at Microsoft.AspNetCore.Hosting.IHostingEnvironment.WebRootPath. /// 
IFileProvider WebRootFileProvider { get; set; } 

あなたのファイルを読むための方法を可能な方法:

// using System.IO; 
// using Microsoft.AspNetCore.Hosting; 

// IHostingEnvironment env 
... 

var fileProvider = env.WebRootFileProvider; 

// here you define only subpath 
var fileInfo = fileProvider.GetFileInfo("keywords\keywords.json"); 

var fileStream = fileInfo.CreateReadStream(); 

using (var reader = new StreamReader(fileStream)) 
{ 
    string data = reader.ReadToEnd(); 
} 

また、Microsoft.Extensions.FileProviders.Physicalパッケージを依存関係として追加する必要があります。


手動でインスタンスを作成したい場合は、あなたが道をカスケードに依存関係を渡す必要があります...(とYourServiceのインスタンスは、コンストラクタを介して同じ方法で作成されたか、依存関係として別のクラスに渡す必要がありますDIを使用して...)

public class YourService 
{ 
    private IHostingEnvironment _env; 

    public YourService(IHostingEnvironment env) 
    { 
     _env = env; 
    } 
    public Article CreateArticle() 
    { 
     return new Article(_env); 
    } 
} 

public class AppTweet 
{ 
    public AppTweet(ITweet tweet, ICollection<string> keyWords, IHostingEnvironment hostingEnvironment) 
    { 
    // read file here for example 
    } 
} 

public class Article() 
{ 
    public Article(IHostingEnvironment hostingEnvironment) 
    { 
    var appTweet = new AppTweet(new Tweet(), new List<string>, hostingEnvironment); 
    } 
} 
+0

しかし、クラスに別のパラメータを受け取るコンストラクタがある場合、このIHostingEnvironment envをクラスにどのように受け取るのですか? DIで私の理解が不足して申し訳ありません。 – Porkopek

+0

ASP.NETコアの実際の[デフォルトDI実装](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection)は、コンストラクタ経由で依存関係を注入することのみをサポートしています – Set

+0

したがって、正しく理解していれば私は、私に呼び出されていないコンストラクタでクラス内の依存関係を注入することができますか?自分自身をインスタンス化する必要のあるクラス(つまり「新しい」単語)でFileProviderを受け取る場合はどうすればよいですか?私はできませんか?私のクラスは、いくつかのプロパティにデータを読み込むためにシステムからファイルを読み込む必要があるモデルで、プロパティをハードコーディングする代わりに(リストです)、それらをファイルに入れることにしました。どうすれば達成できますか? – Porkopek

関連する問題