Masha.Foundation 0.2.0

dotnet add package Masha.Foundation --version 0.2.0
NuGet\Install-Package Masha.Foundation -Version 0.2.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Masha.Foundation" Version="0.2.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Masha.Foundation --version 0.2.0
#r "nuget: Masha.Foundation, 0.2.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Masha.Foundation as a Cake Addin
#addin nuget:?package=Masha.Foundation&version=0.2.0

// Install Masha.Foundation as a Cake Tool
#tool nuget:?package=Masha.Foundation&version=0.2.0

Masha Foundation!

Masha Foundation (MF) is a .NET library that enables you to use functional programing idioms in your C# application.

Benefits

  • Highly readable code
  • Easy to debug and less error-prone
  • Improve developer productivity

Installation

.NET Standard 2.0 compatible.

Install

  • via package manager Install-Package Masha.Foundation
  • via .NET CLI dotnet add package Masha.Foundation
  • package reference <PackageReference Include="Masha.Foundation" Version="0.1.1" />

Quick Start

The functional programming language idioms are drawing attention over object-oriented programming languages. C# incorporated high order functions, currying and partial applications. The left over idiom is function pipelining. It is the game changer to make you think efficiently while writing application.

Masha.Foundation is a C# library enables to use functional programming language idioms including function pipelining.

Pipelining and Monads

Pipelining!

An parameter x1 passed to the function f1 which returns y1. y1 is parameter to function f2, so on. Functions should be non-void to achieve function pipelining. Creating a function pipelining is quite possible in C# without using any special construct. The problem with plain function pipelining is breaking the pipelines by throwing exceptions and returning NULL value parameters as shown below.

Breaking Pipelining!

The cylindrical shape in the above diagrams helps to fix this problem. They are called as monads. These enables to connect functions and pass the parameters safely.

Masha.Foundation (shortly MF) currently provides following monads:

  • Option
  • Result

Map() and Match() Functions

Monads actually wraps a plain .NET object and elevate them so that the upcoming functions in the pipeline can safely peek the value and use it. Interestingly you don't need to check NULL or exception on every step in the programs. Monads can handle them and easily construct a function pipelining by Map() function. To peek a value (plain .NET object) from a monad you can use Match() function.

Option

Option elevates an object and returns Some(object) if it has value, otherwise None.

Let us consider a IUserRepository which has a method FindById() to get an user by his/her ID.

User FindById(int userId); // typical approach
Option<User> FindById(int userId); // MF approach

Let us assume User has a property Gender and you want to know the gender an user.

// typical approach
var repo = new UserRepository();
User user = repo.FindById(1234);
if(user != null) {
    return user.Gender;
}else {
    // throw new Exception
}

// MF approach
return new UserRepository()
    .FindById(1234)
    .Map(user => user.Gender);

Usage

To elevate a plain object:

var user = Some(plainUser);

To peek the value from Option:

user.Match(Some: usr => usr.Gender, None: () => "Not Given");

// or using GetOrElse
string gender = Some(user).GetOrElse("Not Given");

Some and None are named arguments of Match().

Result

Result is more safer than Option while handling plain objects. It elevates and also encapsulates Error so that the caller will get error details if plain object is NULL. This way without exception handling, you can safely pass plain object from innermost layer to top layer.

A result monad has two values:

  • Actual plain object or None
  • Error if actual object is None

To elevate:

var plainUser = new User("Abdul Basid");
var user = Result(plainUser); // elevated using Result()

To return as function value:

// consider UserRepository.FindByUserId()
Result<User> FindByUserId(int userId) {
    var query = // find the user in DB;

    // If your Repository foundation API uses MF, you even don't need to write this NULL handling logic.
    if(query is Good ) {
        return query.User; // automatic Result<User> casting happens
    } else {
        return Error.Of(10010); // assume you are using error code in your application
    }
}

To use it in pipeline:

new UserRepository()
    .FindByUserId(1234)
    .Map(u => u.Gender);

To peek the value at top most layer of your application:

 repo
    .FindByUserId(1234)
    .Match(pass: (v) => $"Hi, {v.Name})",
           fail: (f) => "Sorry, we are not able to find your details");

// or GetOrElse
repo
    .FindByUserId(1234)
    .GetOrElse(EmptyUser());

pass and fail are named arguments of Match().

Detail Developer Guide

In progress

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on Masha.Foundation:

Package Downloads
Masha.Foundation.Repository.MongoDb

Package Description

Masha.Foundation.Domain

Package Description

Masha.FoundExt.Kafka

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.2.0 800 8/29/2019
0.1.1 967 7/23/2019