├── .gitignore
├── Async Await Task Explained
├── AsyncAwait
│ ├── AsyncAwait.sln
│ └── AsyncAwait
│ │ ├── AsyncAwait.csproj
│ │ └── Program.cs
├── making_tea_analogy.linq
└── what_thread_are_we_on.linq
├── Channels
├── HowToUseChannels
│ ├── HowToUseChannels.sln
│ └── HowToUseChannels
│ │ ├── Controllers
│ │ └── Home.cs
│ │ ├── HowToUseChannels.csproj
│ │ ├── Program.cs
│ │ ├── Serivces
│ │ ├── Data
│ │ │ └── User.cs
│ │ ├── Database.cs
│ │ ├── NotificationDispatcher.cs
│ │ └── Notifications.cs
│ │ ├── Startup.cs
│ │ ├── appsettings.Development.json
│ │ └── appsettings.json
├── blocking_operation.linq
└── how_their_made.linq
├── Delegates
├── bench.linq
├── implementation_detail.linq
└── running_example.linq
├── Dependency Injection
├── activator.linq
├── lifetimes.linq
└── resolver_container.linq
├── ExpressionTrees
├── creating_expressions.linq
├── reading_expressions.linq
└── simple_example.linq
├── Generics
├── mediatr_parody.linq
├── no_generics.linq
├── with_generics.linq
└── with_generics_extended.linq
├── HowToUseAsynchAwaitTask
├── HowToUseAsynchAwaitTask.sln
├── WebApp
│ ├── Controllers
│ │ ├── AvoidStateMachine.cs
│ │ ├── DoesntMatterWhichThread.cs
│ │ ├── DontAsyncInConstructor.cs
│ │ └── DontBlockTheThread.cs
│ ├── Program.cs
│ ├── Startup.cs
│ ├── WebApp.csproj
│ ├── appsettings.Development.json
│ └── appsettings.json
├── WhereDoesItStart
│ ├── Program.cs
│ └── WhereDoesItStart.csproj
└── WpfApp
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── AssemblyInfo.cs
│ ├── MainWindow.xaml
│ ├── MainWindow.xaml.cs
│ └── WpfApp.csproj
├── IEnumerable
├── deepish_dive.linq
└── explanation.linq
├── MVC
├── mvc_the_problem.linq
└── mvc_the_solution.linq
├── Middleware
├── Middleware
│ ├── Middleware.sln
│ └── Middleware
│ │ ├── HttpClientMiddleware.cs
│ │ ├── Middleware.csproj
│ │ ├── Program.cs
│ │ ├── Properties
│ │ └── launchSettings.json
│ │ ├── Startup.cs
│ │ ├── appsettings.Development.json
│ │ └── appsettings.json
├── core_concept.linq
├── custom_middleware.linq
├── linq_ladders.linq
└── main.js
├── README.md
├── Reflection
├── Reflection.sln
└── WebApp
│ ├── AuthHandler.cs
│ ├── ClaimsService.cs
│ ├── Constants.cs
│ ├── Controllers
│ ├── HomeController.cs
│ └── ManageController.cs
│ ├── Program.cs
│ ├── Startup.cs
│ ├── Views
│ └── Home
│ │ └── SignIn.cshtml
│ ├── WebApp.csproj
│ ├── appsettings.json
│ └── wwwroot
│ └── favicon.ico
└── Semaphore
├── save_the_client.linq
└── the_gate.linq
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # User specific
3 | **/.idea/**/workspace.xml
4 | **/.idea/**/tasks.xml
5 | **/.idea/shelf/*
6 | **/.idea/dictionaries
7 | **/.idea/httpRequests/
8 |
9 | # Sensitive or high-churn files
10 | **/.idea/**/dataSources/
11 | **/.idea/**/dataSources.ids
12 | **/.idea/**/dataSources.xml
13 | **/.idea/**/dataSources.local.xml
14 | **/.idea/**/sqlDataSources.xml
15 | **/.idea/**/dynamic.xml
16 |
17 | # Rider
18 | # Rider auto-generates .iml files, and contentModel.xml
19 | **/.idea/**/*.iml
20 | **/.idea/**/contentModel.xml
21 | **/.idea/**/modules.xml
22 |
23 | # System Files
24 | .vs/
25 | **/obj
26 | **/bin
27 | **/Properties
28 | *.csproj.user
29 | **/node_modules
--------------------------------------------------------------------------------
/Async Await Task Explained/AsyncAwait/AsyncAwait.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29905.134
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsyncAwait", "AsyncAwait\AsyncAwait.csproj", "{7A02E0EA-683C-4C03-A721-AF94813F439C}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {7A02E0EA-683C-4C03-A721-AF94813F439C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {7A02E0EA-683C-4C03-A721-AF94813F439C}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {7A02E0EA-683C-4C03-A721-AF94813F439C}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {7A02E0EA-683C-4C03-A721-AF94813F439C}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {1A45E28A-9071-475F-9F30-1BD2163588E6}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/Async Await Task Explained/AsyncAwait/AsyncAwait/AsyncAwait.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.1
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Async Await Task Explained/AsyncAwait/AsyncAwait/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net.Http;
3 | using System.Threading.Tasks;
4 |
5 | namespace AsyncAwait
6 | {
7 | class Program
8 | {
9 | static async Task Main(string[] args)
10 | {
11 | var client = new HttpClient();
12 | var task = await client.GetStringAsync("https://google.com");
13 |
14 | int a = 0;
15 | for (int i = 0; i < 1_000_000; i++)
16 | {
17 | a = i + 1;
18 | }
19 | var task2 = await client.GetStringAsync("https://google.com");
20 |
21 | Console.WriteLine("Hello World");
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Async Await Task Explained/making_tea_analogy.linq:
--------------------------------------------------------------------------------
1 |
2 | System.Threading.Tasks
3 |
4 |
5 | async Task Main()
6 | {
7 | await MakeTeaAsync();
8 | }
9 |
10 |
11 | public async Task MakeTeaAsync()
12 | {
13 | var boilingWater = BoilWaterAsync();
14 |
15 | "take the cups out".Dump();
16 |
17 | var a = 0;
18 | for (int i = 0; i < 100_000_000; i++){
19 | a += i;
20 | }
21 |
22 | "put tea in cups".Dump();
23 |
24 | var water = await boilingWater;
25 |
26 | var tea = $"pour {water} in cups".Dump();
27 |
28 | return tea;
29 | }
30 |
31 | public async Task BoilWaterAsync()
32 | {
33 | "Start the kettle".Dump();
34 |
35 | "waiting for the kettle".Dump();
36 | await Task.Delay(300);
37 |
38 | "kettle finished boiling".Dump();
39 |
40 | return "water";
41 | }
42 |
43 | public string MakeTea()
44 | {
45 | var water = BoilWater();
46 |
47 | "take the cups out".Dump();
48 |
49 | "put tea in cups".Dump();
50 |
51 | var tea = $"pour {water} in cups".Dump();
52 |
53 | return tea;
54 | }
55 |
56 | public string BoilWater()
57 | {
58 | "Start the kettle".Dump();
59 |
60 | "waiting for the kettle".Dump();
61 | Task.Delay(2000).GetAwaiter().GetResult();
62 |
63 | "kettle finished boiling".Dump();
64 |
65 | return "water";
66 | }
--------------------------------------------------------------------------------
/Async Await Task Explained/what_thread_are_we_on.linq:
--------------------------------------------------------------------------------
1 |
2 | System.Net.Http
3 | System.Threading.Tasks
4 |
5 |
6 | async Task Main()
7 | {
8 | //part 1
9 | Thread.CurrentThread.ManagedThreadId.Dump("1");
10 | var client = new HttpClient();
11 | Thread.CurrentThread.ManagedThreadId.Dump("2");
12 | var task = client.GetStringAsync("http://google.com");
13 | Thread.CurrentThread.ManagedThreadId.Dump("3");
14 |
15 | var a = 0;
16 | for (int i = 0; i < 1_000_000; i++)
17 | {
18 | a += i;
19 | }
20 |
21 | Thread.CurrentThread.ManagedThreadId.Dump("4");
22 | var page = await task;
23 | // part 2
24 | Thread.CurrentThread.ManagedThreadId.Dump("5");
25 | }
--------------------------------------------------------------------------------
/Channels/HowToUseChannels/HowToUseChannels.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30011.22
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HowToUseChannels", "HowToUseChannels\HowToUseChannels.csproj", "{7AF8688C-D651-40D2-9914-061620DEFABA}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {7AF8688C-D651-40D2-9914-061620DEFABA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {7AF8688C-D651-40D2-9914-061620DEFABA}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {7AF8688C-D651-40D2-9914-061620DEFABA}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {7AF8688C-D651-40D2-9914-061620DEFABA}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {5BBB6AC5-E002-45A8-9424-586F8F6A5E0C}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/Channels/HowToUseChannels/HowToUseChannels/Controllers/Home.cs:
--------------------------------------------------------------------------------
1 | using HowToUseChannels.Serivces;
2 | using Microsoft.AspNetCore.Mvc;
3 | using System.Threading.Channels;
4 | using System.Threading.Tasks;
5 |
6 | namespace HowToUseChannels.Controllers
7 | {
8 | public class Home : Controller
9 | {
10 | public IActionResult Send()
11 | {
12 | Task.Run(() =>
13 | {
14 | Task.Delay(100).Wait();
15 |
16 | Task.Delay(200).Wait();
17 | });
18 |
19 | return Ok();
20 | }
21 |
22 | public Task SendB([FromServices] Notifications notifications)
23 | {
24 | return notifications.Send();
25 | }
26 |
27 | public bool SendA([FromServices] Notifications notifications)
28 | {
29 | return notifications.SendA();
30 | }
31 |
32 | public async Task SendC([FromServices] Channel channel)
33 | {
34 | await channel.Writer.WriteAsync("Hello");
35 | return true;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Channels/HowToUseChannels/HowToUseChannels/HowToUseChannels.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Channels/HowToUseChannels/HowToUseChannels/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Hosting;
6 | using Microsoft.Extensions.Configuration;
7 | using Microsoft.Extensions.Hosting;
8 | using Microsoft.Extensions.Logging;
9 |
10 | namespace HowToUseChannels
11 | {
12 | public class Program
13 | {
14 | public static void Main(string[] args)
15 | {
16 | CreateHostBuilder(args).Build().Run();
17 | }
18 |
19 | public static IHostBuilder CreateHostBuilder(string[] args) =>
20 | Host.CreateDefaultBuilder(args)
21 | .ConfigureWebHostDefaults(webBuilder =>
22 | {
23 | webBuilder.UseStartup();
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Channels/HowToUseChannels/HowToUseChannels/Serivces/Data/User.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace HowToUseChannels.Serivces.Data
8 | {
9 | public class User
10 | {
11 | public int Id { get; set; }
12 | public string Message { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Channels/HowToUseChannels/HowToUseChannels/Serivces/Database.cs:
--------------------------------------------------------------------------------
1 | using HowToUseChannels.Serivces.Data;
2 | using Microsoft.EntityFrameworkCore;
3 | using System.Threading.Tasks;
4 |
5 | namespace HowToUseChannels.Serivces
6 | {
7 | public class Database : DbContext
8 | {
9 | public Database(DbContextOptions options) : base(options) { }
10 |
11 | public DbSet Users { get; set; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Channels/HowToUseChannels/HowToUseChannels/Serivces/NotificationDispatcher.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using Microsoft.Extensions.Hosting;
4 | using Microsoft.Extensions.Logging;
5 | using System;
6 | using System.Net.Http;
7 | using System.Threading;
8 | using System.Threading.Channels;
9 | using System.Threading.Tasks;
10 |
11 | namespace HowToUseChannels.Serivces
12 | {
13 | public class NotificationDispatcher : BackgroundService
14 | {
15 | private readonly Channel channel;
16 | private readonly ILogger logger;
17 | private readonly IHttpClientFactory httpClientFactory;
18 | private readonly IServiceProvider provider;
19 |
20 | public NotificationDispatcher(
21 | Channel channel,
22 | ILogger logger,
23 | IHttpClientFactory httpClientFactory,
24 | IServiceProvider provider)
25 | {
26 | this.channel = channel;
27 | this.logger = logger;
28 | this.httpClientFactory = httpClientFactory;
29 | this.provider = provider;
30 | }
31 |
32 | protected override async Task ExecuteAsync(CancellationToken stoppingToken)
33 | {
34 | while (!channel.Reader.Completion.IsCompleted) // if not complete
35 | {
36 | // read from channel
37 | var msg = await channel.Reader.ReadAsync();
38 | try
39 | {
40 | using (var scope = provider.CreateScope())
41 | {
42 | var database = scope.ServiceProvider.GetRequiredService();
43 | if (!await database.Users.AnyAsync())
44 | {
45 | database.Users.Add(new Data.User());
46 | await database.SaveChangesAsync();
47 | }
48 |
49 | var user = await database.Users.FirstOrDefaultAsync();
50 |
51 | var client = httpClientFactory.CreateClient();
52 | var response = await client.GetStringAsync("https://docs.microsoft.com/en-us/dotnet/core/");
53 | user.Message = response;
54 |
55 | await database.SaveChangesAsync();
56 | }
57 | }
58 | catch (Exception e)
59 | {
60 | logger.LogError(e, "notification failed");
61 | }
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Channels/HowToUseChannels/HowToUseChannels/Serivces/Notifications.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using System;
3 | using System.Net.Http;
4 | using System.Threading.Tasks;
5 |
6 | namespace HowToUseChannels.Serivces
7 | {
8 | public class Notifications
9 | {
10 | private readonly Database database;
11 | private readonly IHttpClientFactory httpClientFactory;
12 |
13 | public Notifications(Database database, IHttpClientFactory httpClientFactory)
14 | {
15 | this.database = database;
16 | this.httpClientFactory = httpClientFactory;
17 | }
18 |
19 | public async Task Send()
20 | {
21 | if (!await database.Users.AnyAsync())
22 | {
23 | database.Users.Add(new Data.User());
24 | await database.SaveChangesAsync();
25 | }
26 |
27 | var user = await database.Users.FirstOrDefaultAsync();
28 |
29 | var client = httpClientFactory.CreateClient();
30 | var response = await client.GetStringAsync("https://docs.microsoft.com/en-us/dotnet/core/");
31 | user.Message = response;
32 |
33 | await database.SaveChangesAsync();
34 |
35 | return true;
36 | }
37 |
38 | public bool SendA()
39 | {
40 | Task.Run(async () =>
41 | {
42 | try
43 | {
44 | if (!await database.Users.AnyAsync())
45 | {
46 | database.Users.Add(new Data.User());
47 | await database.SaveChangesAsync();
48 | }
49 |
50 | var user = await database.Users.FirstOrDefaultAsync();
51 |
52 | var client = httpClientFactory.CreateClient();
53 | var response = await client.GetStringAsync("https://docs.microsoft.com/en-us/dotnet/core/");
54 | user.Message = response;
55 |
56 | await database.SaveChangesAsync();
57 | }
58 | catch (Exception e)
59 | {
60 | var a = e;
61 | }
62 | });
63 |
64 | return true;
65 | }
66 |
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Channels/HowToUseChannels/HowToUseChannels/Startup.cs:
--------------------------------------------------------------------------------
1 | using HowToUseChannels.Serivces;
2 | using Microsoft.AspNetCore.Builder;
3 | using Microsoft.AspNetCore.Hosting;
4 | using Microsoft.EntityFrameworkCore;
5 | using Microsoft.Extensions.DependencyInjection;
6 | using Microsoft.Extensions.Hosting;
7 | using System.Threading.Channels;
8 |
9 | namespace HowToUseChannels
10 | {
11 | public class Startup
12 | {
13 | public void ConfigureServices(IServiceCollection services)
14 | {
15 | services.AddDbContext(config =>
16 | config.UseInMemoryDatabase("test"));
17 |
18 | services.AddHttpClient();
19 |
20 | services.AddHostedService();
21 | services.AddSingleton(Channel.CreateUnbounded());
22 | services.AddTransient();
23 | services.AddControllers();
24 | }
25 |
26 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
27 | {
28 | if (env.IsDevelopment())
29 | {
30 | app.UseDeveloperExceptionPage();
31 | }
32 |
33 | app.UseRouting();
34 |
35 | app.UseEndpoints(endpoints =>
36 | {
37 | endpoints.MapDefaultControllerRoute();
38 | });
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Channels/HowToUseChannels/HowToUseChannels/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Channels/HowToUseChannels/HowToUseChannels/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "AllowedHosts": "*"
10 | }
11 |
--------------------------------------------------------------------------------
/Channels/blocking_operation.linq:
--------------------------------------------------------------------------------
1 |
2 | System.Threading.Tasks
3 |
4 |
5 | void Main()
6 | {
7 | for(int i = 0; i < 10; i++) {
8 | i.Dump();
9 | Task.Run(() => SendNotification());
10 | }
11 | }
12 |
13 | public void SendNotification(){
14 | Task.Delay(1000).GetAwaiter().GetResult();
15 | "complete".Dump();
16 | }
--------------------------------------------------------------------------------
/Channels/how_their_made.linq:
--------------------------------------------------------------------------------
1 |
2 | System.Threading.Tasks
3 | System.Collections.Concurrent
4 |
5 |
6 | void Main()
7 | {
8 | var channel = new Channel();
9 |
10 | Task.WaitAll(Consumer(channel), Producer(channel), Producer(channel), Producer(channel), Producer(channel));
11 | }
12 |
13 | public async Task Producer(IWrite writer){
14 | for(int i = 0; i < 10; i++){
15 | writer.Push(i.ToString());
16 | await Task.Delay(100);
17 | }
18 | writer.Complete();
19 | }
20 |
21 | public async Task Consumer(IRead reader){
22 | while(!reader.IsComplete()){
23 | var msg = await reader.Read();
24 | msg.Dump("msg");
25 | }
26 | }
27 |
28 | public interface IRead
29 | {
30 | Task Read();
31 | bool IsComplete();
32 | }
33 |
34 | public interface IWrite
35 | {
36 | void Push(T msg);
37 | void Complete();
38 | }
39 |
40 | public class Channel : IRead, IWrite
41 | {
42 | private bool Finished;
43 |
44 | private ConcurrentQueue _queue;
45 | private SemaphoreSlim _flag;
46 |
47 | public Channel()
48 | {
49 | _queue = new ConcurrentQueue();
50 | _flag = new SemaphoreSlim(0);
51 | }
52 |
53 | public void Push(T msg)
54 | {
55 | _queue.Enqueue(msg);
56 | _flag.Release();
57 | }
58 |
59 | public async Task Read()
60 | {
61 | await _flag.WaitAsync();
62 |
63 | if(_queue.TryDequeue(out var msg)){
64 | return msg;
65 | }
66 |
67 | return default;
68 | }
69 |
70 | public void Complete()
71 | {
72 | Finished = true;
73 | }
74 |
75 | public bool IsComplete()
76 | {
77 | return Finished && _queue.IsEmpty;
78 | }
79 | }
--------------------------------------------------------------------------------
/Delegates/bench.linq:
--------------------------------------------------------------------------------
1 |
2 | BenchmarkDotNet
3 | BenchmarkDotNet.Running
4 | BenchmarkDotNet.Attributes
5 | BenchmarkDotNet.Jobs
6 | System.Threading.Tasks
7 |
8 |
9 | void Main()
10 | {
11 | BenchmarkRunner.Run().Dump(false);
12 | }
13 |
14 | public class Object_Delegate_Func
15 | {
16 | public class OAdd
17 | {
18 | public static int Add(int a, int b) => a + b;
19 | }
20 |
21 | public delegate int Add(int a, int b);
22 |
23 | [Benchmark]
24 | public int Obj(){
25 | return OAdd.Add(1, 1);
26 | }
27 |
28 | [Benchmark]
29 | public int DelObj()
30 | {
31 | Add add = OAdd.Add;
32 | return add(1, 1);
33 | }
34 |
35 | [Benchmark]
36 | public int DelObjNew()
37 | {
38 | var add = new Add(OAdd.Add);
39 | return add(1, 1);
40 | }
41 |
42 | [Benchmark]
43 | public int Del()
44 | {
45 | Add add = (a,b) => a + b;
46 | return add(1,1);
47 | }
48 |
49 | [Benchmark]
50 | public int Func()
51 | {
52 | Func add = (a,b) => a + b;
53 | return add(1,1);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Delegates/implementation_detail.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | int i = 5;
6 | GetNumber getN = () => 5 + i;
7 | getN().Dump();
8 | }
9 |
10 | public class MyLambda
11 | {
12 | public MyDelegate myDelegate;
13 |
14 | public int Main() => 5;
15 | }
16 |
17 |
18 | public class MyDelegate
19 | {
20 | object _obj;
21 | MethodInfo _info;
22 |
23 | public MyDelegate(
24 | object obj,
25 | MethodInfo info
26 | ){
27 | _obj = obj;
28 | _info = info;
29 | }
30 |
31 | public int Invoke() => (int) _info.Invoke(_obj, null);
32 | }
33 |
34 | delegate int GetNumber();
--------------------------------------------------------------------------------
/Delegates/running_example.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | public delegate void DrinkingAction();
4 |
5 | void Main()
6 | {
7 | //DrinkWater();
8 | //DrinkBeer();
9 | //DrinkLemonade();
10 |
11 | RelaxingOnTheBeach(DrinkWater);
12 | RelaxingOnTheBeach(DrinkBeer);
13 | RelaxingOnTheBeach(DrinkLemonade);
14 | //Run(DrinkBeer);
15 |
16 | //var drinkingAction = new DrinkingAction(DrinkWater);
17 |
18 | Func add = (int a, int b) => a + b;
19 |
20 | add(1,1).Dump();
21 |
22 | Action printNumber = (n, n1) => n.Dump();
23 | }
24 |
25 | public void DrinkWater() => "Drinking Water".Dump();
26 | public void DrinkBeer() => "Drinking Beer".Dump();
27 | public void DrinkLemonade() => "Drinking Lemonade".Dump();
28 |
29 |
30 | public void RelaxingOnTheBeach(Action drink){
31 | "Realxing on the Beach".Dump();
32 | if(drink != null) drink();
33 | }
34 |
35 | public void Run(Func drink)
36 | {
37 | "Running 10 miles".Dump();
38 | if (drink != null) drink();
39 | }
--------------------------------------------------------------------------------
/Dependency Injection/activator.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | // var service = new HelloService();
6 | // var consumer = new ServiceConsumer(service);
7 | var a = typeof(HelloService).Dump();
8 | var service = (HelloService) Activator.CreateInstance(typeof(HelloService));
9 | var consumer = (ServiceConsumer) Activator.CreateInstance(typeof(ServiceConsumer), service);
10 | service.Print();
11 | consumer.Print();
12 | }
13 |
14 | public class ServiceConsumer
15 | {
16 | HelloService _hello;
17 | public ServiceConsumer(HelloService hello)
18 | {
19 | _hello= hello;
20 | }
21 |
22 | public void Print()
23 | {
24 | _hello.Print();
25 | }
26 | }
27 |
28 | public class HelloService
29 | {
30 | public void Print(){
31 | "Hello World".Dump();
32 | }
33 | }
--------------------------------------------------------------------------------
/Dependency Injection/lifetimes.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | var container = new DependencyContainer();
6 | container.AddTransient();
7 | container.AddTransient();
8 | container.AddSingleton();
9 |
10 | var resolver = new DependencyResolver(container);
11 |
12 | var service1 = resolver.GetService();
13 |
14 | service1.Print();
15 | var service2 = resolver.GetService();
16 | service2.Print();
17 | var service3 = resolver.GetService();
18 | service3.Print();
19 | }
20 |
21 | public class DependencyResolver
22 | {
23 | DependencyContainer _container;
24 | public DependencyResolver(DependencyContainer container)
25 | {
26 | _container = container;
27 | }
28 |
29 | public T GetService()
30 | {
31 | return (T)GetService(typeof(T));
32 | }
33 |
34 | public object GetService(Type type)
35 | {
36 | var dependency = _container.GetDependency(type);
37 | var constructor = dependency.Type.GetConstructors().Single();
38 | var parameters = constructor.GetParameters().ToArray();
39 |
40 | if (parameters.Length > 0)
41 | {
42 | var parameterImplementations = new object[parameters.Length];
43 |
44 | for (int i = 0; i < parameters.Length; i++)
45 | {
46 | parameterImplementations[i] = GetService(parameters[i].ParameterType);
47 | }
48 |
49 | return CreateImplementaiton(dependency, t => Activator.CreateInstance(t, parameterImplementations));
50 | }
51 |
52 | return CreateImplementaiton(dependency, t => Activator.CreateInstance(t));
53 | }
54 |
55 | public object CreateImplementaiton(Dependency dependency, Func factory)
56 | {
57 | if (dependency.Implemented)
58 | {
59 | return dependency.Implementation;
60 | }
61 |
62 | var implementation = factory(dependency.Type);
63 |
64 | if (dependency.Lifetime == DependencyLifetime.Singleton)
65 | {
66 | dependency.AddImplementation(implementation);
67 | }
68 |
69 | return implementation;
70 | }
71 | }
72 |
73 |
74 | public class DependencyContainer
75 | {
76 | List _dependencies;
77 |
78 | public DependencyContainer()
79 | {
80 | _dependencies = new List();
81 | }
82 |
83 | public void AddSingleton()
84 | {
85 | _dependencies.Add(new Dependency(typeof(T), DependencyLifetime.Singleton));
86 | }
87 |
88 | public void AddTransient()
89 | {
90 | _dependencies.Add(new Dependency(typeof(T), DependencyLifetime.Transient));
91 | }
92 |
93 | public Dependency GetDependency(Type type)
94 | {
95 | return _dependencies.First(x => x.Type.Name == type.Name);
96 | }
97 | }
98 |
99 | public class Dependency
100 | {
101 | public Dependency(Type t, DependencyLifetime l)
102 | {
103 | Type = t;
104 | Lifetime = l;
105 | }
106 | public Type Type { get; set; }
107 | public DependencyLifetime Lifetime { get; set; }
108 | public object Implementation { get; set; }
109 | public bool Implemented { get; set; }
110 |
111 | public void AddImplementation(object i){
112 | Implementation = i;
113 | Implemented = true;
114 | }
115 | }
116 |
117 | public enum DependencyLifetime
118 | {
119 | Singleton = 0,
120 | Transient = 1,
121 | }
122 |
123 | public class ServiceConsumer
124 | {
125 | HelloService _hello;
126 | public ServiceConsumer(HelloService hello)
127 | {
128 | _hello = hello;
129 | }
130 |
131 | public void Print()
132 | {
133 | _hello.Print();
134 | }
135 | }
136 |
137 | public class HelloService
138 | {
139 | MessageService _message;
140 | int _random;
141 | public HelloService(MessageService message)
142 | {
143 | _message = message;
144 | _random = new Random().Next();
145 | }
146 |
147 | public void Print()
148 | {
149 | $"Hello #{_random} World {_message.Message()}".Dump();
150 | }
151 | }
152 |
153 | public class MessageService
154 | {
155 | int _random;
156 | public MessageService()
157 | {
158 | _random = new Random().Next();
159 | }
160 |
161 | public string Message()
162 | {
163 | return $"Yo #{_random}";
164 | }
165 | }
--------------------------------------------------------------------------------
/Dependency Injection/resolver_container.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | //typeof(ServiceConsumer)
6 | // .GetConstructors()
7 | // .Select(x => x.GetParameters()).Dump();
8 |
9 | var container = new DependencyContainer();
10 | container.AddDependency(typeof(HelloService));
11 | container.AddDependency();
12 | container.AddDependency();
13 |
14 | var resolver = new DependencyResolver(container);
15 |
16 | var service = resolver.GetService();
17 |
18 | service.Print();
19 | }
20 |
21 | public class DependencyResolver
22 | {
23 | DependencyContainer _container;
24 | public DependencyResolver(DependencyContainer container)
25 | {
26 | _container = container;
27 | }
28 |
29 | public T GetService()
30 | {
31 | return (T) GetService(typeof(T));
32 | }
33 |
34 | public object GetService(Type type)
35 | {
36 | var dependency = _container.GetDependency(type);
37 | var constructor = dependency.GetConstructors().Single();
38 | var parameters = constructor.GetParameters().ToArray();
39 |
40 | if (parameters.Length > 0)
41 | {
42 | var parameterImplementations = new object[parameters.Length];
43 |
44 | for (int i = 0; i < parameters.Length; i++)
45 | {
46 | parameterImplementations[i] = GetService(parameters[i].ParameterType);
47 | }
48 |
49 | return Activator.CreateInstance(dependency, parameterImplementations);
50 | }
51 |
52 |
53 | return Activator.CreateInstance(dependency);
54 | }
55 | }
56 |
57 |
58 | public class DependencyContainer
59 | {
60 | List _dependencies;
61 |
62 | public void AddDependency(Type type)
63 | {
64 | _dependencies = new List();
65 | _dependencies.Add(type);
66 | }
67 |
68 | public void AddDependency()
69 | {
70 | _dependencies.Add(typeof(T));
71 | }
72 |
73 | public Type GetDependency(Type type)
74 | {
75 | return _dependencies.First(x => x.Name == type.Name);
76 | }
77 | }
78 |
79 | public class ServiceConsumer
80 | {
81 | HelloService _hello;
82 | public ServiceConsumer(HelloService hello)
83 | {
84 | _hello = hello;
85 | }
86 |
87 | public void Print()
88 | {
89 | _hello.Print();
90 | }
91 | }
92 |
93 | public class HelloService
94 | {
95 | MessageService _message;
96 | public HelloService(MessageService message)
97 | {
98 | _message = message;
99 | }
100 |
101 | public void Print()
102 | {
103 | $"Hello World {_message.Message()}".Dump();
104 | }
105 | }
106 |
107 | public class MessageService
108 | {
109 | public string Message()
110 | {
111 | return "Yo";
112 | }
113 | }
--------------------------------------------------------------------------------
/ExpressionTrees/creating_expressions.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | // value coming from query/header/body
6 | //var selectProperty = "word";
7 | var selectProperty = "number";
8 |
9 | var someClass = new SomeClass {
10 | Word = "Hello World",
11 | Number = 1234
12 | };
13 |
14 | // hard coded, not scalable
15 | if (selectProperty == "word")
16 | {
17 | someClass.Word.Dump();
18 | }
19 | else if (selectProperty == "number")
20 | {
21 | someClass.Number.Dump();
22 | }
23 |
24 | // solution: ???
25 |
26 | //parameter
27 | var parameter = Expression.Parameter(typeof(SomeClass));
28 | var accessor = Expression.PropertyOrField(parameter, selectProperty);
29 |
30 | var lambda = Expression.Lambda(accessor, false, parameter);
31 | lambda.Compile().DynamicInvoke(someClass).Dump();
32 | }
33 |
34 |
35 | public class SomeClass
36 | {
37 | public string Word { get; set; }
38 | public int Number { get; set; }
39 | }
--------------------------------------------------------------------------------
/ExpressionTrees/reading_expressions.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | string url = "http://example.com/users";
6 |
7 | CreateUrl(url, "name", "age").Dump("1"); // mistake prone
8 |
9 | CreateUrl(url, u => u.Name, u => u.Age).Dump("2");
10 | }
11 |
12 | public string CreateUrl(string url, params string[] fields){
13 | var selectedFields = string.Join(',', fields);
14 | return string.Concat(url, "?fields=", selectedFields);
15 | }
16 |
17 | public string CreateUrl(string url, params Expression>[] fieldSelectors){
18 | var fields = new List();
19 |
20 | foreach(var selector in fieldSelectors){
21 | var body = selector.Body;
22 | if (body is MemberExpression me)
23 | {
24 | fields.Add(me.Member.Name.ToLower());
25 | }
26 | else if (body is UnaryExpression ue)
27 | {
28 | fields.Add(((MemberExpression)ue.Operand).Member.Name.ToLower());
29 | }
30 | }
31 | var selectedFields = string.Join(',', fields);
32 | return string.Concat(url, "?fields=", selectedFields);
33 | }
34 |
35 |
36 | public class User {
37 | public string Name { get; set; }
38 | public int Age { get; set; }
39 | }
--------------------------------------------------------------------------------
/ExpressionTrees/simple_example.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | //Func five = () => 5;
6 | //five().Dump();
7 | //
8 | //Expression> five_exp = () => 5;
9 | //five_exp.Compile().Invoke().Dump();
10 |
11 | var user = new User();
12 | Expression> exp = user => user.Name;
13 | //var body = exp.Body.Dump();
14 | //if(body is MemberExpression me){
15 | // me.Member.Name.ToLower().Dump();
16 | //}
17 | //else if(body is UnaryExpression ue){
18 | // ((MemberExpression)ue.Operand).Member.Name.ToLower().Dump();
19 | //}
20 | exp.Dump();
21 | }
22 |
23 | public class User
24 | {
25 | public string Name { get; set; }
26 | public int Age { get; set; }
27 | }
--------------------------------------------------------------------------------
/Generics/mediatr_parody.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | var handler = new RequestHandler();
6 | handler.Handle(new GetAge()).Dump();
7 | handler.Handle(new GetName()).Dump();
8 | }
9 |
10 | public interface IRequest { }
11 |
12 | public class GetAge : IRequest { }
13 |
14 | public class GetName : IRequest { }
15 |
16 | public interface IHandler { };
17 |
18 | public abstract class Handler : IHandler {
19 | public abstract T Handle(IRequest request);
20 | };
21 |
22 | public abstract class Handler : Handler
23 | where TRequest : IRequest
24 | {
25 | public override TResponse Handle(IRequest request) =>
26 | Handle((TRequest) request);
27 |
28 | protected abstract TResponse Handle(TRequest requst);
29 | }
30 |
31 | public class GetAgeHandler : Handler
32 | {
33 | protected override int Handle(GetAge request) => 20;
34 | }
35 |
36 | public class GetNameHandler : Handler
37 | {
38 | protected override string Handle(GetName request) => "Foo";
39 | }
40 |
41 |
42 | public class RequestHandler
43 | {
44 | public Dictionary requestHandlers = new() {
45 | [typeof(GetAge)] = new GetAgeHandler(),
46 | [typeof(GetName)] = new GetNameHandler(),
47 | };
48 |
49 | public T Handle(IRequest request)
50 | {
51 | var handler = requestHandlers[request.GetType()];
52 | if (handler is Handler h) {
53 | return h.Handle(request);
54 | }
55 | return default;
56 | }
57 | }
58 |
59 |
60 |
--------------------------------------------------------------------------------
/Generics/no_generics.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | Hasher.Hash(new Post()).Dump();
6 | Hasher.Hash(new Comment()).Dump();
7 | }
8 |
9 | public class Content
10 | {
11 | public string Id { get; set; } = "id";
12 | public string Author { get; set; } = "author";
13 | public string Text { get; set; } = "text";
14 | }
15 |
16 | public class Post : Content { }
17 |
18 | public class Comment : Content
19 | {
20 | public string PostId { get; set; } = "postid";
21 | }
22 |
23 | public class ContentHashingStrategy
24 | {
25 | public static int Hash(Post post) =>
26 | post.Text.Length
27 | + post.Author.Length;
28 | }
29 |
30 | public class CommentHashingStrategy
31 | {
32 | public static int Hash(Comment comment) =>
33 | comment.Text.Length
34 | + comment.Author.Length
35 | + comment.PostId.Length;
36 | }
37 |
38 | public class Hasher
39 | {
40 | public static int Hash(Content content)
41 | {
42 | if (content is Post p) return ContentHashingStrategy.Hash(p);
43 | if (content is Comment c) return CommentHashingStrategy.Hash(c);
44 | return 0;
45 | }
46 | }
--------------------------------------------------------------------------------
/Generics/with_generics.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | Hasher.Hash(new Post()).Dump();
6 | Hasher.Hash(new Comment()).Dump();
7 | }
8 |
9 | public interface IHashingStrategy
10 | {
11 | int Hash(Content content);
12 | }
13 |
14 | public class Content
15 | {
16 | public string Id { get; set; } = "id";
17 | public string Author { get; set; } = "author";
18 | public string Text { get; set; } = "text";
19 | }
20 |
21 | public class Content : Content where T : IHashingStrategy { }
22 |
23 | public class Post : Content { }
24 |
25 | public class Comment : Content
26 | {
27 | public string PostId { get; set; } = "postid";
28 | }
29 |
30 | public class ContentHashingStrategy : IHashingStrategy
31 | {
32 | public int Hash(Content content)
33 | {
34 | return content.Text.Length
35 | + content.Author.Length;
36 | }
37 | }
38 |
39 | public class CommentHashingStrategy : IHashingStrategy
40 | {
41 | public int Hash(Content content)
42 | {
43 | var comment = content as Comment;
44 | return comment.Text.Length
45 | + comment.Author.Length
46 | + comment.PostId.Length;
47 | }
48 | }
49 |
50 | public class Hasher
51 | {
52 | public static int Hash(Content content)
53 | where T : IHashingStrategy, new()
54 | {
55 | return Activator.CreateInstance().Hash(content);
56 | }
57 | }
--------------------------------------------------------------------------------
/Generics/with_generics_extended.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | Hasher.Hash(new Post()).Dump();
6 | Hasher.Hash(new Comment()).Dump();
7 | }
8 |
9 | public interface IHashingStrategy {
10 | int Hash(Content content);
11 | }
12 |
13 | public abstract class HashingStrategy : IHashingStrategy
14 | where T : Content
15 | {
16 | public int Hash(Content content) => Hash((T) content);
17 |
18 | protected abstract int Hash(T content);
19 | }
20 |
21 | public class Content
22 | {
23 | public string Id { get; set; } = "id";
24 | public string Author { get; set; } = "author";
25 | public string Text { get; set; } = "text";
26 | }
27 |
28 | public class Content : Content where T : IHashingStrategy, new() {}
29 |
30 | public class Post : Content { }
31 |
32 | public class Comment : Content
33 | {
34 | public string PostId { get; set; } = "postid";
35 | }
36 |
37 | public class ContentHashingStrategy : HashingStrategy
38 | {
39 | protected override int Hash(Post content)
40 | {
41 | return content.Text.Length
42 | + content.Author.Length;
43 | }
44 | }
45 |
46 | public class CommentHashingStrategy : HashingStrategy
47 | {
48 | protected override int Hash(Comment comment)
49 | {
50 | return comment.Text.Length
51 | + comment.Author.Length
52 | + comment.PostId.Length;
53 | }
54 | }
55 |
56 | public class Hasher
57 | {
58 | public static int Hash(Content content)
59 | where H : IHashingStrategy, new()
60 | {
61 | return Activator.CreateInstance().Hash(content);
62 | }
63 | }
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/HowToUseAsynchAwaitTask.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30011.22
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApp", "WebApp\WebApp.csproj", "{7F157BFA-1063-42D8-9E8A-6C74C7B630F5}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WhereDoesItStart", "WhereDoesItStart\WhereDoesItStart.csproj", "{23C26454-BEA0-4080-B77E-F4D0338BAD24}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfApp", "WpfApp\WpfApp.csproj", "{F5C53ADB-5A4E-4D8D-97F7-5070AF2CFCC0}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {7F157BFA-1063-42D8-9E8A-6C74C7B630F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {7F157BFA-1063-42D8-9E8A-6C74C7B630F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {7F157BFA-1063-42D8-9E8A-6C74C7B630F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {7F157BFA-1063-42D8-9E8A-6C74C7B630F5}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {23C26454-BEA0-4080-B77E-F4D0338BAD24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {23C26454-BEA0-4080-B77E-F4D0338BAD24}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {23C26454-BEA0-4080-B77E-F4D0338BAD24}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {23C26454-BEA0-4080-B77E-F4D0338BAD24}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {F5C53ADB-5A4E-4D8D-97F7-5070AF2CFCC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {F5C53ADB-5A4E-4D8D-97F7-5070AF2CFCC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {F5C53ADB-5A4E-4D8D-97F7-5070AF2CFCC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {F5C53ADB-5A4E-4D8D-97F7-5070AF2CFCC0}.Release|Any CPU.Build.0 = Release|Any CPU
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | GlobalSection(ExtensibilityGlobals) = postSolution
35 | SolutionGuid = {827DE696-34F9-410F-84C9-EF06D2337BA5}
36 | EndGlobalSection
37 | EndGlobal
38 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WebApp/Controllers/AvoidStateMachine.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Net.Http;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace WebApp.Controllers
10 | {
11 | public class AvoidStateMachine : Controller
12 | {
13 | public async Task Index()
14 | {
15 | var a = await InputOutputN();
16 | return View(a);
17 | }
18 |
19 |
20 | public async Task InputOutputN()
21 | {
22 | var client = new HttpClient();
23 | var content = await client.GetStringAsync("some site");
24 | // do something with the content
25 |
26 | return content;
27 | }
28 |
29 | public Task InputOutputNA()
30 | {
31 | var client = new HttpClient();
32 | return client.GetStringAsync("some site");
33 | }
34 |
35 | public Task InputOutput()
36 | {
37 | var message = "Hello World";
38 | return Task.FromResult(message);
39 | }
40 |
41 | public Task InputOutputC()
42 | {
43 | return Task.CompletedTask;
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WebApp/Controllers/DoesntMatterWhichThread.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Net.Http;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace WebApp.Controllers
10 | {
11 | public class DoesntMatterWhichThread : Controller
12 | {
13 | public IActionResult Index()
14 | {
15 | return View();
16 | }
17 |
18 | public async Task InputOutput()
19 | {
20 | var client = new HttpClient();
21 | var content = await client.GetStringAsync("some site")
22 | .ConfigureAwait(false);
23 |
24 | return content;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WebApp/Controllers/DontAsyncInConstructor.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Net.Http;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace WebApp.Controllers
10 | {
11 | public class DontAsyncInConstructor : Controller
12 | {
13 | public IActionResult Index()
14 | {
15 | return View();
16 | }
17 |
18 | public Task InputOutput()
19 | {
20 |
21 | }
22 | }
23 |
24 | public class SomeObject
25 | {
26 | public SomeObject()
27 | {
28 | //never do async here.
29 | }
30 |
31 | public static async Task Create()
32 | {
33 | return new SomeObject();
34 | }
35 | }
36 |
37 | public class SomeObjectFactory
38 | {
39 | public SomeObjectFactory()
40 | {
41 |
42 | }
43 |
44 | public async Task Create()
45 | {
46 | return new SomeObject();
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WebApp/Controllers/DontBlockTheThread.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Net.Http;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace WebApp.Controllers
10 | {
11 | public class DontBlockTheThread : Controller
12 | {
13 | public IActionResult Index()
14 | {
15 | var task = InputOutput();
16 |
17 | //BAD
18 | var a = task.Result;
19 |
20 | //BAD
21 | task.Wait();
22 |
23 | //BAD
24 | task.GetAwaiter().GetResult();
25 |
26 | //solution is to propagate async await task throught your code
27 |
28 | return View();
29 | }
30 |
31 | public Task InputOutput()
32 | {
33 | var client = new HttpClient();
34 | return client.GetStringAsync("some site");
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WebApp/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Hosting;
6 | using Microsoft.Extensions.Configuration;
7 | using Microsoft.Extensions.Hosting;
8 | using Microsoft.Extensions.Logging;
9 |
10 | namespace WebApp
11 | {
12 | public class Program
13 | {
14 | public static void Main(string[] args)
15 | {
16 | CreateHostBuilder(args).Build().Run();
17 | }
18 |
19 | public static IHostBuilder CreateHostBuilder(string[] args) =>
20 | Host.CreateDefaultBuilder(args)
21 | .ConfigureWebHostDefaults(webBuilder =>
22 | {
23 | webBuilder.UseStartup();
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WebApp/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Builder;
6 | using Microsoft.AspNetCore.Hosting;
7 | using Microsoft.AspNetCore.Http;
8 | using Microsoft.Extensions.DependencyInjection;
9 | using Microsoft.Extensions.Hosting;
10 |
11 | namespace WebApp
12 | {
13 | public class Startup
14 | {
15 | public void ConfigureServices(IServiceCollection services)
16 | {
17 | }
18 |
19 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
20 | {
21 | if (env.IsDevelopment())
22 | {
23 | app.UseDeveloperExceptionPage();
24 | }
25 |
26 | app.UseRouting();
27 |
28 | app.UseEndpoints(endpoints =>
29 | {
30 | endpoints.MapGet("/", async context =>
31 | {
32 | await context.Response.WriteAsync("Hello World!");
33 | });
34 | });
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WebApp/WebApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WebApp/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WebApp/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "AllowedHosts": "*"
10 | }
11 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WhereDoesItStart/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Specialized;
3 | using System.Diagnostics;
4 | using System.Threading.Tasks;
5 |
6 | namespace WhereDoesItStart
7 | {
8 | class Program
9 | {
10 | static void Main(string[] args)
11 | {
12 | //StartApp();
13 | StartApp().GetAwaiter().GetResult();
14 | }
15 |
16 | public static Task StartApp()
17 | {
18 | var collect = Collect();
19 | var process = Process();
20 | //Task.WaitAll(new[] { collect, process });
21 |
22 | return Task.WhenAll(new[] { collect, process });
23 | }
24 |
25 | public static async Task Collect()
26 | {
27 | while (true)
28 | {
29 | // doing some internet stuff
30 | }
31 | }
32 |
33 | public static async Task Process()
34 | {
35 | while (true)
36 | {
37 | // doing some database stuff
38 |
39 | if (true)
40 | {
41 | //fire and forget
42 | Task.Run(() => Notify("hi"));
43 | }
44 | }
45 | }
46 |
47 | public static async Task Notify(string data)
48 | {
49 | // some network stuff
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WhereDoesItStart/WhereDoesItStart.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.1
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WpfApp/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WpfApp/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Data;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 |
9 | namespace WpfApp
10 | {
11 | ///
12 | /// Interaction logic for App.xaml
13 | ///
14 | public partial class App : Application
15 | {
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WpfApp/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | [assembly: ThemeInfo(
4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5 | //(used if a resource is not found in the page,
6 | // or application resource dictionaries)
7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8 | //(used if a resource is not found in the page,
9 | // app, or any theme specific resource dictionaries)
10 | )]
11 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WpfApp/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WpfApp/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net.Http;
5 | using System.Text;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 | using System.Windows;
9 | using System.Windows.Controls;
10 | using System.Windows.Data;
11 | using System.Windows.Documents;
12 | using System.Windows.Input;
13 | using System.Windows.Media;
14 | using System.Windows.Media.Imaging;
15 | using System.Windows.Navigation;
16 | using System.Windows.Shapes;
17 |
18 | namespace WpfApp
19 | {
20 | ///
21 | /// Interaction logic for MainWindow.xaml
22 | ///
23 | public partial class MainWindow : Window
24 | {
25 | public MainWindow()
26 | {
27 | InitializeComponent();
28 | }
29 |
30 | private List threadLog = new List();
31 | private HttpClient _client = new HttpClient();
32 |
33 | private async void Button_Click(object sender, RoutedEventArgs e)
34 | {
35 | threadLog.Add($"1 => {Thread.CurrentThread.ManagedThreadId}");
36 | var text = await Do().ConfigureAwait(false);
37 | threadLog.Add($"4 => {Thread.CurrentThread.ManagedThreadId}");
38 | testBox.Text = text;
39 | }
40 |
41 | public async Task Do()
42 | {
43 | threadLog.Add($"2 => {Thread.CurrentThread.ManagedThreadId}");
44 | var content = await _client.GetStringAsync("http://google.com")
45 | .ConfigureAwait(false);
46 | threadLog.Add($"3 => {Thread.CurrentThread.ManagedThreadId}");
47 | return "Hello World";
48 | }
49 |
50 | private void Button_Click_1(object sender, RoutedEventArgs e)
51 | {
52 | var a = threadLog;
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/HowToUseAsynchAwaitTask/WpfApp/WpfApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WinExe
5 | netcoreapp3.1
6 | true
7 |
8 |
9 |
--------------------------------------------------------------------------------
/IEnumerable/deepish_dive.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | //var simpleGen = new MySimpleGen();
6 | //while (simpleGen.HasValue())
7 | //{
8 | // var value = simpleGen.Value;
9 | // value.Dump("value");
10 | //}
11 |
12 | var actialGen = new MyActualGen();
13 |
14 | foreach(var v in actialGen){
15 | v.Dump("value");
16 | }
17 | }
18 |
19 | public class MySimpleGen
20 | {
21 | int _value = 1;
22 |
23 | public int Value => _value++;
24 |
25 | public bool HasValue()
26 | {
27 | _value.Dump();
28 |
29 | if (_value > 2)
30 | {
31 | return false;
32 | }
33 |
34 | return true;
35 | }
36 | }
37 |
38 | public class MyActualGen : IEnumerable, IEnumerator {
39 |
40 | int _value = 1;
41 |
42 | public int Current => _value++;
43 |
44 | object IEnumerator.Current => Current;
45 |
46 | public void Dispose(){}
47 |
48 | public IEnumerator GetEnumerator()
49 | {
50 | return this;
51 | }
52 |
53 | IEnumerator IEnumerable.GetEnumerator()
54 | {
55 | return GetEnumerator();
56 | }
57 |
58 | public bool MoveNext()
59 | {
60 | _value.Dump();
61 |
62 | if (_value > 2)
63 | {
64 | return false;
65 | }
66 |
67 | return true;
68 | }
69 |
70 | public void Reset()
71 | {
72 | _value = 1;
73 | }
74 | }
--------------------------------------------------------------------------------
/IEnumerable/explanation.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | //var enumrable = Get();
6 | //var list = Get().ToList();
7 |
8 | //var count = list.Count;
9 | //count.Dump("count");
10 | //foreach(var e in list){
11 | // e.Dump("value");
12 | //}
13 |
14 | Get()
15 | .Where(num => num.Dump("where") < 10)
16 | .Select(num => num.Dump("select"))
17 | .Count();
18 |
19 | }
20 |
21 | public IEnumerable Get()
22 | {
23 | "1".Dump();
24 | yield return 1;
25 | "2".Dump();
26 | yield return 2;
27 | "3".Dump();
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/MVC/mvc_the_problem.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | var uri = new Uri("http://localhost/home/index");
6 |
7 | uri.AbsolutePath.Split("/").Skip(1).Dump();
8 | if(uri.AbsolutePath.StartsWith("/home/index")){
9 | // execute some loginc
10 | }
11 | }
--------------------------------------------------------------------------------
/MVC/mvc_the_solution.linq:
--------------------------------------------------------------------------------
1 |
2 | System.Web
3 |
4 |
5 | void Main()
6 | {
7 | var uri = new Uri("http://localhost/home/index?msg=Hello&num=5");
8 |
9 | var container = new MvcContainer();
10 | var result = container.Resolve(uri);
11 | result.Dump();
12 | }
13 |
14 | public class MvcContainer {
15 |
16 | List controllerTypes = new List();
17 |
18 | public MvcContainer()
19 | {
20 | var controllerType = typeof(Controller);
21 |
22 | controllerTypes = controllerType.Assembly.GetTypes()
23 | .Where(type => !type.IsAbstract
24 | && controllerType.IsAssignableFrom(type))
25 | .ToList();
26 | }
27 |
28 | public object Resolve(Uri uri){
29 | var controller = getController(uri);
30 | var action = getAction(controller, uri);
31 | var parameters = getParameters(action, uri);
32 | return action.Invoke(controller, parameters);
33 | }
34 |
35 | private object[] getParameters(MethodInfo methodInfo, Uri uri)
36 | {
37 | var parameterInfos = methodInfo.GetParameters().ToList();
38 | if(parameterInfos.Count == 0){
39 | return null;
40 | }
41 | var results = new object[parameterInfos.Count];
42 |
43 | var query = HttpUtility.ParseQueryString(uri.Query);
44 |
45 | for(int i = 0; i < parameterInfos.Count; i++){
46 | var info = parameterInfos[i];
47 | var type = parameterInfos[i].ParameterType;
48 | var value = query[info.Name];
49 | if(type == typeof(String)){
50 | results[i] = value;
51 | }
52 | else if (type == typeof(Int32))
53 | {
54 | results[i] = Int32.Parse(value);
55 | }
56 | }
57 |
58 | return results;
59 | }
60 |
61 | private MethodInfo getAction(Controller controller, Uri uri)
62 | {
63 | var action = uri.AbsolutePath.Split('/').Last();
64 |
65 | return controller.GetType().GetMethods()
66 | .FirstOrDefault(x => x.Name.Equals(action,
67 | StringComparison.InvariantCultureIgnoreCase));
68 | }
69 |
70 | public Controller getController(Uri uri){
71 | var controllerType = controllerTypes
72 | .FirstOrDefault(x => uri.AbsolutePath
73 | .StartsWith($"/{x.Name.Replace("Controller", "")}",
74 | StringComparison.InvariantCultureIgnoreCase));
75 |
76 |
77 | return (Controller) Activator.CreateInstance(controllerType, null);
78 | }
79 |
80 | }
81 |
82 | public abstract class Controller{}
83 |
84 | public class HomeController : Controller {
85 |
86 | public string Index(int num, string msg)
87 | {
88 | return $"Hello World {msg} - {num}";
89 | }
90 |
91 | public string Test()
92 | {
93 | return "Hello Test";
94 | }
95 | }
96 |
97 | public class TestController : Controller
98 | {
99 |
100 | public string Index()
101 | {
102 | return "Test World";
103 | }
104 |
105 | }
--------------------------------------------------------------------------------
/Middleware/Middleware/Middleware.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29905.134
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Middleware", "Middleware\Middleware.csproj", "{8B336568-76B8-474D-9301-7801A1C643A9}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {8B336568-76B8-474D-9301-7801A1C643A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {8B336568-76B8-474D-9301-7801A1C643A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {8B336568-76B8-474D-9301-7801A1C643A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {8B336568-76B8-474D-9301-7801A1C643A9}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {769557E6-1F30-4DC3-AC6C-AD4A9B55E5D9}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/Middleware/Middleware/Middleware/HttpClientMiddleware.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net.Http;
5 | using System.Text;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace Middleware
10 | {
11 | public class HttpClientMiddleware : DelegatingHandler
12 | {
13 | protected override async Task SendAsync(
14 | HttpRequestMessage request,
15 | CancellationToken cancellationToken)
16 | {
17 | // do before
18 | var response = await base.SendAsync(request, cancellationToken);
19 | // do after
20 | return response;
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Middleware/Middleware/Middleware/Middleware.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Middleware/Middleware/Middleware/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Hosting;
6 | using Microsoft.Extensions.Configuration;
7 | using Microsoft.Extensions.Hosting;
8 | using Microsoft.Extensions.Logging;
9 |
10 | namespace Middleware
11 | {
12 | public class Program
13 | {
14 | public static void Main(string[] args)
15 | {
16 | CreateHostBuilder(args).Build().Run();
17 | }
18 |
19 | public static IHostBuilder CreateHostBuilder(string[] args) =>
20 | Host.CreateDefaultBuilder(args)
21 | .ConfigureWebHostDefaults(webBuilder =>
22 | {
23 | webBuilder.UseStartup();
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Middleware/Middleware/Middleware/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:57891",
7 | "sslPort": 44349
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "Middleware": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "applicationUrl": "https://localhost:5001;http://localhost:5000",
22 | "environmentVariables": {
23 | "ASPNETCORE_ENVIRONMENT": "Development"
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Middleware/Middleware/Middleware/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Builder;
6 | using Microsoft.AspNetCore.Hosting;
7 | using Microsoft.AspNetCore.Http;
8 | using Microsoft.Extensions.DependencyInjection;
9 | using Microsoft.Extensions.Hosting;
10 |
11 | namespace Middleware
12 | {
13 | public class Startup
14 | {
15 | public void ConfigureServices(IServiceCollection services)
16 | {
17 | services.AddTransient();
18 |
19 | services.AddHttpClient("name")
20 | .AddHttpMessageHandler() // 1st
21 | .AddHttpMessageHandler(); // 2nd
22 | }
23 |
24 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
25 | {
26 | if (env.IsDevelopment())
27 | {
28 | app.UseDeveloperExceptionPage();
29 | }
30 |
31 | app.UseRouting();
32 |
33 | app.UseMiddleware();
34 |
35 | app.Use((request) =>
36 | {
37 | //do something before request
38 | //no access to httpcontext
39 | return request;
40 | });
41 |
42 | app.Use(async (httpContext, function) =>
43 | {
44 | // do something before
45 | await function();
46 | // do something after
47 | });
48 |
49 | app.UseEndpoints(endpoints =>
50 | {
51 | endpoints.MapGet("/", async context =>
52 | {
53 | await context.Response.WriteAsync("Hello World!");
54 | });
55 | });
56 | }
57 | }
58 |
59 | public class CustomMiddleware
60 | {
61 | private readonly RequestDelegate _next;
62 |
63 | public CustomMiddleware(RequestDelegate next)
64 | {
65 | _next = next;
66 | }
67 |
68 | public async Task InvokeAsync(HttpContext context)
69 | {
70 | // do before
71 | await _next(context);
72 | // do after
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/Middleware/Middleware/Middleware/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Middleware/Middleware/Middleware/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "AllowedHosts": "*"
10 | }
11 |
--------------------------------------------------------------------------------
/Middleware/core_concept.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | Try(LambdaFirst);
6 |
7 | Wrap(LambdaSeccond);
8 | }
9 |
10 | public void First()
11 | {
12 | "executing first function".Dump();
13 | }
14 |
15 | public void Seccond()
16 | {
17 | "executing seccond function".Dump();
18 | }
19 |
20 | public void LambdaFirst(){
21 | Wrap(First);
22 | }
23 | public void LambdaSeccond()
24 | {
25 | Try(Seccond);
26 | }
27 |
28 | public void Wrap(Action function)
29 | {
30 | "start".Dump();
31 | function();
32 | "ends".Dump();
33 | }
34 |
35 | public void Try(Action function)
36 | {
37 | try
38 | {
39 | "trying".Dump();
40 | function();
41 | }
42 | catch (Exception)
43 | {
44 |
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Middleware/custom_middleware.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | var pipe = new PipeBuilder(First)
6 | .AddPipe(typeof(Try))
7 | .AddPipe(typeof(Wrap))
8 | .AddPipe(typeof(Wrap))
9 | .Build();
10 |
11 | pipe("Wrold");
12 |
13 | pipe("Another One");
14 | }
15 |
16 | public void First(string msg)
17 | {
18 | $"executing {msg}".Dump("first function");
19 | }
20 |
21 | public void Seccond(string msg)
22 | {
23 | $"executing {msg}".Dump("seccond function");
24 | }
25 |
26 | public class PipeBuilder
27 | {
28 | Action _mainAction;
29 | List _pipeTypes;
30 | public PipeBuilder(Action mainAction)
31 | {
32 | _mainAction = mainAction;
33 | _pipeTypes = new List();
34 | }
35 |
36 | public PipeBuilder AddPipe(Type pipeType)
37 | {
38 | _pipeTypes.Add(pipeType);
39 | return this;
40 | }
41 |
42 | private Action CreatePipe(int index){
43 | if(index < _pipeTypes.Count - 1){
44 | var childPipeHandle = CreatePipe(index + 1);
45 | var pipe = (Pipe) Activator.CreateInstance(_pipeTypes[index], childPipeHandle);
46 | return pipe.Handle;
47 | } else {
48 | var finalPipe = (Pipe) Activator.CreateInstance(_pipeTypes[index], _mainAction);
49 | return finalPipe.Handle;
50 | }
51 | }
52 |
53 | public Action Build(){
54 | return CreatePipe(0);
55 | }
56 | }
57 |
58 | public abstract class Pipe
59 | {
60 | protected Action _action;
61 | public Pipe(Action action)
62 | {
63 | _action = action;
64 | }
65 |
66 | public abstract void Handle(string msg);
67 | }
68 |
69 | public class Wrap : Pipe
70 | {
71 | public Wrap(Action action) : base(action) { }
72 |
73 | public override void Handle(string msg)
74 | {
75 | msg.Dump("starting");
76 | _action(msg);
77 | "ends".Dump();
78 | }
79 | }
80 |
81 | public class Try : Pipe
82 | {
83 | public Try(Action action) : base(action) { }
84 |
85 | public override void Handle(string msg)
86 | {
87 | try
88 | {
89 | msg.Dump("trying");
90 | _action(msg);
91 | }
92 | catch (Exception)
93 | {
94 |
95 | }
96 | }
97 | }
--------------------------------------------------------------------------------
/Middleware/linq_ladders.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | void Main()
4 | {
5 | Action pipe = (msg) =>
6 | Try2(msg, (msg1) =>
7 | Try(msg1, (msg2) =>
8 | Wrap(msg2, Seccond)));
9 |
10 | pipe("1");
11 | }
12 |
13 | public void First(string msg)
14 | {
15 | $"executing {msg}".Dump("first function");
16 | }
17 |
18 | public void Seccond(string msg)
19 | {
20 | $"executing {msg}".Dump("seccond function");
21 | }
22 |
23 | public void Wrap(string msg, Action function)
24 | {
25 | msg.Dump("starting");
26 | function(msg);
27 | "ends".Dump();
28 | }
29 |
30 | public void Try(string msg, Action function)
31 | {
32 | try
33 | {
34 | msg.Dump("trying");
35 | function(msg);
36 | }
37 | catch (Exception)
38 | {
39 |
40 | }
41 | }
42 |
43 | public void Try2(string msg, Action function)
44 | {
45 | try
46 | {
47 | msg.Dump("trying");
48 | function(msg);
49 | }
50 | catch (Exception)
51 | {
52 |
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Middleware/main.js:
--------------------------------------------------------------------------------
1 | pipes = []
2 |
3 | apiCall = function (req) {
4 | return "Hello " + req;
5 | }
6 |
7 | wrap = function (req, next) {
8 | console.log("start", req)
9 | var response = next(req);
10 | console.log("end", response)
11 | return response;
12 | }
13 |
14 | tryWrap = function (req, next) {
15 | console.log("trying", req)
16 | return next(req);
17 | }
18 |
19 | addPipe = function (pipe) {
20 | if (pipes.length === 0) {
21 | pipes.push((req) => pipe(req, apiCall))
22 | } else {
23 | let previousPipe = pipes[pipes.length - 1]
24 | pipes.push((req) => pipe(req, previousPipe))
25 | }
26 | }
27 |
28 | build = function () {
29 | return pipes[pipes.length - 1]
30 | }
31 |
32 | addPipe(tryWrap);
33 | addPipe(wrap);
34 |
35 | mainPipe = build()
36 |
37 | mainPipe("World")
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Raw Coding [Youtube](https://www.youtube.com/channel/UCP_jWxjn__YXmo4iU7Low0g?view_as=subscriber) Tutorials
2 | This repository is a collection of my one off tutorials about specific concepts.
3 |
4 | Full Playlist can be found [here](https://www.youtube.com/playlist?list=PLOeFnOV9YBa43HKvIhBUMK6UhSjP2kizx).
5 |
6 | ## Table of contents
7 | - [Middleware](https://youtu.be/xWWj0zGKS-k)
8 | - [Dependency Injection](https://youtu.be/NkTF_6IQPiY)
9 | - [Explaining Async Await Task](https://youtu.be/il9gl8MH17s)
10 | - [How to Use Async AWait Task](https://youtu.be/3GhKdDCvtKE)
11 | - [Semaphore](https://youtu.be/GKjM4AX8NME)
12 | - [Channels](https://youtu.be/E0Ld7ZgE4oY)
13 | - [MVC](https://youtu.be/u4O-b1BJg98)
14 | - [IEnumerable](https://youtu.be/at6weLnskpU)
15 | - [Reflection](https://youtu.be/cdG2JxuZvNI)
16 | - [Expression Trees](https://youtu.be/dwr40KytyaY)
17 | - [Delegates (+Func +Action +Closure)](https://youtu.be/KaxNwGA9fiY)
18 | - [Generics](https://youtu.be/Q1Tv7vj3Txo)
--------------------------------------------------------------------------------
/Reflection/Reflection.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30011.22
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApp", "WebApp\WebApp.csproj", "{FB323F04-C6AE-41C2-9047-934BB7C297D0}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {FB323F04-C6AE-41C2-9047-934BB7C297D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {FB323F04-C6AE-41C2-9047-934BB7C297D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {FB323F04-C6AE-41C2-9047-934BB7C297D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {FB323F04-C6AE-41C2-9047-934BB7C297D0}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {90DE1BA6-8E4D-4628-91DA-9A0665BD81EB}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/Reflection/WebApp/AuthHandler.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authorization;
2 | using Microsoft.AspNetCore.Mvc;
3 | using Microsoft.AspNetCore.Mvc.Controllers;
4 | using Microsoft.AspNetCore.Routing;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 |
10 | namespace WebApp
11 | {
12 | public class AutoGeneratedClaim : IAuthorizationRequirement
13 | {
14 | public AutoGeneratedClaim()
15 | {}
16 | }
17 |
18 | public class AuthHandler : AuthorizationHandler
19 | {
20 | protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AutoGeneratedClaim requirement)
21 | {
22 | var resource = context.Resource;
23 | if(resource is RouteEndpoint endpoint)
24 | {
25 | var metadata = endpoint.Metadata;
26 | var controllerAD = (ControllerActionDescriptor)
27 | metadata.FirstOrDefault(x => x is ControllerActionDescriptor);
28 |
29 | var controller = controllerAD.ControllerTypeInfo;
30 | var action = controllerAD.MethodInfo;
31 | var targetClaim = string.Concat(controller.ToString(), ".", action.ToString().Split(" ").Last());
32 |
33 | if(context.User.Claims.Any(x => x.Type.Equals(Constants.WebAppClaimType)
34 | && x.Value.Equals(targetClaim)))
35 | {
36 | context.Succeed(requirement);
37 | return Task.CompletedTask;
38 | }
39 | }
40 |
41 | context.Fail();
42 | return Task.CompletedTask;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Reflection/WebApp/ClaimsService.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authorization;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace WebApp
10 | {
11 | public class ClaimsService
12 | {
13 | public IEnumerable Claims()
14 | {
15 | var authAttr = typeof(AuthorizeAttribute);
16 | var anonAttr = typeof(AllowAnonymousAttribute);
17 |
18 | return typeof(Startup).Assembly.GetTypes()
19 | .Where(x => x.Name.EndsWith("Controller"))
20 | .SelectMany(x => x.GetMethods()
21 | .Where(m => m.DeclaringType.Equals(x)))
22 | .Where(x => x.GetCustomAttribute(authAttr) != null
23 | || x.DeclaringType.GetCustomAttribute(authAttr) != null)
24 | .Where(x => x.GetCustomAttribute(anonAttr) == null)
25 | .Select(x => string.Concat(x.DeclaringType.ToString(),
26 | ".", x.ToString().Split(" ").Last()));
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Reflection/WebApp/Constants.cs:
--------------------------------------------------------------------------------
1 | namespace WebApp
2 | {
3 | public class Constants
4 | {
5 | public const string WebAppClaimType = nameof(WebAppClaimType);
6 | }
7 | }
--------------------------------------------------------------------------------
/Reflection/WebApp/Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authentication;
2 | using Microsoft.AspNetCore.Authorization;
3 | using Microsoft.AspNetCore.Mvc;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Security.Claims;
7 | using System.Threading.Tasks;
8 |
9 | namespace WebApp.Controllers
10 | {
11 | public class HomeController : Controller
12 | {
13 | public string Index()
14 | {
15 | return "";
16 | }
17 |
18 | [HttpGet]
19 | public IActionResult SignIn([FromServices] ClaimsService claimsService)
20 | {
21 | return View(claimsService.Claims());
22 | }
23 |
24 | [HttpPost]
25 | public async Task SignIn(IEnumerable claims)
26 | {
27 | var identity = new ClaimsIdentity(claims.Select(x => new Claim(Constants.WebAppClaimType, x)), "Identity");
28 | var principal = new ClaimsPrincipal(identity);
29 | await HttpContext.SignInAsync(principal);
30 |
31 | return RedirectToAction("Index");
32 | }
33 |
34 | [Authorize]
35 | public string Secret()
36 | {
37 | return "";
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Reflection/WebApp/Controllers/ManageController.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authorization;
2 | using Microsoft.AspNetCore.Mvc;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace WebApp.Controllers
10 | {
11 | [Authorize]
12 | public class ManageController : Controller
13 | {
14 | [HttpGet()]
15 | public string Secure()
16 | {
17 | return "";
18 | }
19 |
20 | [HttpGet("{boi}")]
21 | public string Secure(string boi)
22 | {
23 | return "";
24 | }
25 |
26 | public string Secret()
27 | {
28 | return "";
29 | }
30 |
31 | [AllowAnonymous]
32 | public string Allowed()
33 | {
34 | return "";
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Reflection/WebApp/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Hosting;
6 | using Microsoft.Extensions.Configuration;
7 | using Microsoft.Extensions.Hosting;
8 | using Microsoft.Extensions.Logging;
9 |
10 | namespace WebApp
11 | {
12 | public class Program
13 | {
14 | public static void Main(string[] args)
15 | {
16 | CreateHostBuilder(args).Build().Run();
17 | }
18 |
19 | public static IHostBuilder CreateHostBuilder(string[] args) =>
20 | Host.CreateDefaultBuilder(args)
21 | .ConfigureWebHostDefaults(webBuilder =>
22 | {
23 | webBuilder.UseStartup();
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Reflection/WebApp/Startup.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authorization;
2 | using Microsoft.AspNetCore.Builder;
3 | using Microsoft.AspNetCore.Hosting;
4 | using Microsoft.AspNetCore.Identity;
5 | using Microsoft.Extensions.Configuration;
6 | using Microsoft.Extensions.DependencyInjection;
7 | using Microsoft.Extensions.Hosting;
8 |
9 | namespace WebApp
10 | {
11 | public class Startup
12 | {
13 | public Startup(IConfiguration configuration)
14 | {
15 | Configuration = configuration;
16 | }
17 |
18 | public IConfiguration Configuration { get; }
19 |
20 | public void ConfigureServices(IServiceCollection services)
21 | {
22 | services.AddAuthentication("Cookie")
23 | .AddCookie("Cookie");
24 |
25 | services.AddAuthorization(config =>
26 | {
27 | var policyBuilder = new AuthorizationPolicyBuilder();
28 |
29 | config.DefaultPolicy = policyBuilder
30 | .AddRequirements(new AutoGeneratedClaim())
31 | .Build();
32 | });
33 |
34 | services.AddScoped();
35 |
36 | services.AddSingleton();
37 |
38 | services.AddControllersWithViews();
39 | }
40 |
41 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
42 | {
43 | if (env.IsDevelopment())
44 | {
45 | app.UseDeveloperExceptionPage();
46 | }
47 | else
48 | {
49 | app.UseExceptionHandler("/Error");
50 |
51 | app.UseHsts();
52 | }
53 |
54 | app.UseHttpsRedirection();
55 | app.UseStaticFiles();
56 |
57 | app.UseRouting();
58 |
59 | app.UseAuthentication();
60 | app.UseAuthorization();
61 |
62 | app.UseEndpoints(endpoints =>
63 | {
64 | endpoints.MapDefaultControllerRoute();
65 | });
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Reflection/WebApp/Views/Home/SignIn.cshtml:
--------------------------------------------------------------------------------
1 | @model IEnumerable
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Reflection/WebApp/WebApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Reflection/WebApp/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Reflection/WebApp/wwwroot/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/T0shik/raw-coding-101-tutorials/af525fa6dc50d43dc96d75f0650bac5fd7b18194/Reflection/WebApp/wwwroot/favicon.ico
--------------------------------------------------------------------------------
/Semaphore/save_the_client.linq:
--------------------------------------------------------------------------------
1 |
2 | System.Net.Http
3 | System.Threading.Tasks
4 |
5 |
6 | HttpClient _client = new HttpClient
7 | {
8 | Timeout = TimeSpan.FromSeconds(5)
9 | };
10 | SemaphoreSlim _gate = new SemaphoreSlim(20);
11 |
12 | void Main()
13 | {
14 | Task.WaitAll(CreateCalls().ToArray());
15 | }
16 |
17 | public IEnumerable CreateCalls()
18 | {
19 | for (int i = 0; i < 500; i++)
20 | {
21 | yield return CallGoogle();
22 | }
23 | }
24 |
25 |
26 | public async Task CallGoogle()
27 | {
28 | try
29 | {
30 | await _gate.WaitAsync();
31 | var response = await _client.GetAsync("https://google.com");
32 | _gate.Release();
33 |
34 | response.StatusCode.Dump();
35 | }
36 | catch (Exception e)
37 | {
38 | e.Message.Dump();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Semaphore/the_gate.linq:
--------------------------------------------------------------------------------
1 |
2 | System.Threading.Tasks
3 |
4 |
5 | SemaphoreSlim gate = new SemaphoreSlim(1);
6 |
7 | async Task Main()
8 | {
9 | for (int i = 0; i < 10; i++)
10 | {
11 | "Start".Dump();
12 | await gate.WaitAsync();
13 | "Do Some Work".Dump();
14 | gate.Release();
15 | "Finish".Dump();
16 | }
17 | }
--------------------------------------------------------------------------------