نظرات مطالب
مروری بر کاربردهای Action و Func - قسمت اول
نمی‌توان. چون در اصل Action و Func به این صورت تعریف شده‌اند:
public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
البته می‌توان بجای Action و Func، یک delegate سفارشی را از صفر نوشت؛ ولی هدف در اینجا سهولت استفاده‌است.
+ از زمان C# 7.0 اگر نیاز به نامگذاری این پارامترها را داشتید، می‌توانید از tuples به صورت زیر استفاده کنید:
Func<(string firstName, string lastName), string> f = (data) => data.firstName + data.lastName;
f(("Foo", "Bar"));
نظرات مطالب
خودکارسازی فرآیند نگاشت اشیاء در AutoMapper
ممنونم. مشکل قبل حل شد. 
 اگر ویومدل من بدینصورت باشه
public class MyViewModel : IHaveCustomMappings
    {
       
        public int SchedulerId { get; set; }
        public bool IsApplied { get; set; }
        public int Qty { get; set; }
        
        public void CreateMappings(IMapperConfigurationExpression configuration)
        {
            configuration.CreateMap<DomainModels.Models.Scheduler, MyViewModel>()
                .ForMember(dest => dest.SchedulerId, opt => opt.MapFrom(src => src.Id));
                    }
    }
خطایی صادر میکندبا این عنوان: 
Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters
اگر دو فیلد IsApplied  ,    Qty   هم در متد  CreateMappings بصورت دستی map کنم خطایی صادر نمیشود. در صورتیکه قبلا با اتوماتیک مپ میشدند. آیا تغییری در AutoMapperRegistry  نیاز هست؟
مطالب
ثبت جزئیات استثناهای Entity framework توسط ELMAH
در حین بروز استثناهای Entity framework، می‌توان توسط ابزارهای Logging متنوعی مانند ELMAH، جزئیات متداول آن‌ها را برای بررسی‌های آتی ذخیره کرد. اما این جزئیات فاقد SQL نهایی تولیدی و همچنین پارامترهای ورودی توسط کاربر یا تنظیم شده توسط برنامه هستند. برای اینکه بتوان این جزئیات را نیز ثبت کرد، می‌توان یک IDbCommandInterceptor جدید را طراحی کرد.


کلاس EfExceptionsInterceptor

در اینجا نمونه‌ای از یک پیاده سازی اینترفیس IDbCommandInterceptor را مشاهده می‌کنید. همچنین طراحی یک متد عمومی که می‌تواند به جزئیات SQL نهایی و پارامترهای آن دسترسی داشته باشد، در اینترفیس IEfExceptionsLogger ذکر شده‌است.
public interface IEfExceptionsLogger
{
    void LogException<TResult>(DbCommand command,
        DbCommandInterceptionContext<TResult> interceptionContext);
}

using System.Data.Common;
using System.Data.Entity.Infrastructure.Interception;
 
namespace ElmahEFLogger
{
    public class EfExceptionsInterceptor : IDbCommandInterceptor
    {
        private readonly IEfExceptionsLogger _efExceptionsLogger;
 
        public EfExceptionsInterceptor(IEfExceptionsLogger efExceptionsLogger)
        {
            _efExceptionsLogger = efExceptionsLogger;
        }
 
        public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
        {
            _efExceptionsLogger.LogException(command, interceptionContext);
        }
 
        public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
        {
            _efExceptionsLogger.LogException(command, interceptionContext);
        }
 
        public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
        {
            _efExceptionsLogger.LogException(command, interceptionContext);
        }
 
        public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
        {
            _efExceptionsLogger.LogException(command, interceptionContext);
        }
 
        public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
        {
            _efExceptionsLogger.LogException(command, interceptionContext);
        }
 
        public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
        {
            _efExceptionsLogger.LogException(command, interceptionContext);
        }
    }
}


تهیه یک پیاده سازی سفارشی از IEfExceptionsLogger توسط ELMAH

اکنون که ساختار کلی IDbCommandInterceptor سفارشی برنامه مشخص شد، می‌توان پیاده سازی خاصی از آن‌را جهت استفاده از ELMAH به نحو ذیل ارائه داد:
using System;
using System.Data.Common;
using System.Data.Entity.Infrastructure.Interception;
using Elmah;
 
namespace ElmahEFLogger.CustomElmahLogger
{
    public class ElmahEfExceptionsLogger : IEfExceptionsLogger
    {
        /// <summary>
        /// Manually log errors using ELMAH
        /// </summary>
        public void LogException<TResult>(DbCommand command,
            DbCommandInterceptionContext<TResult> interceptionContext)
        {
            var ex = interceptionContext.OriginalException;
            if (ex == null)
                return;
 
            var sqlData = CommandDumper.LogSqlAndParameters(command, interceptionContext);
            var contextualMessage = string.Format("{0}{1}OriginalException:{1}{2} {1}", sqlData, Environment.NewLine, ex);
 
 
            if (!string.IsNullOrWhiteSpace(contextualMessage))
            {
                ex = new Exception(contextualMessage, new ElmahEfInterceptorException(ex.Message));
            }
 
            try
            {
                ErrorSignal.FromCurrentContext().Raise(ex);
            }
            catch
            {
                ErrorLog.GetDefault(null).Log(new Error(ex));
            }
        }
    }
}
در اینجا شیء Command به همراه SQL نهایی تولید و پارامترهای مرتبط است. همچنین interceptionContext.OriginalException جزئیات عمومی استثنای رخ داده را به همراه دارد. می‌توان این اطلاعات را پس از اندکی نظم بخشیدن، به متد Raise مربوط به ELMAH ارسال کرد تا جزئیات بیشتری از استثنای رخ داده شده، در لاگ‌های آن ظاهر شوند.


استفاده از ElmahEfExceptionsLogger جهت طراحی یک Interceptor عمومی

   public class ElmahEfInterceptor : EfExceptionsInterceptor
    {
        public ElmahEfInterceptor()
            : base(new ElmahEfExceptionsLogger())
        { }
    }
برای استفاده از ElmahEfExceptionsLogger و تهیه یک Interceptor عمومی، می‌توان با ارث بری از کلاس Interceptor ابتدای بحث شروع کرد و وهله‌ای از ElmahEfExceptionsLogger را به سازنده‌ی آن تزریق نمود (یکی از چندین روش ممکن). سپس برای استفاده از آن کافی است به ابتدای متد Application_Start فایل Global.asax.cs مراجعه و در ادامه سطر ذیل را اضافه نمود:
 DbInterception.Add(new ElmahEfInterceptor());

پس از آن جزئیات کلیه استثناهای EF در لاگ‌های نهایی ELMAH به نحو ذیل ظاهر خواهند شد:




کدهای کامل این پروژه را از اینجا می‌توانید دریافت کنید:
ElmahEFLogger
نظرات اشتراک‌ها
پیاده سازی ساده Google Recaptcha در ASP.NET MVC
یک راه دیگر :
public static class AsyncHelper  
{
    private static readonly TaskFactory _taskFactory = new
        TaskFactory(CancellationToken.None,
                    TaskCreationOptions.None,
                    TaskContinuationOptions.None,
                    TaskScheduler.Default);

    public static TResult RunSync<TResult>(Func<Task<TResult>> func)
        => _taskFactory
            .StartNew(func)
            .Unwrap()
            .GetAwaiter()
            .GetResult();

    public static void RunSync(Func<Task> func)
        => _taskFactory
            .StartNew(func)
            .Unwrap()
            .GetAwaiter()
            .GetResult();
}
نحوه استفاده  
AsyncHelper.RunSync(() => client. IsAcceptAsync ( response ,  secretkey ));

نظرات مطالب
پَرباد - آموزش پیاده‌سازی پرداخت آنلاین در دات نت - تنظیمات
گشتم پیدا کردم. اینترفیس IParbadOptionsProvider با اینترفیس IGatewayAccountSource جایگزین شده‌است. لطفا آموزش بالا را هم آپدیت بفرمایید. من همچین چیزی پیاده سازی کردم:
  public class MellatAccountProvider : IGatewayAccountSource<MellatGatewayAccount>
    {
        private readonly ParbadMellatSettings _settingsService;

        public MellatAccountProvider(ParbadMellatSettings settingsService)
        {
            _settingsService = settingsService;
        }
        
        public async Task  AddAccountsAsync(IGatewayAccountCollection<MellatGatewayAccount> accounts)
        {
          //  var settings =  _settingsService.TerminalId();

            accounts.Add(new MellatGatewayAccount
            {
                TerminalId = _settingsService.TerminalId,
                UserName = _settingsService.UserName,
                UserPassword = _settingsService.UserPassword
            });
        }
نظرات مطالب
چه زمان‌هایی یک برنامه‌ی ASP.NET ری استارت می‌شود؟
یک نکته‌ی تکمیلی: چگونه برنامه‌های ASP.NET Core را به صورت دستی ری‌استارت کنیم؟

با توجه به چندسکویی بودن ASP.NET Core، برای نمونه در لینوکس، تغییراتی مانند تغییر در web.config، سبب ری‌استارت برنامه نمی‌شوند. در این حالت برای بارگذاری تغییرات، می‌توان از روش دستی ری‌استارت برنامه استفاده کرد:
[Authorize(Roles = "Admin")] 
public class AdminController : Controller 
{ 
    private readonly IApplicationLifetime _applicationLifetime;
 
    public AdminController(IApplicationLifetime appLifetime) 
    { 
        _applicationLifetime = appLifetime; 
    } 
 
    public IActionResult Shutdown() 
    { 
       _applicationLifetime.StopApplication(); 
       return Content("Done"); 
    } 
}
در اینجا از سرویس توکار IApplicationLifetime و متد StopApplication آن برای recycle/restart برنامه استفاده شده‌است. بدیهی است دسترسی به یک چنین اکشن متدی باید کاملا کنترل شده باشد.
نظرات مطالب
ارتقاء به ASP.NET Core 1.0 - قسمت 6 - سرویس‌ها و تزریق وابستگی‌ها
معادل مطلب «Lazy loading در تزریق وابستگی‌ها به کمک StructureMap» در ASP.NET Core
public void ConfigureServices(IServiceCollection services) 
{     
   // ...
   services.AddScoped<IEmailService, EmailService>()
                .AddScoped(x => new Lazy<IEmailService>(() => x.GetRequiredService<IEmailService>())); 
   // ...
}
ابتدا سرویس مدنظر به صورت معمولی ثبت می‌شود و سپس نمونه‌ی Lazy آن بر اساس این سرویس تعریف خواهد شد.
اکنون امکان تعریف و تزریق این سرویس به صورت Lazy در سازنده‌ی کنترلرها وجود خواهد داشت:
public class EmailController : Controller 
{   
   private readonly Lazy<IEmailService> _emailService; 
   public EmailController(Lazy<IEmailService> emailService)   
   {        
       _emailService = emailService;
   }
مطالب
بررسی Bad code smell ها: دلال یا Middle Man
دلال یا Middle man در دسته الگوهای «کدهایی بیش از اندازه وابسته به هم» قرار می‌گیرد. زمانیکه یک کلاس، تنها کاری را که انجام می‌دهد، هدایت فراخوانی به کلاس دیگری باشد، با این الگو مواجه هستیم. تشخیص این کد بد بو معمولا بسیار آسان است.  
به طور مثال:  
 public class ProductQuery 
    { 
        public dynamic GetProductsByCustomerId(int id) 
        { 
            return new ExpandoObject(); 
        } 
    } 
    public class CustomerQuery 
    { 
        private readonly ProductQuery _productQuery; 
  
        public CustomerQuery(ProductQuery productQuery) 
        { 
            _productQuery = productQuery; 
        } 
        public dynamic GetProducts(int customerId) 
        { 
            return _productQuery.GetProductsByCustomerId(customerId); 
        } 
    } 
    public static class Programm 
    { 
        static void Main(string[] args) 
        { 
            var query = new CustomerQuery(new ProductQuery()); 
            var products = query.GetProducts(1); 
        } 
    }
در کلاس ProductQuery، متدی برای دریافت تمامی محصولات مربوط به یک مشتری وجود دارد. در کلاس CustomerQuery نیز یک متد برای دریافت تمامی محصولات مشتری وجود دارد. در این مثال متد GetProducts در کلاس CustomerQuery را می‌توان «متد حسود» نیز نامید. این نوع استفاده از متد، «الگوی دلال» نیز است. زمانیکه تمامی متدهای یک کلاس به این صورت باشند، آن کلاس به عنوان دلال شناخته می‌شود.

چرا چنین بویی به راه می‌افتد  

معمولا به چند دلیل با این کد بد بو مواجه خواهیم شد: 
  • انتقال مسئولیت‌های یک کلاس به کلاسی دیگر به مرور زمان و تبدیل متدهای آن به هدایت کنندگان فراخوانی.
  • عدم تشخیص درست مسئولیت‌های یک کلاس و اجبار به افزودن هدایت کنندگان فراخوانی در کلاس‌های دیگر. این حالت معمولا زمانی اتفاق می‌افتد که یک کلاس، مسئولیت‌های زیادی داشته باشد و کلاس‌های مختلف، صرفا نیاز به هدایت فراخوانی به این کلاس را داشته باشند. 
  • عدم استفاده مناسب از الگوهای طراحی. 


روش‌های اصلاح این کد بد بو  

روش کلی برای اصلاح چنین بوی بدی، حذف متدها و کلاسهای هدایت کننده فراخوانی و تغییر تمامی استفاده کنندگان از آن‌ها است. در مثال بالا می‌توان متد GetProducts از کلاس CustomerQuery را حذف و تمامی فراخوانی‌های آن را به متد GetProductsByCustomerId از کلاس ProductQuery انتقال داد، یا بلعکس.

چه کدهایی دلال نیستند 

زمانیکه کلاس هدایت کننده فرخوانی به صورت عمدی ساخته شده باشد، معمولا با چنین الگویی روبرو نیستیم. مانند استفاده از الگوهای طراحی زیر: 
  • Chain of responsibility 
  • Decorator 
  • Proxy 
  • Adapter 
هر کدام از الگوهای طراحی ذکر شده در بالا به دلایل خاصی ایجاد می‌شوند و علارغم شباهت زیاد آن‌ها با کد بد بوی دلال، شرایط مربوط به کد بد بود را دارا نمی‌باشند و معمولا نیازی به اعمال تغییری در آن‌ها نیست. با مطالعه و بررسی دقیق الگوهای طراحی می‌توان از تشخیص اشتباه این الگوی بد جلوگیری کرد.