اشتراک‌ها
سری آموزشی Git و GitHub

Git and GitHub for Poets
11 videos

Learning Objectives:
* Understand the concept of version control.
* Understand the difference between git software and GitHub the website.
* Understand terminology: branch, fork, merge, pull, push, remote
* Make your first pull request to a git repository on GitHub. 

سری آموزشی Git و GitHub
اشتراک‌ها
جاوا اسکریپت برای توسعه دهندگان #C
The conference is a two-day, multi-track event that covers all aspects of software development, design and project management. We have speakers from all over the world who are industry experts that deliver both break-out sessions as well as hands-on workshops to further our attendee’s knowledge and understanding of the topics 
جاوا اسکریپت برای توسعه دهندگان #C
نظرات مطالب
استفاده از Luke برای بهبود کیفیت جستجوی لوسین
برای full text search در زبان فارسی این 150 کلمه که آقا عرب‌عامری زحمت کشیدن اصلا کفایت نمیکند. زبان فارسی و دیکته‌اش به این نحو اصلا مناسب ایندکس کردن نیست و بیشتر نیاز به توسعه دارد.
شاید اگر بشه با ابزارهای توسعه‌ای که روی زبان فارسی کار شده - مثل ویراسباز ^ - خروجی بگیریم برای ایندکس کردن و در نتیجه تحلیل اونا به وسیله همین کتابخونه Luke یا  Solr یا Nutch - که در وبلاگ آقای زبردست معرفی شده ^  - آسونتره.
مطالب
معرفی Decorator Design Pattern

فرض کنید که می‌خواهیم یک برنامه برای یک فروشگاه نوشیدنی (مانند coffee shop) بنویسیم ، این فروشگاه در ابتدای کار ممکن است ، منوی ساده‌ای جهت ارائه به مشتری داشته باشد. برای مثال ممکن است که فقط 3 یا 4 محصول داشته باشد. بنابراین ممکن است ما برنامه‌ای را که می‌خواهیم برای این مشتری بنویسیم به صورت زیر طراحی کنیم:

 


که بسیار طبیعی و درست می‌باشد. اما حالا در نظر بگیرید که این فروشگاه در آینده ممکن است محصولات خود را افزایش بدهد و یا حالاتی که ممکن است این محصولات با هم ادغام شوند را در نظر بگیرید. برای مثال ممکن است شما بخواهید که قهوه‌تان را با شیر نوش جان کنید و یا ....

بنابراین تعداد این حالات را در نظر بگیرید که در آینده ممکن است چقدر زیاد بشود:

 

خوب پس چه‌کاری ما می‌توانیم برای نگهداری این برنامه انجام بدهیم؟ یکی از راه‌هایی که ممکن است به فکر ما برسد این است که روش بالا روش احمقانه ای است‌. چرا ما باید به همه‌ی این کلاس‌ها نیاز داشته باشیم. ما می‌توانیم که چاشنی‌ها را در کلاس اصلی نگه‌داری کنیم و کلاس محصولاتمان را از کلاس اصلی به ارث ببریم اجازه دهید تا این کار را با هم انجام بدهیم

خوب با این روش ما n   کلاس تشکیل شده در رویکرد اول را فقط به 5 کلاس تبدیل کردیم. خوب این روشی بسیار ایده‌ال به نظر می‌رسد. اما ممکن است در آینده که تعداد چاشنی‌های ما بالا می‌رود و همچنین تعداد محصولاتمان نیز ممکن است بیشتر شود مجبور شویم که تعداد این کلاس‌ها را بیشتر کنیم،  و یا فکر کنید که ما می‌خواهیم هریک از چاشنی‌هایمان، یک قیمت را نسبت بدهیم. بنابراین مجبوریم که تمامی این‌ها را در کلاس پایه اضافه کنیم؛ بله درست است، ما با کلاس پایه‌ی حجیمی روبرو می‌شویم که بیشتر خواص و یا متدهای آن برای زیر کلاس‌های دیگر مناسبت نیستند. خوب آیا روش بهتری برای جلوگیری از این مشکل داریم؟ بلی.

خوب ما به این مسئله به این صورت نگاه می‌کنیم که شروع می‌کنیم با نوشیدنی‌ها و آن‌ها را با چاشنی‌ها در زمان اجرا تزیین (Decorate) می‌کنیم؛ نه کامپایل.

برای مثال اگر مشتری ما یک نوشیدنی DarkRoast با Mocha و Whip خواست، سپس ما :
1- یک شی از DarkRoast  ایجاد می‌کنیم .
2- آن را با یک شی از  Mocha  تزئین می‌کنیم.
3- آن را با یک شی از Whip - تزیین می‌کنیم.
4- متد Cost()  را صدا می‌زنیم و  یک Delegation  را برای اضافه کردن قیمت چاشنی‌ها در نظر می‌گیریم.

بسیار خوب؛ اما ما عملیات تزئین یک شی را چگونه انجام می‌دهیم و delegation ما چگونه عمل می‌کند .
یک اشاره : به شیء تزئین کننده، مانند یک Wrappers فکر کنید. اجاز بدهید ببینم که چه طور این کار را انجام می‌دهیم.
1- یک شی از DarkRoast  ایجاد می‌کنیم.
 
 

2- آن را با یک شی از  Mocha  تزئین می‌کنیم.

3- آن را با یک شی از Whip تزیین می‌کنیم 


 4- حالا زمان محاسبه قیمت محصول برای مشتری فرا رسیده است. ما این کار را را با صدا زدن بیرونی‌ترین Decorator(Whip)  انجام می‌دهیم و شی  whip به کمک  Delegate مابقی توابع cost را صدا می‌زند.



  در آخر شما می‌توانید پیاده سازی این برنامه را به زبان جاوا در زیر مشاهد نمایید.

public abstract class Beverage
{
     string description ="unknow beverage";
     public String getDescription(){
         return description;
     }
     public abstract double cost();
}

public abstract class CondimentDecorator extends Beverage {
    public abstract string getDescription();
}

public class Espersso extends Beverage{
   public Espersso()
   {
      description="Espersso";
   }
   public double cost(){
     return 1.99;
   }
}

public class HouseBelend extends Beverage {
   public HouseBelend()
   {
     description="HouseBelend";
   }
   public double cost()
   {
     return .89;
   }
}

public class mocha extends condimateDecorator {
  Beverage beverage;
  public mocha(Beverage beverage)
  {
     this.beverage=beverage;
  }
   public string getDescription(){
      return beverage.getdescription() + "Mocha";
   }
   public double cost(){
     return .20 +beverage.cost
   }
}


// Now Use These classes in Final form
Beverage beverage=new Espersso();
//Customers want a coffe with double milk and whip
beverage=new mocha(beverage);
beverage=new mocha(meverage);
beverage=new whip(beverage);

system.out.println(beverage.getDescription() + "$" +beverage.cost());
مطالب
چرا به الگوهای طراحی JavaScript نیاز داریم ؟
امروزه اهمیت یادگیری JavaScript بر هیچ کس پوشیده نیست ، API‌های جدید HTML 5 و امکانات جدید وب مثل Geo Location ، Offline storage ، Canvas ، Offline Web applications و ... همه نیاز به دانش JavaScript دارند. در نتیجه نیاز است علاوه بر یادگیری JavaScript به تمیز کد نوشتن جهت سهولت نگهداری آگاه بود.  همانطور که در کدهای سمت سرور مثل C# و یا PHP نیاز به استفاده از الگوهای طراحی (Design Patterns)است در JavaScript هم اوضاع به همین منوال است.
الگوی طراحی یک راه حل قابل استفاده مجدد است که برای حل مشکلات متداول در طراحی نرم افزار به کار می‌رود.
چرا به الگوی‌های طراحی JavaScript نیازمندیم ؟ 
  1. می خواهیم کد هایی با قابلیت استفاده‌ی مجدد بنویسیم ، استفاده از عملکرد‌های مشابه در سطح صفحات یک Web application یا چند Web Application.
  2. می خواهیم کد هایی با قابلیت نگهداری بنویسیم ، هر چه قدر در فاز توسعه کد‌های با کیفیت بنویسیم در فاز نگهداری از آن بهره می‌بریم. باید کد هایی بنویسیم که قابل Debug و خواندن توسط دیگر افراد تیم باشند.
  3. کدهای ما نباید با توابع و متغیر‌های دیگر پلاگین‌ها تداخل نامگزاری داشته باشند. در برنامه‌های امروزی بسیار مرسوم است که از پلاگین‌های Third party استفاده شود. می‌خواهیم با رعایت Encapsulation and modularization در کدهایمان از این تداخل جلوگیری کنیم.
معمولا کد‌های JavaScript که توسط اکثر ما نوشته می‌شود یک سری تابع پشت سرهم هست ، بدون هیچ کپسوله سازی : 
function getDate() {
    var now = new Date();
    var utc = now.getTime() + (now.getTimezoneOffset() * 60000);
    var est;
    est = new Date(utc + (3600000 * -4));
    return dateFormat(est, "dddd, mmmm dS, yyyy, h:MM:ss TT") + " EST";

}
function initiate_geolocationToTextbox() {
    navigator.geolocation.getCurrentPosition(handle_geolocation_queryToTextBox);
}

function handle_geolocation_queryToTextBox(position) {
    var longitude = position.coords.longitude;
    var latitude = position.coords.latitude;
    $("#IncidentLocation").val(latitude + " " + longitude);
}
به این روش کدنویسی Function Spaghetti Code گفته می‌شود که معایبی دارد : 
  • توابع و متغیر‌ها به Global scope برنامه افزوده می‌شوند.
  • کد Modular نیست.
  • احتمال رخ دادن Conflict در اسامی متغیر‌ها و توابع بالا می‌رود.
  • نگهداری کد به مرور زمان سخت می‌شود.
با شبیه سازی یک مثال مشکلات احتمالی را بررسی می‌کنیم : 
// file1.js
function saveState(obj) {
    // write code here to saveState of some object
    alert('file1 saveState');
}
// file2.js (remote team or some third party scripts)
function saveState(obj, obj2) {
     // further code...
    alert('file2 saveState");
}
همانطور که می‌بینید در این مثال در 2 فایل متفاوت در برنامه مان از 2 تابع با اسامی یکسان و امضای متفاوت استفاده کرده ایم . اگر فایل‌ها را اینگونه در برنامه آدرس دهی کنیم : 
<script src="file1.js" type="text/javascript"></script>
<script src="file2.js" type="text/javascript"></script>
متد saveState در فایلی که دیرتر آدرس داده شده (file2.js) ، متد saveState در file1.js را Override می‌کند ، در نتیجه عملکردی که از متد saveState در فایل اول انتظار داریم اتفاق نمی‌افتد.
 در پست بعدی به راه حل این مشکلات و کپسوله سازی خواهم پرداخت.
برای مطالعه‌ی بیشتر کتاب (Learning JavaScript Design Patterns) را از دست ندهید.
اشتراک‌ها
SourceForge صاحبان جدیدی پیدا کرده‌است
SourceForge, and its stablemate Slashdot, were acquired at the end of January by web publisher BIZX, LLC from DHI, formerly Dice Holdings. which had owned it since 2012. SourceForge was originally launched in 1999 by VA Software cofounded by Larry Augustin and James Vera. This company later became Geeknet and acquired Slashdot as part of Andover.net in 2000.
SourceForge صاحبان جدیدی پیدا کرده‌است
اشتراک‌ها
نمونه مثالی از ASP.NET Core و Entity Framework Core به همراه معماری DDD و CQRS و Event Sourcing

Full ASP.NET Core 2.2 application with DDD, CQRS and Event Sourcing  

Technologies implemented:

  • ASP.NET Core 2.2 (with .NET Core 2.2)
  • ASP.NET MVC Core
  • ASP.NET WebApi Core
  • ASP.NET Identity Core
  • Entity Framework Core 2.2
  • .NET Core Native DI
  • AutoMapper
  • FluentValidator
  • MediatR
  • Swagger UI 

Architecture:

  • Full architecture with responsibility separation concerns, SOLID and Clean Code
  • Domain Driven Design (Layers and Domain Model Pattern)
  • Domain Events
  • Domain Notification
  • CQRS (Imediate Consistency)
  • Event Sourcing
  • Unit of Work
  • Repository and Generic Repository 

نمونه مثالی از ASP.NET Core و Entity Framework Core به همراه معماری DDD و CQRS و Event Sourcing
مطالب
الگوی سردر Facade Pattern
یکی از الگوهای ساختاری Gang Of Four، استفاده از الگوی Facade است که پیچیدگی‌های یک سیستم را مخفی می‌سازد و با ارائه یک پیاده سازی ساده‌تر، استفاده از آن و تست آن را راحت‌تر می‌سازد. این الگو یک کلاس یا یک سیستمی را با متدها و رویدادهایی ساده، در اختیار ما قرار می‌دهد و در یک لحظه، تنها با یک کلاس واحد سر و کله می‌زنیم. احتمالا بسیاری از شما از این الگو استفاده کرده‌اید، ولی شاید با اسم آن آشنا نبوده‌اید.

کار این کلاس در واقع ترکیب کلاس‌ها و کتابخانه‌های کاری مشخص است که نیاز به ارتباط با یکدیگر را دارند. به عنوان مثال یک برنامه کتابخانه، برای وظیفه‌ای چون امانت یک کتاب نیاز است تا چندین کلاس مختلف را با یکدیگر به کار بگیرد که این وظایف شامل موارد زیر می‌باشند:
  1. بررسی وجود کتاب
  2. بررسی تعداد موجود یک کتاب در کتابخانه
  3. بررسی وضعیت امانی کتاب (آیا کتاب در دست کسی از قبل امانت است؟ یا کتاب برای امانت آزاد است؟)
  4. در صورتی که کتابی بیش از زمان مورد نظر در دست کسی امانت است، با یک پیامک از او بخواهیم که کتاب را بازگرداند.
تمامی موارد بالا تنها قسمتی از انجام یک عمل ساده هستند که در یک گروه جای می‌گیرند؛ ولی در واقع از چندین کلاس جدا مثل کلاس کتاب، امانت، سیستم پیامکی و ... استفاده شده است . الگوی Facade به ما کمک می‌کند تا پیچیدگی و تعداد خطوط اجرا را در سطوح بالاتر مخفی سازیم و تنها با صدا زدن یک یا چند متد ساده، کار را به اتمام برسانیم. این کار باعث کاهش کد و خوانایی برنامه در سطوح بالاتر می‌شود.

در کد زیر ما قصد داریم نمونه‌ای از اجرای این الگو را ببینیم. ابتدا سه کلاس اطلاعاتی زیر را ایجاد می‌کنیم:
کلاس کتاب Book:
    class Book
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public int Quantity { get; set; }
        public bool IsLoanable { get; set; }
    }

کلاس کاربر User
 class User
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public  string CellPhoneNumber { get; set; }
    }

کلاس امانت Loan
  class Loan
    {
       public DateTime ExpiredDate { get; set; }
        public User User { get; set; }
    }

بعد از آن سه کلاس را برای مدیریت کتاب، مدیریت امانت و مدیریت پیامکی، ایجاد می‌کنیم:
کلاس کتاب BookManager:
 class BookManager
    {
        public Book GetBook(int id)
        {
                return new Book()
                {
                    Id=id,
                    Title = "a book",
                    Quantity = 3,
                    IsLoanable = true
                };
        }
    }
کلاس بالا یک کتاب را با موجودی سه عدد بازمی‌گرداند که خاصیت IsLoanable آن می‌گوید کتاب را برای بردن به خانه امانت می‌دهند؛ ولی اگر کتاب به فرض یک کتاب مرجع باشد باید False برگرداند تا از امانت آن خودداری شود.

کلاس LoanManager برای مدیریت امانت‌ها
 public int IsLoan(int bookId)
        {
            return 2;
        }

        public List<Loan> GetLoans(int bookId)
        {
            return new List<Loan>()
            {
                new Loan()
                {
                    ExpiredDate = DateTime.Now.AddDays(-15),
                    User = new User()
                {
                    Id = 2,
                    Title = "User1",
                    CellPhoneNumber = "342342424"
                }
                },
                new Loan()
                {
                    ExpiredDate = DateTime.Now.AddDays(5),
                    User = new User()
                        {
                            Id = 56,
                            Title = "User56",
                            CellPhoneNumber = "324324324324"
                        }
                }
            };
        }
این کلاس شامل دو متد است که اولین متد آن کد کتاب را دریافت می‌کند و تعداد افرادی را که در حال حاضر نسخه‌های مختلف آن را به امانت برده‌اند، برمی‌گرداند. در کد بالا عدد دو بازگردانده می‌شود که میگوید از نسخه‌های موجود این کتاب در کتابخانه، دوتای آن‌ها به امانت برده شده‌اند. در متد دوم، کد کتاب داده شده و امانت‌های فعلی آن کتاب که همان دو عدد بالا می‌باشد را برگشت می‌دهد.

در نهایت سومی کلاس مدیریتی برای پیامک هاست:
   class SmsManager
    {
        public void SendMessage(string number)
        {
            Console.WriteLine("please take back the book to the library : "+number);
        }
    }

و در کلاس Facade داریم
    class FacadeBookLoan
    {
        private readonly BookManager _bookManager;
        private readonly LoanManager _loanManager;
        private readonly SmsManager _smsManager;
        public FacadeBookLoan()
        {
            _bookManager = new BookManager();
            _loanManager=new LoanManager();
            _smsManager=new SmsManager();
        }

        public int IsLoanable(int bookId)
        {
            var book = _bookManager.GetBook(2);
            if (book == null)
                return -2;
            if (!book.IsLoanable)
                return -1;
            var howManyBookIsLoaned = _loanManager.IsLoan(bookId);

            if(howManyBookIsLoaned>0) ManageLoaners(bookId);

            return book.Quantity - howManyBookIsLoaned;
        }

        private void ManageLoaners(int bookId)
        {
            var loans = _loanManager.GetLoans(bookId);

            foreach (var loan in loans)
            {
                if (loan.ExpiredDate > DateTime.Now)
                {
                    _smsManager.SendMessage(loan.User.CellPhoneNumber);
                }
            }
        }
    }
در این کلاس متد IsLoanable چک می‌کند که آیا کتاب قابل امانت هست یا خیر. در اینجا مرحله به مرحله، وجود کتاب و قابلیت امانت کتاب بررسی شده و در صورت نتیجه، کد وضعیت -1 یا -2 بازگردانده می‌شوند و در مرحله بعد تعداد نسخه‌های آن کتاب که در حال حاضر در دست امانت هستند، بررسی می‌شوند. اگر کتابی در درست امانت باشد، متد خصوصی صدا زده شده و به کاربرانی که بیش از مدت معینی یک نسخه از کتاب را داشته‌اند، پیامک می‌زند که کتاب را بازگردانید؛ چرا که نسخه‌ها در حال کاهش هستند و در مرحله بعد تعداد نسخه‌های موجود از آن کتاب را در کتابخانه باز می‌گرداند که در این مثال تنها یک نسخه از آن کتاب در کتابخانه موجود است و دو تای آن‌ها در دست امانت هستند که یکی از امانت دارها 15 روز است کتاب را در تاریخ معینی تحویل نداده است.

کد بدنه اصلی برنامه:
var myfacade=new FacadeBookLoan();
var loansCount= myfacade.IsLoanable(2);
Console.WriteLine(loansCount > 0 ? "you can loan the book" : "you can't loan the book");
خروجی برنامه:
please take back the book to the library : 324324324324
you can loan the book
اشتراک‌ها
انتشار R Tools 1.0 برای Visual Studio 2015

This release will be shortly followed by R Tools 1.0 for Visual Studio 2017 in early May. RTVS is a free and open source plug-in that turns Visual Studio into a powerful and productive R development environment. 

انتشار R Tools 1.0 برای Visual Studio 2015
مطالب
الگوی نماینده (پروکسی) Proxy Pattern
همه کاربران کامپیوتر در ایران به خوبی با کلمه پروکسی آشنا هستند. پروکسی به معنی نماینده یا واسط است و پروکسی واسطی است بین ما و شیء اصلی. پروکسی در شبکه به این معنی است که سیستم شما به یک سیستم واسط متصل شده است که از طریق پروکسی محدودیت‌های دسترسی برای آن تعریف شود. در اینجا هم پروکسی در واقع به همین منظور استفاده می‌شود. در تعدادی از کامنت‌های سایت خوانده بودم دوستان در مورد اصول SOLID  و Refactoring بحث می‌کردند که آیا انجام عمل اعتبارسنجی در خود اصل متد کار درستی است یا خیر. در واقع خودم هم نمی‌دانم که این حرکت چقدر به این اصول پایبند است یا خیر، ولی می‌دانم که الگوی پروکسی کل سؤالات بالا را حذف می‌کند و با این الگو دیگر این سؤال اهمیتی ندارد. به عنوان مثال فرض کنید که شما یک برنامه ساده کار با فایل را دارید. ولی اگر بخواهید اعتبارسنجی‌هایی را برای آن تعریف کنید، بهتر است اینکار را به یک پروکسی بسپارید تا شیء گرایی بهتری را داشته باشید.

برای شروع ابتدا یک اینترفیس تعریف می‌کنیم:
   public interface IFilesService
    {
        DirectoryInfo GetDirectoryInfo(string directoryPath);
        void DeleteFile(string fileName);
        void WritePersonInFile(string fileName,string name, string lastName, byte age);
    }
این اینترفیس شامل سه متد نام نویسی، حذف فایل و دریافت اطلاعات یک دایرکتوری است. بعد از آن دو عدد کلاس را از آن مشتق می‌کنیم:
کلاس اصلی:
    class FilesServices:IFilesService
    {
        public DirectoryInfo GetDirectoryInfo(string directoryPath)
        {
            return new DirectoryInfo(directoryPath);
        }

        public void DeleteFile(string fileName)
        {
            File.Delete(fileName);
            Console.WriteLine("the file has been deleted");
        }

        public void WritePersonInFile(string fileName, string name, string lastName, byte age)
        {
            var text = $"my name is {name} {lastName} with {age} years old from dotnettips.info";
            File.WriteAllText(fileName,text);
        }    
    }
که تنها وظیفه اجرای فرامین را دارد و دیگری کلاس پروکسی است که وظیف تامین اعتبارسنجی و آماده سازی پیش شرط‌ها را دارد:
    class FilesServicesProxy:IFilesService
    {
        private readonly IFilesService _filesService;

        public FilesServicesProxy()
        {
            _filesService=new FilesServices();
        }

        public DirectoryInfo GetDirectoryInfo(string directoryPath)
        {
            var existing = Directory.Exists(directoryPath);
            if (!existing)
                Directory.CreateDirectory(directoryPath);
            return _filesService.GetDirectoryInfo(directoryPath);
        }

        public void DeleteFile(string fileName)
        {
            if(!File.Exists(fileName))
                Console.WriteLine("Please enter a valid path");
            else
                _filesService.DeleteFile(fileName);
        }

        public void WritePersonInFile(string fileName, string name, string lastName, byte age)
        {
            if (!Directory.Exists(fileName.Remove(fileName.LastIndexOf("\\"))))
            {
                Console.WriteLine("File Path is not valid");
                return;
            }
            if (name.Trim().Length == 0)
            {
                Console.WriteLine("first name must enter");
                return;
            }

            if (lastName.Trim().Length == 0)
            {
                Console.WriteLine("last name must enter");
                return;
            }

            if (age<18)
            {
                Console.WriteLine("your age is illegal");
                return;
            }


            if (name.Trim().Length < 3)
            {
                Console.WriteLine("first name must be more than 2 letters");
                return;
            }

            if (lastName.Trim().Length <5)
            {
                Console.WriteLine("last name must be more than 4 letters");
                return;
            }

            _filesService.WritePersonInFile(fileName,name,lastName,age);
            Console.WriteLine("the file has been written");
        }
    }
کلاس پروکسی، همان کلاسی است که شما باید صدا بزنید. وظیفه کلاس پروکسی هم این است که در زمان معین و صحیح، کلاس اصلی شما را بعد از اعتبارسنجی‌ها و انجام پیش شرط‌ها صدا بزند. همانطور که می‌بیند، ما در سازنده کلاس اصلی را در حافظه قرار می‌دهیم. سپس در هر متد، اعتبارسنجی‌های لازم را انجام می‌دهیم. مثلا در متد GetDirectoryInfo باید اطلاعات دایرکتوری بازگشت داده شود؛ ولی اصل عمل در واقع در کلاس اصلی است و اینجا فقط شرط گذاشته‌ایم اگر مسیر داده شده معتبر نبود، همان مسیر را ایجاد کن و سپس متد اصلی را صدا بزن. یا اگر فایل موجود است جهت حذف آن اقدام کن و ...
در نهایت در بدنه اصلی با تست چندین حالت مختلف، همه متد‌ها را داریم:
static void Main(string[] args)
        {
            IFilesService filesService=new FilesServicesProxy();
            filesService.WritePersonInFile("c:\\myfakepath\\a.txt","ali","yeganeh",26);

            var directory = filesService.GetDirectoryInfo("d:\\myrightpath\\");
            var fileName = Path.Combine(directory.FullName, "dotnettips.txt");

            filesService.WritePersonInFile(fileName, "al", "yeganeh", 26);
            filesService.WritePersonInFile(fileName, "ali", "yeganeh", 12);
            filesService.WritePersonInFile(fileName, "ali", "yeganeh", 26);

            filesService.DeleteFile("c:\\myfakefile.txt");
            filesService.DeleteFile(fileName);
        }
و نتیجه خروجی:
File Path is not valid
first name must be more than 2 letters
your age is illegal
the file has been written
Please enter a valid path
the file has been deleted