استفاده از File Provider ها در ASP.NET Core

چهارشنبه 17 خرداد 1396

در این مقاله به توضیح و معرفی File Provider می پردازیم و نحوه استفاده File Provider ها در ASP.NET Core به صورت یک آموزش عملی توضیح داده می شود.

استفاده از File Provider ها در ASP.NET Core

مقدمه

به کمک استفاده از File Provider ها در ASP.NET Core توانایی دسترسی به فایل سیستم را خواهیم داشت. به عبارت دیگر می توان گفت در واقع File Provider یک مفهوم انتزاعی روی فایل سیستم است. File Provider ها از اینترفیس IfileProvider استفاده می کنند که این اینترفیس دارای متدهایی است که توانایی دریافت اطلاعات فایل، اطلاعات دایرکتوری و تنظیم ارسال اطلاعیه ها را دارند.

از IfileInfo برای دریافت اطلاعات فایل استفاده می شود و IfileInfo  قابلیت ارائه متدها و خصوصیات انفرادی فایل ها و دایرکتوری ها را دارد. اینترفیس IdirectoryContents برای دریافت محتویات یک دایرکتوری در file provider است. اینترفیس IchangeToken تغییرات رخ داده شده را با ارسال اطلاعیه منتشر می کند.

سه نوع پیاده سازی برای IFileProvider وجود دارد

Physical File Provider – برای دسترسی به فایل های واقعی در سیستم استفاده می شود

Embedded File Provider -  برای دسترسی به فایل هایی نهفته در اسمبلی ها استفاده می شود

Composite File Provider – برای دسترسی به فایل ها از طریق یک یا چند Provider

PhysicalFileProvider

PhysicalFileProvider در واقع System.IO.File استفاده می کند و از طریق فایل سیستم فیزیکی به فایل ها دسترسی پیدا می کند. این File Provider دارای قابلیت دسترسی به یک دایرکتوری و زیر دایرکتوری هایش است ولی در بعضی از دایرکتوری ها دارای سطح دسترسی محدود تری است. ما می توانیم یک نمونه PhysicalFileProvider را به کمک متد ConfigureServices که در کلاس startup  وجود دارد، ایجاد کنیم و آن را به صورت تزریق وابستگی از طریق سازنده کنترلر استفاده کنیم.

 در کد های زیر، یک شی PhysicalFileProvider می سازیم و از آن را به صورت تزریق وابستگی استفاده می کنیم.

متد ConfigureServices  در کلاس Startup

    public void ConfigureServices(IServiceCollection services)  
    {  
        services.AddMvc();  
        IFileProvider physicalProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());  
          
        services.AddSingleton<IFileProvider>(physicalProvider);  
    }  

HomeController.cs

    using Microsoft.AspNetCore.Mvc;  
    using Microsoft.Extensions.FileProviders;  
      
    public class HomeController : Controller  
    {  
        private readonly IFileProvider _fileProvider;  
        public HomeController(IFileProvider fileProvider)  
        {  
            _fileProvider = fileProvider;  
        }  
        [Route("home/index")]  
        public IActionResult Index()  
        {  
            var contents = _fileProvider.GetDirectoryContents("");  
            return View(contents);  
        }  
    }  

 Index.cshtml

@using Microsoft.Extensions.FileProviders  
@model  IDirectoryContents  
  
<h2>Folder Contents</h2>  
  
<ul>  
    @foreach (IFileInfo item in Model)  
    {  
        if (item.IsDirectory)  
        {  
            <li><strong>@item.Name</strong> - Directory</li>  
        }  
        else  
        {  
            <li><strong>@item.Name</strong> - @item.PhysicalPath </li>  
        }  
    }  
</ul> 

خروجی

EmbeddedFileProvider

این provider برای دسترسی به فایل های نهفته در اسمبلی ها به کار می رود. ما می توانیم فایل ها را به کمک عنصر EmbeddedResource در اسمبلی جاسازی کنیم. همچنین می توان از الگوی های globbing برای پیدا کردن فایل استفاده کرد.

در اینجا ما نیاز داریم که شی از EmbeddedFileProvider بسازیم و آن را به صورت تزریق وابستگی استفاده کنیم. کدهای کنترلر و View مثل قبل خواهند ماند.

    IFileProvider embeddedProvider = new EmbeddedFileProvider(Assembly.GetEntryAssembly());  
    services.AddSingleton<IFileProvider>(embeddedProvider);  

CompositeFileProvider

در این روش دو یا چند نمونه از IfileProvider با یکدیگر ترکیب می شوند و یک اینترفیس برای کار با فایل ها ایجاد می شود. در مثال زیر ما یک CompositeFileProvider ساخته ایم و دو نمونه از IfileProvider (physical و embedded) را به سازنده آن می فرستیم. همانطور که در خروجی مشخص است، ما می توانیم از هر دو نوع  provider برای فایل ها استفاده کنیم.

    IFileProvider physicalProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());  
    IFileProvider embeddedProvider = new EmbeddedFileProvider(Assembly.GetEntryAssembly());  
    IFileProvider compositeProvider = new CompositeFileProvider(physicalProvider, embeddedProvider);  
      
    services.AddSingleton<IFileProvider>(compositeProvider);  

خروجی

 نظارت بر تغییرات روی فایل ها و دایرکتوری ها

متد Watch از FileProvider به ارائه یک روش برای نظارت بر تغییرات یک یا چند دایرکتوری و فایل ها، می پردازد. این متد یک آدرس را به صورت string دریافت می کند. همچنین ما می توانیم از الگوی های globbing برای پیدا کردن چندین فایل یا مسیر دایرکتوری ها استفاده کنیم. این متد در آخر یک IchangeToken برمی گرداند. IchangeToken مقدار خصوصیت HasChanged را نمایش می دهد که برای بازرسی مورد استفاده قرار می گیرد و متد RegisterChangeCallback  را وقتی که انجام یک تغییر شناسایی شد، فراخوانی می کند. برای نظارت به صورت متداوم نیاز داریم که از TaskCompletionSource استفاده کنیم.


در مثال زیر، ما یک console application ساخته ایم که بر روی فایل watchFil.txt نظارت می کند و وقتی تغییری انجام شود در صفحه console یک پیام نمایش داده می شود.

    using System;  
    using System.IO;  
    using System.Threading.Tasks;  
    using Microsoft.Extensions.FileProviders;  
    using Microsoft.Extensions.Primitives;  
      
    namespace ConsoleApplication  
    {  
        public class Program  
        {  
            private static PhysicalFileProvider _fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());  
            public static void Main(string[] args)  
            {  
                while (true)  
                {  
                    MainAsync().GetAwaiter().GetResult();  
                }  
            }  
            private static async Task MainAsync()  
            {  
                IChangeToken token = _fileProvider.Watch("WatchFile.txt");  
                var source = new TaskCompletionSource<object>();  
                token.RegisterChangeCallback(state =>  
                    ((TaskCompletionSource<object>)state).TrySetResult(null), source);  
                await source.Task.ConfigureAwait(false);  
                Console.WriteLine("File changed - WatchFile.txt");  
            }  
        }  
    }  

خروجی

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید