اشتراک‌ها
Uno Platform و انتقال Windows Calculator به Linux

We’ve ported the open-source Windows Calculator to yet another platform: Linux! With all the rumors of a Microsoft browser – Edge – coming to Linux soon, we thought it would be good to show that the open source community can be effective in bringing a piece of Windows to Linux. 

Uno Platform و انتقال Windows Calculator به Linux
اشتراک‌ها
پروژه های Open Source در زمینه e-commerce با ASP.NET Core

 Top 3 Open Source ASP.NET Core based e-commerce web applications


nopCommerce
 SimplCommerce
grandnode ( Powered By nopCommerce) :It’s an open source, free, cross-platform e-commerce software based on ASP.NET Core 2.2 and MongoDB — NoSQL database. You can run it on Linux, Windows, and MacOS easily. GrandNode also supports Docker, so you are able to install it just in seconds with Docker. 

پروژه های Open Source در زمینه e-commerce با ASP.NET Core
اشتراک‌ها
نسخه دوم فریم‌ورک MSTest سورس باز شد

As promised , we announced the open sourcing of MSTest Test Framework “MSTest V2”. The community now has a fully supported, open source, cross-platform implementation of the MSTest V2 portfolio with which to write tests targeting .NET Framework, .NET Core and ASP.NET Core on Windows, Linux, and Mac. 

نسخه دوم فریم‌ورک MSTest سورس باز شد
اشتراک‌ها
Windows Live Writer سورس باز شد

An independent group of volunteers within Microsoft has successfully open sourced and forked Windows Live Writer. The fork is called Open Live Writer (also known as OLW) and it is part of the .NET Foundation and managed by this group of volunteers.  

Windows Live Writer سورس باز شد
اشتراک‌ها
Tools for Apache Cordova - مثال ها و مستندات
Open source code is the norm for so many developers these days, and unsurprisingly, so is open documentation. From Azure to TypeScript, public repositories have become a go-to place for sharing samples, tutorials, and “tips and tricks” so that everyone can learn and contribute together as a community.
Tools for Apache Cordova - مثال ها و مستندات
نظرات مطالب
ارسال پیام های تبلیغاتی به Telegram با استفاده از #C
چند نمونه دموی برنامه هایی که من دیدم از خود برنامه وایبر در دسکتاب استفاده  می‌کنند. به این صورت که، زدن کلیدهای روی برنامه سیموله شده. ولی در مورد تلگرام قضیه فرق میکنه خود شرکت از استفاده از API استقبال میکنه:

Using Telegram API
Our API is 100% open for all developers who wish to create Telegram applications on our platform
 Feel free to study the open source code of existing Telegram applications for examples of how things work here
مطالب
روشی برای مقایسه‌ی مقادیر تمام خواص دو شیء در آزمون‌های واحد
در زمان نوشتن تست‌های مختلف (Unit - Integration - UI) گاهی اوقات پیش می‌آید که بخواهید تمامی خصوصیت‌های یک شیء را تایید کنید. معمولا نوشتن اعتبارسنجی برای همه خصوصیت‌ها و همین طور پیام‌های استثناء برای هر یک در زمان عدم تایید اعتبار، کار بسیار زمانبری است. در این مقاله به شما نشان خواهم داد که چگونه با نوشتن یک اعتبارسنج عمومی از اتلاف زمان زیادی جلوگیری کنید.

با استفاده از کلاس زیر می‌توان کار اعتبارسنجی را با استفاده از Reflection به راحتی انجام داد. در اینجا برای اعتبارسنجی DateTime از کلاس DateTimeAssert استفاده کرده‌ایم.
public class PropertiesValidator<TK, T> where T : new() where TK : new()
{
    static TK _instance;

    public static TK Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new TK();
            }
            return _instance;
        }
    }

    public void Validate(T expectedObject, T realObject, params string[] propertiesNotToCompare)
    {
        var properties = realObject.GetType().GetProperties();
        foreach (var currentRealProperty in properties)
        {
            if (!propertiesNotToCompare.Contains(currentRealProperty.Name))
            {
                var currentExpectedProperty = expectedObject.GetType().GetProperty(currentRealProperty.Name);
                var exceptionMessage = $"The property {currentRealProperty.Name} of class {currentRealProperty.DeclaringType?.Name} was not as expected.";

                if (currentRealProperty.PropertyType != typeof(DateTime) && currentRealProperty.PropertyType != typeof(DateTime?))
                {
                    Assert.AreEqual( currentExpectedProperty.GetValue( expectedObject,
                                                                        null ),
                                        currentRealProperty.GetValue( realObject,
                                                                    null ),
                                        exceptionMessage );
                }
                else
                {
                    DateTimeAssert.Validate( currentExpectedProperty.GetValue( expectedObject,
                                                                                null ) as DateTime?,
                                                currentRealProperty.GetValue( realObject,
                                                                            null ) as DateTime?,
                                                TimeSpan.FromMinutes( 5 ) );
                }
            }
        }
    }
}


طرز استفاده

فرض کنید مدلی داریم با این مشخصات:
public class ObjectToAssert
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime LastVisit { get; set; }
}
و دو نمونه از آن را ایجاد کرده ایم:
var expectedObject = new ObjectToAssert
                        {
                            FirstName = "Vahid",
                            LastName = "Mohammad Taheri",
                            LastVisit = new DateTime( 2016, 11, 14, 0, 10, 50 )
                        };
var actualObject = new ObjectToAssert
                        {
                            FirstName = "Vahid",
                            LastName = "Mohammad Taheri",
                            LastVisit = new DateTime( 2016, 11, 14, 0, 13, 50 )
                        };
کلاسی را با ارث بری از PropertiesValidator ایجاد می‌کنیم:
public class ObjectToAssertValidator : PropertiesValidator<ObjectToAssertValidator, ObjectToAssert>
{
    public void Validate(ObjectToAssert expected, ObjectToAssert actual)
    {
        this.Validate(expected, actual, "FirstName");
    }
}

نکته
: در صورتی که می‌خواهید خصوصیتی را استثناء کنید از اعتبارسنجی، می‌توانید آن‌را به عنوان پارامتر سوم به بعد به تابع Validate ارسال کنید. طبق کد بالا FirstName به صورت استثناء تعریف شده است.


اکنون دو نمونه ساخته شده از ObjectToAssert بالا را با فراخوانی دستور زیر اعتبارسنجی می‌کنیم:
ObjectToAssertValidator.Instance.Validate(expectedObject, actualObject);
نظرات مطالب
استفاده از GitHub Actions برای Build و توزیع خودکار پروژه‌های NET Core.
یک نکته تکمیلی دیگر:
توسط کد زیر میتوانید اطلاعاتی از محیط اجرا شدن Github Action مورد نظر جمع آوری و لاگ کنید
 از جمله :
  •  event اجرا شده (مثلا push) و شخص فراخوان این رخداد
  • جزئیات commit ایی که منجر به این event شده از جمله SHA hash کامیت، author و committer کامیت
  • تعداد Issue ها، Fork‌ها و Star‌های ریپازیتوری در آن لحظه
  • و بسیاری اطلاعات دیگر
    steps:
    - name: Dump GitHub Context
      env:
        GITHUB_CONTEXT: ${{ toJson(github) }}
      run: echo "$GITHUB_CONTEXT"
نمونه خروجی تولید شده
GITHUB_CONTEXT: {
  "token": "***",
  "ref": "refs/heads/master",
  "sha": "3251394ad66ae8419e606fbf78570906ff2f01d3",
  "repository": "mjebrahimi/github_actions_test",
  "repositoryUrl": "git://github.com/mjebrahimi/github_actions_test.git",
  "run_id": "66966756",
  "run_number": "17",
  "actor": "mjebrahimi",
  "workflow": ".NET Core",
  "head_ref": "",
  "base_ref": "",
  "event_name": "push",
  "event": {
    "after": "3251394ad66ae8419e606fbf78570906ff2f01d3",
    "base_ref": null,
    "before": "b6c382e8fe74916daf6821a5a71efe480bd98a13",
    "commits": [
      {
        "author": {
          "email": "mj.ebrahimi72@gmail.com",
          "name": "Mohammad Javad Ebrahimi",
          "username": "mjebrahimi"
        },
        "committer": {
          "email": "noreply@github.com",
          "name": "GitHub",
          "username": "web-flow"
        },
        "distinct": true,
        "id": "3251394ad66ae8419e606fbf78570906ff2f01d3",
        "message": "Update dotnetcore.yml",
        "timestamp": "2020-03-31T04:48:53+04:30",
        "tree_id": "e27a05129010b3b2a7b18b92d91cd73a32babb8f",
        "url": "https://github.com/mjebrahimi/github_actions_test/commit/3251394ad66ae8419e606fbf78570906ff2f01d3"
      }
    ],
    "compare": "https://github.com/mjebrahimi/github_actions_test/compare/b6c382e8fe74...3251394ad66a",
    "created": false,
    "deleted": false,
    "forced": false,
    "head_commit": {
      "author": {
        "email": "mj.ebrahimi72@gmail.com",
        "name": "Mohammad Javad Ebrahimi",
        "username": "mjebrahimi"
      },
      "committer": {
        "email": "noreply@github.com",
        "name": "GitHub",
        "username": "web-flow"
      },
      "distinct": true,
      "id": "3251394ad66ae8419e606fbf78570906ff2f01d3",
      "message": "Update dotnetcore.yml",
      "timestamp": "2020-03-31T04:48:53+04:30",
      "tree_id": "e27a05129010b3b2a7b18b92d91cd73a32babb8f",
      "url": "https://github.com/mjebrahimi/github_actions_test/commit/3251394ad66ae8419e606fbf78570906ff2f01d3"
    },
    "pusher": {
      "email": "mj.ebrahimi72@gmail.com",
      "name": "mjebrahimi"
    },
    "ref": "refs/heads/master",
    "repository": {
      "archive_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/{archive_format}{/ref}",
      "archived": false,
      "assignees_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/assignees{/user}",
      "blobs_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/git/blobs{/sha}",
      "branches_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/branches{/branch}",
      "clone_url": "https://github.com/mjebrahimi/github_actions_test.git",
      "collaborators_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/collaborators{/collaborator}",
      "comments_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/comments{/number}",
      "commits_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/commits{/sha}",
      "compare_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/compare/{base}...{head}",
      "contents_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/contents/{+path}",
      "contributors_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/contributors",
      "created_at": 1585584602,
      "default_branch": "master",
      "deployments_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/deployments",
      "description": null,
      "disabled": false,
      "downloads_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/downloads",
      "events_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/events",
      "fork": false,
      "forks": 0,
      "forks_count": 0,
      "forks_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/forks",
      "full_name": "mjebrahimi/github_actions_test",
      "git_commits_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/git/commits{/sha}",
      "git_refs_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/git/refs{/sha}",
      "git_tags_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/git/tags{/sha}",
      "git_url": "git://github.com/mjebrahimi/github_actions_test.git",
      "has_downloads": true,
      "has_issues": true,
      "has_pages": false,
      "has_projects": true,
      "has_wiki": true,
      "homepage": null,
      "hooks_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/hooks",
      "html_url": "https://github.com/mjebrahimi/github_actions_test",
      "id": 251358686,
      "issue_comment_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/issues/comments{/number}",
      "issue_events_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/issues/events{/number}",
      "issues_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/issues{/number}",
      "keys_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/keys{/key_id}",
      "labels_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/labels{/name}",
      "language": "C#",
      "languages_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/languages",
      "license": null,
      "master_branch": "master",
      "merges_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/merges",
      "milestones_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/milestones{/number}",
      "mirror_url": null,
      "name": "github_actions_test",
      "node_id": "MDEwOlJlcG9zaXRvcnkyNTEzNTg2ODY=",
      "notifications_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/notifications{?since,all,participating}",
      "open_issues": 0,
      "open_issues_count": 0,
      "owner": {
        "avatar_url": "https://avatars1.githubusercontent.com/u/23256135?v=4",
        "email": "mj.ebrahimi72@gmail.com",
        "events_url": "https://api.github.com/users/mjebrahimi/events{/privacy}",
        "followers_url": "https://api.github.com/users/mjebrahimi/followers",
        "following_url": "https://api.github.com/users/mjebrahimi/following{/other_user}",
        "gists_url": "https://api.github.com/users/mjebrahimi/gists{/gist_id}",
        "gravatar_id": "",
        "html_url": "https://github.com/mjebrahimi",
        "id": 23256135,
        "login": "mjebrahimi",
        "name": "mjebrahimi",
        "node_id": "MDQ6VXNlcjIzMjU2MTM1",
        "organizations_url": "https://api.github.com/users/mjebrahimi/orgs",
        "received_events_url": "https://api.github.com/users/mjebrahimi/received_events",
        "repos_url": "https://api.github.com/users/mjebrahimi/repos",
        "site_admin": false,
        "starred_url": "https://api.github.com/users/mjebrahimi/starred{/owner}{/repo}",
        "subscriptions_url": "https://api.github.com/users/mjebrahimi/subscriptions",
        "type": "User",
        "url": "https://api.github.com/users/mjebrahimi"
      },
      "private": false,
      "pulls_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/pulls{/number}",
      "pushed_at": 1585613933,
      "releases_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/releases{/id}",
      "size": 40,
      "ssh_url": "git@github.com:mjebrahimi/github_actions_test.git",
      "stargazers": 0,
      "stargazers_count": 0,
      "stargazers_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/stargazers",
      "statuses_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/statuses/{sha}",
      "subscribers_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/subscribers",
      "subscription_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/subscription",
      "svn_url": "https://github.com/mjebrahimi/github_actions_test",
      "tags_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/tags",
      "teams_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/teams",
      "trees_url": "https://api.github.com/repos/mjebrahimi/github_actions_test/git/trees{/sha}",
      "updated_at": "2020-03-31T00:01:15Z",
      "url": "https://github.com/mjebrahimi/github_actions_test",
      "watchers": 0,
      "watchers_count": 0
    },
    "sender": {
      "avatar_url": "https://avatars1.githubusercontent.com/u/23256135?v=4",
      "events_url": "https://api.github.com/users/mjebrahimi/events{/privacy}",
      "followers_url": "https://api.github.com/users/mjebrahimi/followers",
      "following_url": "https://api.github.com/users/mjebrahimi/following{/other_user}",
      "gists_url": "https://api.github.com/users/mjebrahimi/gists{/gist_id}",
      "gravatar_id": "",
      "html_url": "https://github.com/mjebrahimi",
      "id": 23256135,
      "login": "mjebrahimi",
      "node_id": "MDQ6VXNlcjIzMjU2MTM1",
      "organizations_url": "https://api.github.com/users/mjebrahimi/orgs",
      "received_events_url": "https://api.github.com/users/mjebrahimi/received_events",
      "repos_url": "https://api.github.com/users/mjebrahimi/repos",
      "site_admin": false,
      "starred_url": "https://api.github.com/users/mjebrahimi/starred{/owner}{/repo}",
      "subscriptions_url": "https://api.github.com/users/mjebrahimi/subscriptions",
      "type": "User",
      "url": "https://api.github.com/users/mjebrahimi"
    }
  },
  "workspace": "/home/runner/work/github_actions_test/github_actions_test",
  "action": "run1"
}

با توجه به این نکته، اگر میخواین توی یه کامیت، عملیات CI رو به هر دلیلی Skip/Ignore کنین میتونین اینطوری عمل کنین.
jobs:
  build:
    if: contains(toJson(github.event.commits), '[SKIP CI]') == false
    runs-on: ubuntu-latest
...
در این صورت هر کامیت ایی که توی message اش، عبارت "[SKIP CI]" باشه Workflow روش اجرا نمیشه .  
اشتراک‌ها
سیستم مدیریت هویت غیرمتمرکز: محصول جدید مایکروسافت

در پی همکاری با بنیاد هویت غیرمتمرکز، شرکت مایکروسافت از برنامه خودش برای بهره‌گیری از فناوری بلاک‌چین با هدف حل چالش‌های مدیریت هویت خبر داده است.

به‌طور دقیق‌تر این شرکت بزرگ فناوری با طراحی یک اپلیکیشن در پی استفاده از امکانات فناوری زنجیره‌بلوک برای مدیریت بهتر اوراق هویتی دیجیتال است.

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

سیستم مدیریت هویت غیرمتمرکز: محصول جدید مایکروسافت