{ADCES] Discutii si Networking
Timp de discutii / networking / profesional / neprofesional.
https://www.meetup.com/bucharest-a-d-c-e-s-meetup/events/298422520/
Va invitam pe toti
Șoseaua Grozăvești 82 · București
Timp de discutii / networking / profesional / neprofesional.
https://www.meetup.com/bucharest-a-d-c-e-s-meetup/events/298422520/
Va invitam pe toti
Șoseaua Grozăvești 82 · București
Visitor pattern is a way of separating an algorithm from an object structure on which it operates. A practical result of this separation is the ability to add new operations to existing object structures without modifying the structures.
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Visitor; internal class VisitorDemo { public static void VisitMethods() { var Code = @""" using System; namespace Test1 { class Program { static void Main(string[] args) { var dt=DateTime.Now; Console.WriteLine(dt); } } } """; var tree = CSharpSyntaxTree.ParseText(Code); var node = tree.GetRoot(); MethodVisiting LG = new MethodVisiting(); //start visiting var sn = LG.Visit(node); } } public class MethodVisiting : CSharpSyntaxRewriter { public override SyntaxNode? VisitMethodDeclaration(MethodDeclarationSyntax node) { if (node.Body == null || node.Body.Statements.Count == 0) return base.VisitMethodDeclaration(node); var parent = node.Parent as ClassDeclarationSyntax; if (parent == null) return base.VisitMethodDeclaration(node); var nameMethod = node.Identifier.Text; var nameClass = parent.Identifier.Text; Console.WriteLine($"visiting {nameMethod} from {nameClass}"); return base.VisitMethodDeclaration(node); } }
Implement a visitor that will allow you to calculate the total price of a shopping cart. The shopping cart should contain items with a price and a quantity.Visit every item and make the sum
Adapter design pattern allows the interface of an existing class to be used as another interface.It is often used to make existing classes work with others without modifying their source code.
namespace Adaptor; internal class SQLiteDataAdapterDemo { /// <summary> ///Adaptee - Command ///Target - DataTable ///Adapter - SqlDataAdapter ///Target Method - Fill(Dataset instance) /// </summary> /// <returns></returns> public static async Task MainSqliteAdapterAsync() { var dataFormats = new DataTable(); Console.WriteLine(dataFormats.Rows.Count); Console.WriteLine(dataFormats.Columns.Count); using (var con = new SQLiteConnection()) { con.ConnectionString = "Data Source=CatalogRo.sqlite3"; await con.OpenAsync(); using (var cmd = new SQLiteCommand()) { cmd.CommandText = "select * from Format"; cmd.Connection = con; using (var adapt = new SQLiteDataAdapter(cmd)) { adapt.Fill(dataFormats); } } } Console.WriteLine(dataFormats.Rows.Count); Console.WriteLine(dataFormats.Columns.Count); } }
namespace Adaptor; internal class EncodingAdapterDemo { /// <summary> ///Adaptee - string ///Target - bytes ///Adapter - encoding ///Target Method - GetBytes /// </summary> public static void AdapterStringByte() { var url = "http://msprogrammer.serviciipeweb.ro"; Encoding e = new ASCIIEncoding(); var b = e.GetBytes(url); Console.WriteLine($"from {e.EncodingName} number bytes {b.Length}"); e = new UTF32Encoding(); b = e.GetBytes(url); Console.WriteLine($"from {e.EncodingName} number bytes {b.Length}"); } }
iPhone 7 does not have a headphone jack. Implement an adapter that will allow you to use your old headphones , that have jack, with the iPhone 7.
The intent of the Builder design pattern is to separate the construction of a complex object from its representation
namespace Builder; static class UriBuilderDemo { public static void UriMod() { //start example 1 var uri = new Uri("https://msprogrammer.serviciipeweb.ro/category/friday-links/"); var b = new UriBuilder(uri); //changing part b.Scheme = "http"; //now we have http://msprogrammer.serviciipeweb.ro/category/friday-links/ Console.WriteLine(b.Uri); //changing part b.Path = "2018/03/05/design-patterns-class/"; //now we have http://msprogrammer.serviciipeweb.ro/2018/03/05/design-patterns-class/ Console.WriteLine(b.Uri); //end example 1 } }
namespace Builder; internal class ConnectionStringDemo { public static void ConnectionString() { //start example 2 var build = new SqlConnectionStringBuilder(); build.DataSource = "."; build.InitialCatalog = "MyDatabase"; build.ConnectTimeout = 30; //here is the connection string built Console.WriteLine(build.ConnectionString); //end example 2 } }
Imagine that you have a logger that logs to a file and to a console. Implement a builder that will allow you to create a logger with different configurations. For example, you can set the log level, the log format, and the log destination.
Iterator design pattern allows to traverse a container and access the container’s elements.
namespace Iterator; internal class DirectoryEnumerableDemo { public static void DirectoryEnumerableFiles(int nrMaxFiles) { var count = 0; //what if we called Directory.GetFiles foreach (var file in Directory.EnumerateFiles(@"c:\","*.*",SearchOption.AllDirectories)) { count++; if (count > nrMaxFiles) break; Console.WriteLine(file); } } }
With the Yield keyword implement a function that return an IEnumerable of generic int that will return the first 10 numbers of the Fibonacci sequence
Instead of returning null , use an object which implements the expected interface, but whose method body is empty.
using System; using System.IO; namespace NullObject; internal class EmptyFolderDemo { public static void DemoWithCreateNewFolder() { //start example 1 var env = Environment.CurrentDirectory; var guid = Guid.NewGuid().ToString("X"); var fldEmpty = Path.Combine(env, guid); //create empty folder Directory.CreateDirectory(fldEmpty); var files= Directory.GetFiles(fldEmpty); Console.WriteLine($"files.Length:{files.Length}"); //end example 1 } }
namespace NullObject; internal class LogWithData { ILogger _logger; public LogWithData(ILogger? logger=null) { _logger = logger ?? NullLogger.Instance; } public void DoWork(string message) { _logger.LogInformation($"start work with {message}"); } }
When retrieving data( e.g. a Person with ID =-1 ) from a database , return a NullObject instead of null. How you will verify that the object is a NullObject?
ID | Name |
---|---|
1 | Part 1 |
2 | Part 2 |
3 | Part 3 |
I did not have the opportunity to migrate from a database from another . But seems to me that , when using EF, the principal problem will be the stored procedures, not the code that EF ( and providers) are generating automatically. Yes, there are some problems ( see part 1 and part 2) , but those seems not so important and easy to solve.
ID | Name |
---|---|
1 | Part 1 |
2 | Part 2 |
3 | Part 3 |
I have started with a simple table – Department( id autogenerated , name) and generate EFCore context and classes with scaffolding templates https://learn.microsoft.com/en-us/ef/core/managing-schemas/scaffolding/templates?tabs=dotnet-core-cli .
Then I have created a simple text ( XUnit + LightBDD ) in order to test
– generateDatabase from classes
– CRUD
– some simple search .
Works perfectly, so to the next – more different tables ( datetime, binary, money and so on) => scaffold code => make tests.
When generating the scaffolding the OnModelCreating generates .HasColumnType – for example,
modelBuilder.Entity<Tbl_DATETIME>(entity => { entity.HasKey(e => e.ID).HasName("PK__Tbl_DATE__3214EC27B76F5021"); entity.Property(e => e.DataColumn).HasColumnType("datetime"); });
And PostgresSql has no type that is called “datetime”, but “timestamp” – https://www.postgresql.org/docs/current/datatype-datetime.html
So what I do is to have OnModelCreatingPartial that is called AFTER all set and re-write
modelBuilder.Entity<Tbl_DATETIME>(entity => { entity.HasKey(e => e.ID).HasName("PK__Tbl_DATE__3214EC27B76F5021"); entity.Property(e => e.DataColumn).HasColumnType(null); });
Even if column type is null, the CreateDatabase knows that the field is DateTime
public partial class Tbl_DATETIME { public int ID { get; set; } public DateTime? DataColumn { get; set; } }
so all is ok.
The DateTime that is on the class generates a column that supports ONLY UTC kind in datetimes . The error is
–> System.InvalidCastException : Cannot write DateTime with Kind=Local to PostgreSQL type ‘timestamp with time zone’, only UTC is supported. Note that it’s not possible to mix DateTimes with different Kinds in an array/range. See the Npgsql.EnableLegacyTimestampBehavior AppContext switch to enable legacy behavior.
Youn
Makes sense, usual in database you want just the UTC and transform for each user
This is the test:
var dataM = new Tbl_DATETIME(); dataM.ID = 3; dataM.DataColumn = DateTime.Now.AddDays(100); using (var db = await startDatabase.GetNewContext<SimpleTablesMultipleData>()) { await db.Tbl_DATETIMEModify(dataM); } using (var db = await startDatabase.GetNewContext<SimpleTablesMultipleData>()) { var verify = await db.Tbl_DATETIMEGetSingle(dataM.ID); verify.Should().NotBeNull(); verify!.DataColumn!.Should().NotBeNull(); verify!.DataColumn.Should().Be(dataM.DataColumn); }
And the error is
Xunit.Sdk.XunitException : Expected verify!.DataColumn to be <2023-12-13 21:45:39.6089917>, but found <2023-12-13 21:45:39.608991>.
You can see the Ok tests at https://ignatandrei.github.io/TestEFCoreDatabaseProviders/
And the problems at https://ignatandrei.github.io/TestEFCoreDatabaseProviders/problems.html