Skip to content

Instantly share code, notes, and snippets.

View Thorium's full-sized avatar

Tuomas Hietanen Thorium

View GitHub Profile
@Thorium
Thorium / dev.md
Last active November 19, 2024 09:43

Guidance for .NET systems development

Here is some opinionated guidance maybe to save some part of your valuable lifetime. The following topics focus on: development, architecture and maintainability.

The primary advice after John Skeet: Just solve your issue in the simplest possible way. Limit the boundaries: what are the requirements? Don't try to solve meta-level problems of every software engineer ever. Draft the boundaries even if you're writing a general library: Users can compose multiple small libraries if necessary. Expect your requirement specifications, if any, could be better, that's life.

@Thorium
Thorium / textmagic.fs
Created July 2, 2024 09:46
Send text messages with F# (FSharp)
[<RequireQualifiedAccess>]
module TextMagic
//https://www.textmagic.com/docs/api/send-sms/
// #r "System.Text.Json"
// #r "FSharp.Data"
open System
open System.IO
open System.Net
open System.Text.Json
@Thorium
Thorium / ef-functional.cs
Last active July 1, 2024 09:40
DBContext independend LINQ, the functional way
/// Old post recovered from Feb 2013:
/// https://web.archive.org/web/20130510043355/social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/bc0bd8f3-0e49-440c-b0bb-8d9adb593934
///
/// This shows how you can:
///
/// - Code from top-down, give high level picture first and then go to details
/// - Define LINQ outside EF-context and still convert it to SQL: Don't hammer the database!
/// - Have small independend classes (/parts)
/// - Have state-less code with no global/class-variables outside entities
/// - Easy to test: a) Integration test with EF-DbContext.
@Thorium
Thorium / AbstractProject.fs
Last active February 16, 2024 15:23
Use (or replace) existing Logary via Microsoft.Extensions.Logging.Abstractions. This can be used to abstract Logary behind Microsoft.Extensions.Logging so it's easier to remove from existing infra (or migrate to, whatever).
// This expects you have 2 projects, this first one has dependendency only to Microsoft.Extensions.Logging.Abstractions
// (and temporarily usage of Microsoft.Extensions.Logging.Console ).
module AbstractProject
let loggerFactory =
Microsoft.Extensions.Logging.LoggerFactory.Create(fun builder ->
let _ = Microsoft.Extensions.Logging.ConsoleLoggerExtensions.AddSimpleConsole builder
())
/// This is ILogger.
@Thorium
Thorium / readJson.fsx
Created November 16, 2023 23:12
Using Utf8JsonReader from System.Text.Json with FSharp
//High-performance JSON parsing with System.Text.Json and F#
// Example translated to F# from
// https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/use-utf8jsonreader
#r "nuget:System.Text.Json"
open System
open System.Text
open System.Text.Json
let options = JsonReaderOptions(
@Thorium
Thorium / bindingredirects.fsx
Last active February 14, 2023 13:46
Parse bindingRedirects with Linq2Xml
// Find binding-redirects with linq-to-xml from a .config file.
// This might be useful for then parsing config-changes e.g. by System.Linq.Enumerable.Except
#r @"System.Xml.Linq.dll"
open System.Xml.Linq
let parseBindingRedirects (filename:string) =
let xn s = XName.Get(s,"urn:schemas-microsoft-com:asm.v1")
let xml = XDocument.Load filename
let depAssemblies = xml.Descendants(xn "dependentAssembly")
seq {
@Thorium
Thorium / tiktok.ts
Created April 7, 2022 17:10
TikTok Pixel tag valid TypeScript / JavaScript
function tiktokTag() {
try {
window.TiktokAnalyticsObject = 'ttq';
var ttq = window.ttq = window.ttq || [];
ttq.methods = ["page", "track", "identify", "instances", "debug", "on", "off", "once", "ready", "alias", "group", "enableCookie", "disableCookie"];
ttq.setAndDefer = function(t, e) {
t[e] = function() {
t.push([e].concat(Array.prototype.slice.call(arguments, 0)))
}
};
@Thorium
Thorium / MapTools.fsx
Created February 7, 2022 19:12
KML / Google Maps / Oculus Wander
/// Set of little F# (FSharp) functions as script tools to work with
/// - KML files (Keyhole Markup Language) used by Google Earth and Google Maps
/// - Google Maps Streetview API,
/// - Oculus Wander Application (by Parkline Interactive, LLC) bookmarks: Wander_Favorites.json
/// You have to first set your Google API key to environment variables as api-key and enable
/// Streetview API for that
// System.Environment.SetEnvironmentVariable("api-key", "...")
#r "nuget: FSharp.Data"
@Thorium
Thorium / Emojis.fs
Created June 3, 2020 15:04
Coding with Emojis
// In Windows you can press WindowsKey+"." to open Emoji menu.
let ``🍕`` = "🥓" + "🍍"
//val ( 🍕 ) : string = "🥓🍍"
@Thorium
Thorium / myvisitor.fs
Created November 8, 2019 14:11
F# LINQ-Expression-tree visitor
// A simple expression tree visitor, to inject a lambda inside another lambda parameters.
open Microsoft.FSharp.Linq.RuntimeHelpers
open System
open System.Linq.Expressions
//F#-helper method for Linq.Expressions: fssnip.net/ts/title/F-lambda-to-C-LINQ-Expression
module Lambda =
let toExpression (``f# lambda`` : Quotations.Expr<'a>) =
``f# lambda``
|> LeafExpressionConverter.QuotationToExpression