C# etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
C# etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

1 Kasım 2023

Rosyln Compiler - Memory Leak Free(Disposable)

Original Article: https://carljohansen.wordpress.com/2020/05/09/compiling-expression-trees-with-roslyn-without-memory-leaks-2/

I register handlebars helper for my codes that could be editable from text file.

Aim: Invoke public methods with TemplateHelper attribute.

Example Text File that contains C# Code:


using HandlebarsDotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RosylnCompilerDemo
{
    public class DigitalInsertHandlebarsHelpers
    {
        [TemplateHelper]
        public void RegisterPriceWhole(IHandlebars _handlebars)
        {
            _handlebars.RegisterHelper("Price.Whole", (writer, context, arguments) =>
            {
                if (!arguments.Any())
                {
                    throw new HandlebarsException("Correct Format: {{#Price.Whole decimalPrice seperator}}, {{Price.Whole decimalPrice}}");
                }
                var price = arguments.At<string>(0);
                if (!string.IsNullOrWhiteSpace(price))
                {
                    string seperator = ",";
                    if (arguments.Length == 2)
                    {
                        seperator = arguments.At<string>(1);
                    }
                    price = price.Split(seperator).FirstOrDefault();
                }
                writer.WriteSafeString($"{price}");
            });
        }

        [TemplateHelper]
        public void RegisterPriceFraction(IHandlebars _handlebars)
        {
            _handlebars.RegisterHelper("Price.Fraction", (writer, context, arguments) =>
            {
                if (!arguments.Any())
                {
                    throw new HandlebarsException("Correct Format: {{#Price.Fraction decimalPrice seperator}}, {{Price.Whole decimalPrice}}");
                }
                var price = arguments.At<string>(0);
                if (!string.IsNullOrWhiteSpace(price))
                {
                    string seperator = ",";
                    if (arguments.Length == 2)
                    {
                        seperator = arguments.At<string>(1);
                    }
                    price = price.Split(seperator).LastOrDefault();
                }
                writer.WriteSafeString($"{price}");
            });
        }
    }
}





Code File:

using HandlebarsDotNet;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Reflection;
using System.Runtime.Loader;

namespace RosylnCompilerDemo
{
    public class TemplateHelperOperations
    {
        private class CollectibleAssemblyLoadContext : AssemblyLoadContext, IDisposable
        {
            public CollectibleAssemblyLoadContext() : base(true)
            { }

            protected override Assembly Load(AssemblyName assemblyName)
            {
                return null;
            }

            public void Dispose()
            {
                Unload();
            }
        }

        public static void RegisterHelpers(string code, IHandlebars handlebars)
        {
            var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);

            List<Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();

            var references = assemblies.Where(q => !string.IsNullOrWhiteSpace(q.Location))
                .Select(q => MetadataReference.CreateFromFile(q.Location)).ToList();

            var syntaxTree = SyntaxFactory.ParseSyntaxTree(code);
            var assemblyName = $"TempAssembly{Guid.NewGuid()}";
            var compilation = CSharpCompilation.Create(assemblyName)
                                .WithOptions(compilationOptions)
                                .AddReferences(references)
                                .AddSyntaxTrees(syntaxTree);


            using (var assemblyLoadContext = new CollectibleAssemblyLoadContext())
            using (var ms = new MemoryStream())
            {
                var emitResult = compilation.Emit(ms);
                if (emitResult.Success)
                {
                    ms.Seek(0, SeekOrigin.Begin);

                    // Load the compiled assembly
                    var assembly = Assembly.Load(ms.ToArray());

                    // Execute the library code
                    var helperMethods = assembly.GetTypes()
                        .Where(q => q.IsClass && q.IsPublic)
                        .Select(q => new { ClassName = q.FullName, Methods = q.GetMethods().Where(m => m.IsPublic && m.GetCustomAttributes(typeof(TemplateHelperAttribute), false).FirstOrDefault() != null) })
                        .Where(q => q?.Methods?.Any() ?? false)
                        .ToList();


                    foreach (var cls in helperMethods.Where(q => q.Methods?.Any() ?? false).GroupBy(q => q.ClassName))
                    {
                        if (!string.IsNullOrWhiteSpace(cls.Key))
                        {
                            var libClassType = assembly.GetType(cls.Key);
                            var libraryInstance = Activator.CreateInstance(libClassType);
                            foreach (var item in cls)
                            {
                                foreach (var method in item.Methods)
                                {
                                    method.Invoke(libraryInstance, new object[] { handlebars });
                                }
                            }
                        }
                    }
                }
                else
                {
                    foreach (var diagnostic in emitResult.Diagnostics)
                    {
                        Console.WriteLine(diagnostic.ToString());
                    }
                }
            }
        }
    }

}

24 Mart 2022

SignedString Sınıfı

 Dışarıya açık dosya paylaşmada URL i zaman bazlı kısıtlamak için oluşturulmuş kod parçaları.

EncryptTool.cs

using System;

using System.Security.Cryptography;

using System.Text;


namespace SampleSigner

{

    public static class EncryptTool 

    {

        public static byte[] EncryptSha5126(string plainText)

        {

            if (string.IsNullOrEmpty(plainText))

            {

                throw new ArgumentNullException(nameof(plainText));


            }

            using (var sha = SHA512.Create())

                return sha.ComputeHash(Encoding.UTF8.GetBytes(plainText));

        }


        /// <summary>

        /// 

        /// </summary>

        /// <param name="plainText"> Not Null</param>

        /// <param name="key">byte[64] random bytes</param>

        /// <returns></returns>

        public static byte[] HmacSha256(string plainText, byte[] key)

        {

            if (key == null)

                throw new ArgumentNullException(nameof(key));

            if (key.Length != 64)

                throw new ArgumentException("key.length must be 64");

            if (string.IsNullOrEmpty(plainText))

                throw new ArgumentNullException(nameof(plainText));


            using (HMACSHA256 hmac = new HMACSHA256(key))

            {

                return hmac.ComputeHash(Encoding.UTF8.GetBytes(plainText));

            }

        } 

    }

}



// SignedStringSettings.cs

using System;

namespace SampleSigner
{
    public class SignedStringSettings
    {
        /// <summary>
        /// Key olarak proje her başlatıldığında key değişsin diye dinamik guid üretilmiştir.
        /// İsteyen gömülü key kullanabilir. 
        /// Ben dosya paylaşım süresini uzun tutmayacağım için Guid benim için sorun değil
        /// </summary>
        private SignedStringSettings()
            :this(Guid.NewGuid().ToString())
        {

        }
        private SignedStringSettings(string key)
        {
            var bytes = EncryptTool.EncryptSha5126(key);
            byte[] data = new byte[64];
            Array.Copy(bytes, 0, data, 0, 64);
            Key = data;
        }

        public static readonly Lazy<SignedStringSettings> _instance
            = new Lazy<SignedStringSettings>(() => new SignedStringSettings());

        public static SignedStringSettings Instance => _instance.Value;

        public byte[] Key { get; private set; }

    }
}


// SignedString.cs

using System;
using System.Security.Cryptography;
using System.Text;

namespace SampleSigner
{
    public class SignedString
    {
        private string _text { get; set; }
        private long _validUntil { get; set; }

        private SignedString(string text, DateTimeOffset validUntil)
        {
            _validUntil = validUntil.ToUnixTimeSeconds();
            _text = Sign(text, _validUntil);
        }

        private SignedString(string text)
        {
            _text = text;
        }



        public static SignedString CreateNew(string text, DateTimeOffset to)
        {
            return new SignedString(text, to);
        }
        public static SignedString CreateNew(string text, TimeSpan time)
        {
            return new SignedString(text, DateTimeOffset.UtcNow.Add(time));
        }

        public static SignedString Load(string text)
        {
            return new SignedString(text);
        }



        private string Sign(string text, long validUntil)
        {
            var plainText = Convert.ToBase64String(Encoding.UTF8.GetBytes(text));
            plainText += $".{validUntil}";
            var computedHash = EncryptTool.HmacSha256(plainText, SignedStringSettings.Instance.Key);
            return $"{plainText}.{Convert.ToBase64String(computedHash)}";
        }

        private bool Verify(string signedText, byte[] key)
        {
            if (string.IsNullOrWhiteSpace(signedText))
                throw new ArgumentNullException(nameof(signedText));

            var parts = signedText.Split('.');

            if (parts.Length != 3
                || string.IsNullOrWhiteSpace(parts[0])
                || string.IsNullOrWhiteSpace(parts[1])
                || string.IsNullOrWhiteSpace(parts[2]))
                throw new ArgumentException("Invalid String");

            
           

            byte[] computedBytes = null;
            using (HMACSHA256 hmac = new HMACSHA256(key))
            {
                var checkText = signedText.Substring(0, signedText.LastIndexOf("."));
                computedBytes = EncryptTool.HmacSha256(checkText, SignedStringSettings.Instance.Key);
            }
            var signBytes = Convert.FromBase64String(parts[2]);

            if (computedBytes == null
                || (computedBytes.Length != signBytes.Length))
                return false;

            for (int i = 0; i < computedBytes.Length; i++)
            {
                if (computedBytes[i] != signBytes[i])
                {
                    return false;
                };
            }
            var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
            var until = Convert.ToInt64(parts[1]);

            return now < until;
        }

        public override string ToString()
        {
            return _text;
        }

        public bool IsValid => Verify(_text, SignedStringSettings.Instance.Key);

        public string ToUnsignedString()
        {
            if (IsValid)
            {
                var parts = _text.Split(".");
                var byteText = Convert.FromBase64String(parts[0]);
                return Encoding.UTF8.GetString(byteText);
            }
            else return string.Empty;
        }
    }
}

// Program.cs

using System;
using System.Threading;

namespace SampleSigner
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var plainUrl = "https://www.muharrembarkin.com/";
            var sample = SignedString.CreateNew(plainUrl, TimeSpan.FromSeconds(5));
            // Url is valid 5 seconds
            var signedUrl = sample.ToString();
            Console.WriteLine($"Signed Url: {sample}");

            Console.WriteLine();

            //  1 second later  valid
            Thread.Sleep(1000);
            var sample2 = SignedString.Load(signedUrl);
            Console.WriteLine($"Is Valid after 1 seconds: {sample2.IsValid}");
            Console.WriteLine();
            Console.WriteLine("1 Second later Unsigned Url: " + sample2.ToUnsignedString());
            Console.WriteLine();
            //  6 second later not valid
            Thread.Sleep(5000);
            Console.WriteLine($"Is Valid after 6 seconds: {sample2.IsValid}");
            Console.WriteLine();
            Console.WriteLine("6 Second later Unsigned Url: " + sample2.ToUnsignedString());

            Console.WriteLine();
            var sample3 = SignedString.CreateNew(plainUrl, TimeSpan.FromSeconds(30));
            Console.WriteLine($"Signed Url: {sample3}");
            Console.WriteLine();
            Console.WriteLine("lets change one character of signed url");
            var signedUrl2 = sample3.ToString();
            signedUrl2 = signedUrl2.Substring(0, signedUrl2.Length - 1) + "a";
            Console.WriteLine("Changed Url: " + signedUrl2);
            Console.WriteLine();
            var sample4 = SignedString.Load(signedUrl2);
            Console.WriteLine($"Is valid changed url: {sample4.IsValid}");
            Console.WriteLine();
            Console.WriteLine($"UnsignedString changed url: {sample4.ToUnsignedString()}");
            Console.WriteLine();
            Console.WriteLine("Re test original url");
            var sample5 = SignedString.Load(sample3.ToString());
            Console.WriteLine($"IsValid: {sample5.IsValid}");
            Console.WriteLine($"UnsignedString: {sample5.ToUnsignedString()}");

        }
    }
}

21 Ekim 2019

C# ISO Oluşturma

DiscUtils
using DiscUtils.Iso9660;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace FileCount
{
    class Program
    {
        static void Main(string[] args)
        {
            string directoryPath = @"D:\test\";
            CreateIso("test", @"C:\Users\developer\Desktop\test.iso", directoryPath, new string[] { directoryPath });
            Console.ReadKey();
        }

        public static List<string> GetAllFiles(string directoryPath)
        {
            var result = new List<string>();
            if (Directory.Exists(directoryPath))
            {
                result.AddRange(Directory.GetFiles(directoryPath));
                foreach (var dir in Directory.GetDirectories(directoryPath))
                {
                    result.AddRange(GetAllFiles(dir));
                }
            }
            return result;
        }
        static string GetSubName(string rootDirectory, string path)
        {
            if (!path.StartsWith(rootDirectory))
                new ArgumentException("Given parameters are not in same root directory!");
            var output = path.Substring(rootDirectory.Length);
            if (output[0] == '\\')
                output = output.Substring(1);
            return output;
        }
        static void CreateIso(string volumeIdentifier, string output, string rootDirectory, string[] paths)
        {
            var builder = new CDBuilder();
            builder.UseJoliet = true;
            builder.VolumeIdentifier = volumeIdentifier;
            if (!Directory.Exists(rootDirectory))
                throw new DirectoryNotFoundException("The directory not found: " + rootDirectory);

            if (!paths.All(q => q.StartsWith(rootDirectory)))
                new ArgumentException("Given parameters are not in same root directory!");
            var files = new List<string>();
            foreach (var path in paths)
            {
                var fileAttr = File.GetAttributes(path);
                if (fileAttr.HasFlag(FileAttributes.Directory))

                    files.AddRange(GetAllFiles(path));
                else files.Add(path);
            }
            foreach (var file in files.Distinct())
            {
                builder.AddFile(GetSubName(rootDirectory, file), File.ReadAllBytes(file));
            }
            builder.Build(output);
        }
        
    }
}

1 Ağustos 2019

Memory Mapped Files in .NET

Non-Persisted Memory Mapped Files


using System;
using System.IO.MemoryMappedFiles;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
       
            using (MemoryMappedFile memoryMappedFile = MemoryMappedFile.CreateNew("idg.txt", 5))
            {
                using (MemoryMappedViewAccessor memoryMappedViewAccessor = memoryMappedFile.CreateViewAccessor())
                {
                    memoryMappedViewAccessor.Write(0,1);
                    Console.ReadKey();

                    memoryMappedViewAccessor.Dispose();

                    memoryMappedFile.Dispose();
                }
            }

        }
    }
}

using System;
using System.IO.MemoryMappedFiles;
using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var x = 0;

            using (MemoryMappedFile memoryMappedFile = MemoryMappedFile.OpenExisting("idg.txt"))
            using (MemoryMappedViewAccessor memoryMappedViewAccessor = memoryMappedFile.CreateViewAccessor())
            {
                while (true)
                {
                    var t = memoryMappedViewAccessor.ReadInt32(0);
                    if (x != t)
                    {
                        x = t;
                        Console.WriteLine(t);
                    }
                    Thread.Sleep(1);
                }
            }
        }
    }
}
Kaynak:
https://www.infoworld.com/article/2898365/working-with-memory-mapped-files-in-net.html
https://www.buraksenyurt.com/post/Persisted-Memory-Mapped-Files
https://docs.microsoft.com/tr-tr/dotnet/standard/io/memory-mapped-files

28 Mart 2019

C# String Compress and Uncompress

using System;
using System.IO;
using System.IO.Compression;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {

        static void Main(string[] args)
        {
            var xmlContent = File.ReadAllText("CompressExample.txt");
            Console.WriteLine($"Plain XML Text Size {xmlContent.Length}");
            var compressedText = xmlContent.Zip();
            Console.WriteLine($"Plain XML Text Size {compressedText.Length}");
            Console.WriteLine($"Uncompressed == Plain {compressedText.Unzip() == xmlContent}");
            Console.ReadKey();

        }

    }
    public static class StringExtensions
    {
        public static string Zip(this string str)
        {
            var bytes = Encoding.UTF8.GetBytes(str);
            var compressedBytes = ComporessionUtils.Zip(bytes);
            var base64 = Convert.ToBase64String(compressedBytes);
            return base64;
        }

        public static string Unzip(this string compressedBase64String)
        {
            var compressedBytes = Convert.FromBase64String(compressedBase64String);
            var uncompressedBytes = ComporessionUtils.Unzip(compressedBytes);
            var result = Encoding.UTF8.GetString(uncompressedBytes);
            return result;
        }
    }
    public class ComporessionUtils
    {
        public static void CopyTo(Stream src, Stream dest)
        {
            var bytes = new byte[4096];

            int cnt;

            while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0)
            {
                dest.Write(bytes, 0, cnt);
            }
        }



        public static byte[] Zip(byte[] bytes)
        {
            using (var msi = new MemoryStream(bytes))
            using (var mso = new MemoryStream())
            {
                using (var gs = new GZipStream(mso, CompressionMode.Compress))
                {
                    CopyTo(msi, gs);
                }
                return mso.ToArray();
            }
        }

        public static byte[] Unzip(byte[] bytes)
        {
            using (var msi = new MemoryStream(bytes))
            using (var mso = new MemoryStream())
            {
                using (var gs = new GZipStream(msi, CompressionMode.Decompress))
                {
                    CopyTo(gs, mso);
                }

                return mso.ToArray();
            }
        }
    }
}

6 Mart 2019

C# Thread

using System;
using System.Threading;

namespace ThreadDemo
{
    class Program
    {
        static void Main(params string[] args)
        {

            Example4(args);
            Console.ReadKey();
        }


        #region Example 0 Simple
        static void Example0(string[] args)
        {
            var t = new Thread(WriteY);
            t.Start();
            for (int i = 0; i < 1000; i++)
            {
                Console.Write("x");
            }
        }

        static void WriteY()
        {
            for (int i = 0; i < 1000; i++)
            {
                Console.Write("y");
            }
        }
        #endregion

        #region Example 1 Join And Sleep

        /*
        Join        : You can wait for another thread to end by calling its Join method
        Thread.Sleep: Pauses the current thread for a specified period

             */
        static void Example1(string[] args)
        {
            var t = new Thread(WriteY);
            t.Start();
            t.Join();
            for (int i = 0; i < 1000; i++)
            {
                Console.Write("x");
            }
            Console.WriteLine("Thread is sleeping 5 seconds");
            Thread.Sleep(TimeSpan.FromSeconds(5));
            Console.WriteLine("Waited 5 seconds");
        }
        #endregion

        #region Example 2 If threads on same instance they can share fields.

        bool done;
        static void Example2(string[] args)
        {
            var td = new Program();
            new Thread(td.Go).Start();
            td.Go();
        }

        void Go()
        {
            // it changed by another thread so it will write just once
            if (!done)
            {
                done = true;
                Console.WriteLine("Done");
            }
        }

        #endregion

        #region Example 3 Locking and Thread Safety

        static readonly object _locker = new object();

        static void Example3(string[] args)
        {
            var td = new Program();
            new Thread(td.GoThreadSafe).Start();
            td.GoThreadSafe();
        }

        void GoThreadSafe()
        {
            // it will lock thread so other thread cannot acces until this operation finished finished
            lock (_locker)
            {
                if (!done)
                {
                    done = true;
                    Console.WriteLine("Done");
                }
            }
        }

        #endregion

        #region Example 4 Signaling

        /*Sometimes you need a thread to wait until receiving notification(s) from other
thread(s). This is called signaling. The simplest signaling construct is ManualReset
Event. Calling WaitOne on a ManualResetEvent blocks the current thread until
another thread “opens” the signal by calling Set. */

        static void Example4(string[] args)
        {
            var signal = new ManualResetEvent(false);
            new Thread(() => {
                Console.WriteLine("Waiting for signal ...");
                signal.WaitOne();
                signal.Dispose();
                Console.WriteLine("Got signal!");
            }).Start();

            Thread.Sleep(TimeSpan.FromSeconds(2));
            signal.Set();
        }
        

        #endregion
    }
}

30 Kasım 2018

The Ambient Context Design Pattern in .NET

The Ambient Context Design Pattern in .NET
using System;
using System.Collections.Generic;
namespace DependencyInjection
{
    class Program
    {
        static void Main(string[] args)
        {

            PrintContextTitle();
            using (new MyNestedContext("outer scope"))
            {
                PrintContextTitle();
                using (new MyNestedContext("inner scope"))
                {
                    PrintContextTitle();
                }
                PrintContextTitle();
            }
            PrintContextTitle();

            Console.ReadKey();
        }

        static void PrintContextTitle()
        {
            Console.WriteLine("Current Context is {0}", MyNestedContext.Current != null ? MyNestedContext.Current.Title : "null");
        }
    }

    
    public class MyNestedContext : IDisposable
    {
        private static Stack<MyNestedContext> scopeStack = new Stack<MyNestedContext>();

        public string Title { get; set; }
        public MyNestedContext(string title)
        {
            Title = title;
            scopeStack.Push(this);
        }

        public static MyNestedContext Current {
            get {
                if (scopeStack.Count == 0)
                    return null;
                return scopeStack.Peek();
            }
        }
        public void Dispose()
        {          
            scopeStack.Pop();
        }       
    }
}

16 Kasım 2018

C# RSA Kullanımı

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace RsaDemo
{
    public class RsaUtilities
    {
        public static void CreatePublicAndPrivateKeys()
        {
            using (var csp = new RSACryptoServiceProvider())
            {
                //Generate Key 
                //True:Public and Private Key, False: Just Public Key
                csp.ExportParameters(true);

                //Write Private Key 
                var publicKey = csp.ToXmlString(true);
                File.WriteAllText("private", publicKey);
                Console.WriteLine("Private key generated and saved to disk as 'private'");
                //Write Public Key
                var privateKey = csp.ToXmlString(false);
                File.WriteAllText("public", publicKey);
                Console.WriteLine("Public key generated and saved to disk as 'public'");
            }
        }
        private static string m_PublicKeyXml = string.Empty;
        public static string PublicKeyXml
        {
            get
            {
                if (string.IsNullOrWhiteSpace(m_PublicKeyXml))
                {
                    if (!File.Exists("public"))
                        throw new FileNotFoundException("public key not found for encrypting", "public");
                    else m_PublicKeyXml = File.ReadAllText("public");
                }
                return m_PublicKeyXml;   
            }
        }
        private static string m_PrivateKeyXml = string.Empty;
        public static string PrivateKeyXml
        {
            get
            {
                if (string.IsNullOrWhiteSpace(m_PrivateKeyXml))
                {
                    if (!File.Exists("private"))
                        throw new FileNotFoundException("private key not found for encrypting", "private");
                    else m_PrivateKeyXml = File.ReadAllText("private");
                }
                return m_PrivateKeyXml;
            }
        }

        public static string Encrypt(string plainText)
        {
            byte[] encryptedByteArray;

            using (var csp = new RSACryptoServiceProvider())
            {                
                csp.FromXmlString(PublicKeyXml);

                encryptedByteArray = csp.Encrypt(Encoding.UTF8.GetBytes(plainText), false);
            }
            return Convert.ToBase64String(encryptedByteArray);
        }

        public static string Decrypt(string encryptedText)
        {
            using (var csp = new RSACryptoServiceProvider())
            {
                csp.FromXmlString(PrivateKeyXml);
                var encryptedByteArray = Convert.FromBase64String(encryptedText);
                var decryptedByteArray = csp.Decrypt(encryptedByteArray, false);
                return Encoding.UTF8.GetString(decryptedByteArray);
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // RsaUtilities.CreatePublicAndPrivateKeys();
            string plainText = "foobar";
            Console.WriteLine($"Plain Text: {plainText}");
            string encryptedText = RsaUtilities.Encrypt(plainText);
            Console.WriteLine($"Encrypted Text: {encryptedText}");
            string decryptedText = RsaUtilities.Decrypt(encryptedText);
            Console.WriteLine($"Decrypted Text: {decryptedText}");

        }
    }
}

13 Kasım 2018

C# SqlBulkCopy ile büyük miktarda veri ekleme

Örnek olarak ekleyeceğimiz Customer tablosu


 CREATE TABLE [dbo].[Customer](
  Id bigint IDENTITY(1,1) NOT NULL,
  Name [nvarchar](60) NOT NULL,
  BirthDate [datetime] NOT NULL,
     Height INT NULL
     CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED 
     (
    [ID] ASC
        )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
     ) ON [PRIMARY]


C# İle Kullanımı


using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;

namespace SqlBulkCopyDemo
{
    public class Customer
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public DateTime BirthDate { get; set; }
        public int Height { get; set; }

        public static IEnumerable<Customer> GenerateExampleData(int count)
        {
            int i = 0;
            while (i++ < count)
            {
                yield return new Customer()
                {
                    Name = Guid.NewGuid().ToString(),
                    BirthDate = DateTime.Today.AddDays(-1 * (i % (365 * 50))),
                    Height = new Random(i).Next(150, 190)
                };
            }

        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var customerCount = 5000000;
            var stopWatch = new Stopwatch();
            Console.WriteLine("Generating example data");
            stopWatch.Start();

            var dt = new DataTable();

            //Write Destination Column Names
            dt.TableName = "Customer";
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("BirthDate", typeof(DateTime));
            dt.Columns.Add("Height", typeof(int));

            foreach (var customer in Customer.GenerateExampleData(customerCount))
            {
                dt.Rows.Add(customer.Name, customer.BirthDate, customer.Height);
            }
            Console.WriteLine($"Data generated {stopWatch.Elapsed.ToString()}");

            Console.WriteLine($"SqlBulkCopy starting ");
            stopWatch.Restart();
            using (var con = new SqlConnection("Server=xxx;Database=xxx;User Id=xxx;Password=xxx;"))
            {

                using (var bulkCopy = new SqlBulkCopy(con, SqlBulkCopyOptions.TableLock, null))
                {
                    bulkCopy.DestinationTableName = "Customer";
                    bulkCopy.ColumnMappings.Add("Name", "Name");
                    bulkCopy.ColumnMappings.Add("BirthDate", "BirthDate");
                    bulkCopy.ColumnMappings.Add("Height", "Height");

                    bulkCopy.EnableStreaming = true;
                    bulkCopy.BatchSize = 10000;
                    bulkCopy.NotifyAfter = 1000;
                    bulkCopy.SqlRowsCopied += (sender, e) => Console.WriteLine("RowsCopied: " + e.RowsCopied);

                    var rows = new DataRow[dt.Rows.Count];
                    dt.Rows.CopyTo(rows, 0);

                    con.Open();
                    bulkCopy.WriteToServer(rows);
                }

            }
            stopWatch.Stop();
            Console.WriteLine($"Written to Database: {stopWatch.Elapsed.ToString()}");
            
            Console.ReadKey();
        }
    }
}

8 Kasım 2018

Arka Planda Sürekli Çalışan İş Örneği

//JobTask.cs

using System;
using System.Threading;
using System.Threading.Tasks;

namespace TaskJobCreater
{
    public class JobTask
    {
        CancellationTokenSource cancellationTokenSource { get; set; }
        Task task;
        private Task CreateTask(Action action, CancellationToken cancellationToken)
        {
            return new Task(() =>
            {

                while (!cancellationTokenSource.Token.IsCancellationRequested)
                {
                    if (StartDate < DateTime.Now)
                    {
                        IsStarted = true;
                        Started.Invoke(this);
                        action();
                        Completed();
                        return;
                    }
                    task.Wait(1000);
                }
            },
           cancellationTokenSource.Token
           );
        }
        public DateTime StartDate { get; private set; }
        public void Start(DateTime startDate, Action action)
        {            
            if (IsActive)
                throw new InvalidOperationException("Task started before");
            StartDate = startDate;
            cancellationTokenSource = new CancellationTokenSource();

            task = CreateTask(action, cancellationTokenSource.Token);            
            task.Start();
            IsActive = true;
            if (Activated != null)
                Activated.Invoke(this);
        }
        public event Action<object> Stopped;
        public event Action<object> Started;
        public event Action<object> Activated;
        private void Completed()
        {
            
            IsActive = false;
            IsStarted = false;
            Stopped.Invoke(this);
        }
        public void Stop()
        {
            if (IsActive)
            {
                cancellationTokenSource.Cancel();
                try
                {
                    task.Wait();
                }
                catch (OperationCanceledException ce)
                {
                    task.Dispose();
                }
                Completed();
            }
        }
        public bool IsActive { get; private set; }
        public bool IsStarted { get; private set; }

    }
}


/****************************************************************/

//MainWindowModel.cs

using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;

namespace TaskJobCreater
{
    public class MainWindowModel : INotifyPropertyChanged
    {
        public MainWindowModel()
        {
            job.Stopped += (s) =>
            {
                Log("Job has ben stopped");
                StartJob();
            };
            job.Started += (s) =>
            {
                Log($"Job has been started");
                ButtonName = "START";
            };
            job.Activated += (s) =>
            {
                Log( $"Job will start after {Convert.ToInt32((job.StartDate - DateTime.Now).TotalSeconds)} seconds later.");
                ButtonName = "STOP";
            };
            StartJob();
            canExecute = true;
        }
        private bool canExecute;
        private ICommand clickCommand;
        public ICommand ClickCommand => clickCommand ?? (clickCommand = new CommandHandler(() => ToogleJob(), canExecute));


        public void ToogleJob()
        {
            if (job.IsActive)
                StopJob();
            else StartJob();
        }
        private void Log(string log)
        {
            Logs += log;
            Logs += Environment.NewLine;
        }
        private void StartJob() => job.Start(DateTime.Now.AddSeconds(5), Job);

        private void StopJob() => job.Stop();

        public void Job() => Log(DateTime.Now.ToString("HH:mm:ss"));




        string m_ButtonName = "START";

        public string ButtonName {
            get { return m_ButtonName; }
            set {
                m_ButtonName = value;
                OnPropertyChanged();
            }
        }

        string m_Logs;

        public string Logs {
            get { return m_Logs; }
            set {
                m_Logs = value;
                OnPropertyChanged();
            }
        }



        public JobTask job = new JobTask();




        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName]string propertyName = "")
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }
}


/****************************************************************/

//CommandHandler.cs

using System;
using System.Windows.Input;

namespace TaskJobCreater
{
    public class CommandHandler : ICommand
    {
        private Action action;
        private bool canExecute;

        public CommandHandler(Action action, bool canExecute)
        {
            this.action = action;
            this.canExecute = canExecute;
        }

        public bool CanExecute(object parameter) => canExecute;

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter) => action();

    }
}
/****************************************************************/

//MainWindow.xaml

<Window x:Class="TaskJobCreater.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TaskJobCreater"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Button Content="{Binding ButtonName}" Height="40" Command="{Binding ClickCommand}"/>
        <TextBox Grid.Row="1" Text="{Binding Logs}" AcceptsReturn="True"  />
    </Grid>
</Window>

/****************************************************************/
//MainWindow.cs

using System.Windows;

namespace TaskJobCreater
{
    /// 
    /// Interaction logic for MainWindow.xaml
    /// 
    public partial class MainWindow : Window
    {
        public readonly MainWindowModel model;
        public MainWindow()
        {
            InitializeComponent();
            model = new MainWindowModel();
            DataContext = model;
        }
    }
}


10 Ekim 2018

RabbitMQ için C# ile basit bir örnek

Programı kullanmak için ilk önce https://www.rabbitmq.com/download.html adresinden RabbitMQ kurmanız gerekiyor. Kurulum sırasında Erlang dilinin kurulumunu isterse http://www.erlang.org/downloads adresinden indirip kurduktan sonra tekrar kuruluma devama edin.

Yapılan örneğin aslını https://www.rabbitmq.com/tutorials/tutorial-one-dotnet.html adresinden takip edebilirsiniz.

Kurulumdan sonra servisi başlatmak için Windows Başlat kısmından RabbitMQ Service - start aratılarak çıkan program ile başlatılır. Ve yine servisi durdurmak için Windows Başlat kısmından RabbitMQ Service - stop aratılarak çıkan programla durdurulur.

RabbitMQ için yapılacak tüm komutlar için yine başlat menüsünden RabbitMQ Command Prompt(sbin dir) ile komut satırı açılacaktır.

RabbitMQ için yönetim panelini kurarak görsel arayüze ulaşabilirsiniz.
Kurmak için RabbitMQ Command Prompt üzerinden aşağıda ki komut ile Management Plugin kurulur:

rabbitmq-plugins enable rabbitmq_management


Kurulum ile birlikte http://localhost:15672 üzerinde yönetim ekranına  ulaşabilirsiniz.
İlk gelen kullanıcı adı ve şifre "guest" olarak belirlenmiştir.

Detaylı kurulum için http://www.rabbitmq.com/management.html adresindeki adımları takip ediniz.


RabbitMQPublisher ve RabbitMQReceiver adında iki farklı "Console Project" açalım. Her iki proje için de RabbitMQ.Client   referansları projeye eklenmelidir.


Uygulamanın kodları aşağıdan görülebilir.
!RabbitMQPublisher için Program isimli sınıfın adı Send olarak değiştirildi fakat gerekli değildir.


using RabbitMQ.Client;
using System;
using System.Text;

namespace RabbitMQPublisher
{
    class Send
    {
        static void Main(string[] args)
        {


            var factory = new ConnectionFactory() { HostName = "localhost" };
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue: "hello",
                                     durable: false,
                                     exclusive: false,
                                     autoDelete: false,
                                     arguments: null);
                var message = string.Empty;

                do
                {
                    Console.WriteLine("Send Message:");
                    message = Console.ReadLine();
                    var body = Encoding.UTF8.GetBytes(message);

                    channel.BasicPublish(exchange: "",
                                         routingKey: "hello",
                                         basicProperties: null,
                                         body: body);

                    Console.WriteLine(" [x] Sent {0}", message);
                    Console.WriteLine("Write empty input to exit.");

                } while (!string.IsNullOrWhiteSpace(message));

            }
        }
    }
}


!RabbitMQReceiver için Program isimli sınıfın adı Receive olarak değiştirildi fakat gerekli değildir.


using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;

namespace RabbitMQReceiver
{
    class Receive
    {
        static void Main(string[] args)
        {
            var factory = new ConnectionFactory() { HostName = "localhost" };
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue: "hello", 
                                     durable: false,
                                     exclusive: false,
                                     autoDelete: false,
                                     arguments: null);


                var consumer = new EventingBasicConsumer(channel);

                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body);
                    Console.WriteLine(" [x] Received {0}", message);
                };

                var result = channel.BasicConsume(queue: "hello",
                                                  autoAck: true,
                                                  consumer: consumer);

                Console.WriteLine(" Press [enter] to exit.");
                Console.ReadLine();
            }
        }
    }
}

İleride detaylandırılacaktır.
İlk önce Receiver başlatılmak üzere iki programı da aynı anda açarsak. Aşağıda ki gibi Publisher üzerinden gönderilen mesaj iş kuyruğuna eklenecek ve Receiver tarafından kuyruktan alınıp işlenecektir.

17 Eylül 2018

IEnumerator ve yield kullanımı

IEnumerator ile tekrar eden basit yığınlar üzerinde işlemler yapılır. Yığın içerisinde MoveNext() ile dönen değeri alırız. Eğer dönen değer True ise bir adım ilerlemiştir. Ve bulunduğu adımdaki değeri Current ile alırız. Eğer değer False ise bir sonraki adımı okumamıştır. Yığın içerisinde ki adım bitmiştir. yield anahtarı ile işlemin bitmesini beklemeden her adımı göndeririz. Bu bize tüm işlemlerin bitmeden çalışmamızı sağlar. Aşağıda ki örneğe dikkat ederseniz uzun işleme girmeden önce her adımı teker teker yollamıştır.
using System;
using System.Collections.Generic;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var g = Metod();
            while (g.MoveNext())
            {
                Console.WriteLine(g.Current);
            }                    
        }

        static IEnumerator<int> Metod()
        {
            yield return 1;
            yield return 2;
            Console.WriteLine("Uzun işlem başlangıç");
            System.Threading.Thread.Sleep(5000);
            Console.WriteLine("Uzun işlem bitiş");
            yield return 3;
        }
    }
}

15 Temmuz 2018

C# ile basit bir Inversion Of Control (IoC) Örneği

Burada verilen örnek ile basit bir IoC çalışma mantığı gösterme hedeflenmiştir.
Kararlı bir IoC kütüphanesi için Castle Windsor inceleyiniz.


using System;
using System.Collections.Generic;
using System.Linq;

namespace DIP
{
    class Program
    {
        static void Main(string[] args)
        {
            var ioc = new SimpleIoC();
            ioc.Register<IPrinter, ConsolePrinter>();
            ioc.Register<Test, Test>();

            var test = ioc.Resolve<Test>();
            test.Hello("Ali");
        }
    }

    interface IPrinter
    {
        void Print(string text);
    }
    class ConsolePrinter : IPrinter
    {
        public void Print(string text)
        {
            Console.WriteLine(text);
        }
    }
    class Test
    {
        private readonly IPrinter printer;
        public Test(IPrinter printer)
        {
            this.printer = printer;
        }
        public void Hello(string name) => printer.Print($"Hello {name}");
    }
    public class SimpleIoC
    {
        private readonly Dictionary<Type, Type> _map = new Dictionary<Type, Type>();
        public void Register<TFrom, TTo>() => _map.Add(typeof(TFrom), typeof(TTo));

        public T Resolve<T>() => (T)Resolve(typeof(T));

        private object Resolve(Type type)
        {
            Type resolvedType = null;
            try
            {
                resolvedType = _map[type];
            }
            catch (Exception)
            {
                throw new ArgumentException($"Couldn't resolve the type {type}");
            }

            var ctor = resolvedType.GetConstructors().First();
            var ctorParameters = ctor.GetParameters();

            if (ctorParameters.Length == 0)
                return Activator.CreateInstance(resolvedType);

            var parameters = new List<object>();
            foreach (var parameterToResolve in ctorParameters)
            {
                parameters.Add(Resolve(parameterToResolve.ParameterType));
            }
            return ctor.Invoke(parameters.ToArray());
        }
    }
}

11 Temmuz 2018

C# Serializable Özelliği ile Nesneleri Dosyaya Yazmak ve Okumak

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace SerializeDemo
{
    class Program
    {
        
        static void Main(string[] args)
        {
            string dbPath = "serialize_demo.dat";
            List employees;
            if (File.Exists(dbPath))
                using (var fs = new FileStream(dbPath, FileMode.Open, FileAccess.Read))
                {
                    var formatter = new BinaryFormatter();
                    employees = (List)formatter.Deserialize(fs);
                }
            else
                using (var fs = new FileStream(dbPath, FileMode.Create, FileAccess.Write))
                {
                    employees = CreateExampleList();
                    var formatter = new BinaryFormatter();
                    formatter.Serialize(fs, employees);
                }
        }

        public static List CreateExampleList()
        {
            return new List()
            {
                new Employee
                {
                    Id = 1,
                    Name = "Test 1",
                    Birthdate = DateTime.Now,
                    Salary = 1m
                },
                new Employee
                {
                    Id = 2,
                    Name = "Test 2",
                    Birthdate = DateTime.Now,
                    Salary = 1.3m
                }
            };
        }
    }
    [Serializable]
    public class Employee
    {
        public int Id { get; set; }

        public string Name { get; set; }
        public decimal Salary { get; set; }
        public DateTime Birthdate { get; set; }
    }
}

9 Temmuz 2018

C# Idle - Kullanıcının Bilgisayar ile Son Etkileşim Zamanını Yakalama

using System;
using System.Runtime.InteropServices;

namespace IdleDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var logoutDuration = TimeSpan.FromSeconds(10);
            var idle = new IdleUtilities();
            var tmr = new System.Timers.Timer(1000);
            tmr.Elapsed += (s, e) =>
              {
                  var remainingTime = logoutDuration - idle.GetLastInputTime();
                  var remainingSecond = (int)remainingTime.TotalSeconds;
                  if (remainingSecond <= 0)
                  {
                      Console.WriteLine("Program is closed");
                      Environment.Exit(0);
                  }
                  else Console.WriteLine($"Program will be closed after {remainingSecond} seconds later");
              };
            tmr.Start();

            Console.WriteLine("Exit?(Y/N)");
            do
            {

            } while (Console.ReadLine() == "Y");
        }
    }
    public class IdleUtilities
    {
        [StructLayout(LayoutKind.Sequential)]
        struct LASTINPUTINFO
        {
            public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO));

            [MarshalAs(UnmanagedType.U4)]
            public UInt32 cbSize;
            [MarshalAs(UnmanagedType.U4)]
            public UInt32 dwTime;
        }


        [DllImport("user32.dll")]
        static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

        public TimeSpan GetLastInputTime()
        {
            uint idleTicks = 0;
            var lastInputInfo = new LASTINPUTINFO();
            lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);
            lastInputInfo.dwTime = 0;

            uint envTicks = (uint)Environment.TickCount;
            if (GetLastInputInfo(ref lastInputInfo))
            {
                uint lastInputTick = lastInputInfo.dwTime;
                idleTicks = envTicks - lastInputTick;
            }

            return new TimeSpan(idleTicks * 10000);
        }
    }
}

22 Haziran 2018

C# ile Yeni Veri Tipi Oluşturmak

Para işlemlerinde kullanmak için virgülden sonraki sadece iki basamağı hesaba katmak için Money türünde yeni bir veri tipi oluşturdum.

Money.cs

using System;
using System.Globalization;

namespace ConsoleApplication1
{
    public struct Money
    {
        public static int MidPointWayFromZero = 2;
        private decimal value;
        private Money(decimal value)
        {
            this.value = Decimal.Round(value, MidPointWayFromZero, MidpointRounding.AwayFromZero);
        }

        public static implicit operator Money(decimal value) => new Money(value);
        public static implicit operator Money(byte value) => new Money(value);
        public static implicit operator Money(sbyte value) => new Money(value);
        public static implicit operator Money(short value) => new Money(value);
        public static implicit operator Money(ushort value) => new Money(value);
        public static implicit operator Money(char value) => new Money(value);
        public static implicit operator Money(int value) => new Money(value);
        public static implicit operator Money(uint value) => new Money(value);
        public static implicit operator Money(long value) => new Money(value);
        public static implicit operator Money(ulong value) => new Money(value);
        public static implicit operator Money(float value) => new Money(Convert.ToDecimal(value));
        public static implicit operator Money(double value) => new Money(Convert.ToDecimal(value));


        public static explicit operator decimal(Money money) => money.value;
        public static explicit operator byte(Money money) => Convert.ToByte(money.value);
        public static explicit operator sbyte(Money money) => Convert.ToSByte(money.value);
        public static explicit operator char(Money money) => Convert.ToChar(money.value);
        public static explicit operator short(Money money) => Convert.ToInt16(money.value);
        public static explicit operator ushort(Money money) => Convert.ToUInt16(money.value);
        public static explicit operator int(Money money) => Convert.ToInt32(money.value);
        public static explicit operator uint(Money money) => Convert.ToUInt32(money.value);
        public static explicit operator long(Money money) => Convert.ToInt64(money.value);
        public static explicit operator ulong(Money money) => Convert.ToUInt64(money.value);
        public static explicit operator float(Money money) => Convert.ToSingle(money.value);
        public static explicit operator double(Money money) => Convert.ToDouble(money.value);




        public override String ToString() => value.ToString();

        public String ToString(String format) => value.ToString(format);

        public String ToString(IFormatProvider provider) => value.ToString(provider);

        public String ToString(String format, IFormatProvider provider) => value.ToString(format, provider);


        public static Money Parse(String s) => new Money(Decimal.Parse(s));

        public static Money Parse(String s, NumberStyles style) => new Money(Decimal.Parse(s, style));

        public static Money Parse(String s, IFormatProvider provider) => new Money(Decimal.Parse(s, provider));

        public static Money Parse(String s, NumberStyles style, IFormatProvider provider) => new Money(Decimal.Parse(s, style, provider));

        public static Boolean TryParse(String s, out Money result) => Decimal.TryParse(s, out result.value);

        public static Boolean TryParse(String s, NumberStyles style, IFormatProvider provider, out Decimal result)
            => Decimal.TryParse(s, style, provider, out result);

        public static Money Round(Money d, int decimals = 0) => new Money(Decimal.Round(d.value, decimals));


        public static Money Round(Money d, MidpointRounding mode) => new Money(Decimal.Round(d.value, 0, mode));


        public static Money Round(Money d, int decimals, MidpointRounding mode) => new Money(Decimal.Round(d.value, decimals, mode));

        public static short ToInt16(Money value) => Convert.ToInt16(value.value);
        public static int ToInt32(Money d) => Convert.ToInt32(d.value);
        public static long ToInt64(Money d) => Convert.ToInt64(d.value);



        public static Money operator +(Money d) => d;

        public static Money operator -(Money d) => -d;

        public static Money operator ++(Money d) => new Money(d.value + 1);

        public static Money operator --(Money d) => new Money(d.value - 1);

        public static Money operator +(Money d1, Money d2) => new Money(d1.value + d2.value);

        public static Money operator -(Money d1, Money d2) => new Money(d1.value - d2.value);

        public static Money operator *(Money d1, Money d2) => new Money(d1.value * d2.value);


        public static Money operator /(Money d1, Money d2) => new Money(d1.value / d2.value);

        public static Money operator %(Money d1, Money d2) => new Money(d1.value % d2.value);

        public static bool operator ==(Money d1, Money d2) => d1.value == d2.value;


        public static bool operator !=(Money d1, Money d2) => d1.value != d2.value;

        public static bool operator <(Money d1, Money d2) => d1.value < d2.value;

        public static bool operator <=(Money d1, Money d2) => d1.value <= d2.value;

        public static bool operator >(Money d1, Money d2) => d1.value > d2.value;

        public static bool operator >=(Money d1, Money d2) => d1.value >= d2.value;


        public TypeCode GetTypeCode()
        {
            return TypeCode.Decimal;
        }

    }
}

Consol içerisinde kullanım testi
using System;

namespace ConsoleApplication1
{

    class Program
    {
        public static void Main(params string[] args)
        {

            Money money = 919;

            Console.WriteLine(IsPrime(money));
            money += .23;
            money *= .18;
            Console.WriteLine(money);
        }

        private static bool IsPrime(Money number)
        {
            Money i = 2;
            if (number <= 2 || number % 2 == 0)
                return false;
            i++;
            while (i * i <= number)
            {
                if (number % i == 0)
                    return false;
                i++;
            }
            return true;
        }
    }
}

21 Nisan 2018

C# Indexer Örneği

using System;
using System.Collections.Generic;

namespace CSharpIntermediate
{

    public class HttpCookie
    {
        private readonly Dictionary<string, string> dictionary;
        public HttpCookie()
        {
            dictionary = new Dictionary<string, string>();
        }
        public string this[string key]
        {
            get
            {
                return dictionary[key];
            }
            set
            {
                dictionary[key] = value;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var httpCookie = new HttpCookie();
            httpCookie["username"] = "admin";
            Console.WriteLine(httpCookie["username"]);
        }
    }
}

20 Nisan 2018

C# Enumlarda Description Okuma

using System;
using System.ComponentModel;

namespace Demo
{

    [Flags]
    public enum Directions
    {
        [Description("Doğu")]
        E = 0,

        [Description("Kuzey Doğu")]
        NE = 1,

        [Description("Kuzey")]
        N = 2,

        [Description("Kuzey Batı")]
        NW = 3,

        [Description("Batı")]
        W = 4,

        [Description("Güney Batı")]
        SW = 5,

        [Description("Güney")]
        S = 6,

        [Description("Güney Doğu")]
        SE = 7,
    }


    public static class EnumsExtensions
    {
        public static string GetDescription(this Enum enumerationValue)
        {
            var type = enumerationValue.GetType();
            var memberInfo = type.GetMember(enumerationValue.ToString());
            if (memberInfo.Length > 0)
            {
                var attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

                if (attrs.Length > 0)
                {
                    return ((DescriptionAttribute)attrs[0]).Description;
                }
            }
            return enumerationValue.ToString();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Directions.E.GetDescription());
            Console.WriteLine(Directions.NE.GetDescription());
            Console.WriteLine(Directions.N.GetDescription());
            Console.WriteLine(Directions.NW.GetDescription());
            Console.WriteLine(Directions.W.GetDescription());
            Console.WriteLine(Directions.SW.GetDescription());
            Console.WriteLine(Directions.S.GetDescription());
            Console.WriteLine(Directions.SE.GetDescription());            
        }
    }
}


9 Nisan 2018

C# ile Yazılan Kütüphaneyi C++ ile dışarı açmak.

Amaç: Varolan C# projesini C++ ile diğer dillere açmak.

1) Visual Studio ile Class Library projesi oluşturalım. Ben projemin adını MyLibrary verdim.

2) https://www.nuget.org/packages/UnmanagedExports adresinde ki paketi C# projemize kuralım.

Install-Package UnmanagedExports -Version 1.2.7

3) Solution Explorer üzerinden projemize sağ tıkla "Properties" içerisinden
a) "Build" sekmesi içersinde
aşağıda ki ayarları yapalım.

Platform target: x86 ,
Allow unsafe code: true,
Register for COM interop: true

b) "Build Events" içerisinde  aşağıdaki komutu yazarak dll i her build edildiğinde çıkan dosyaları C++ projesinin build edildiği klasöre ekliyoruz. Proje boyunca release modunda çalışıyorum. bu yüzden Release seçtim.

Post-build event command line:
xcopy /y "$(ProjectDir)$(OutDir)*" "$(SolutionDir)Release"

4) Export.cs sınıfını oluşturalım.

using RGiesecke.DllExport;
using System.Runtime.InteropServices;

namespace MyLibrary
{
    public class Export
    {
        [DllExport("SayMyName", CallingConvention = CallingConvention.Cdecl)]
        [return: MarshalAs(UnmanagedType.LPWStr)]
        public static string SayMyName([MarshalAs(UnmanagedType.LPWStr)]string name)
        {
            if (name == "Heisenberg")
                return "You're Goddamn Right";
            else return "Say my name!";
        }

        [DllExport("Sum", CallingConvention = CallingConvention.Cdecl)]
        public static int Sum(int x, int y) => x + y;
    }
}

5) Yeni bir C++ projesi oluşturalım. Solution Explorer üzerinden Yeni Proje ekleyelim.

Other Languages ( Diğer Diller) => Visual C++ => Win32 Project seçelim. Proje adını MyLibrary.Native verdim.
!Win32 Application Wizard'da Applcation Type: DLL seçerek devam edelim.

6) C++ projesine sağ tıkla properties içerisinde "Build Events" =>"Pre-Build Event" sekmesine komutlarını ekleyelim. Böylece build edilmeden önce C# dll lerini proje içerisine kopyalamış oluruz.

xcopy /y "$(SolutionDir)Release\MyLibrary.tlb" "$(ProjectDir)"
xcopy /y "$(SolutionDir)Release\MyLibrary.dll" "$(ProjectDir)"


7) C++ içerisinde Header Files klasörü içerisinde stdafx.h içerisinde yoksa aşağıdaki satırları da ekleyin.

#include <stdio.h>
#include <tchar.h>


8) MyLibrary.Native.cpp içerisini aşağıdaki gibi olacaktır.
//
// MyLibrary.Native.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"


extern "C" {
 //Dışarı verilecek metodlar
 __declspec(dllexport) wchar_t * __cdecl SayMyName(wchar_t * name);
 __declspec(dllexport) int __cdecl Sum(int x, int y);
}
#include <windows.h>

#import "MyLibrary.tlb" auto_rename

//MyLibrary.dll içerisinden okunacak methodların tipleri
//wchar_t* string'e karşılık geliyor.

typedef wchar_t* (*pSayMyName)(wchar_t* name);
typedef int (*pSum)(int x, int y);

wchar_t* __cdecl SayMyName(wchar_t* name) {
 pSayMyName sayMyName = NULL;
 HINSTANCE hDLL = 0;

 hDLL = ::LoadLibrary(L"MyLibrary.dll");
 ::CoInitialize(NULL);

 if (!hDLL) {
  return L"DLL Yüklenemedi";
 }

 //
 // TO DO: Add code here to get an instance of MyClass
 //
 sayMyName = (pSayMyName)GetProcAddress(hDLL, "SayMyName");

 if (!sayMyName)
 {
  return L"ERROR: Unable to find entry for SayMyName(name)\n";

 }
 return  sayMyName(name);
}

int __cdecl Sum(int x, int y) {
 pSum sum = NULL;
 HINSTANCE hDLL = 0;

 hDLL = ::LoadLibrary(L"MyLibrary.dll");
 ::CoInitialize(NULL);

 if (!hDLL) {
  printf("DLL Yüklenemedi");
 }

 //
 // TO DO: Add code here to get an instance of MyClass
 //
 sum = (pSum)GetProcAddress(hDLL, "Sum");

 if (!sum)
 {
  printf("ERROR: Unable to find entry for Sum(x,y)\n");

 }
 return  sum(x, y);
}
//
9)Sırasıyla MyLibrary ve MyLibrary.Native projelerini Release modunda build edelim. Ve Solution'ın bulunduğu klasör içerisindeki Release klasöründe bizim paketler hazırdır. Şimdi bunları önce Visul Studio Komut Satırı ("VS2015 x86 Native Tools Command Prompt") ile kontrol edelim.

Komut satırını açalım ve aşağıdaki komutu çalıştıralım. Bu bize dışarı açılan methodları listeleyecek.

Burada SayMyName ve Sum methodlarını her iki dll içinde de görmemiz lazım.

dumpbin "{proje yolu}\MyLibrary\Release\MyLibrary.dll" /exports
dumpbin "{proje yolu}\MyLibrary\Release\MyLibrary.Native.dll" /exports

Görüyorsanız İşin büyük bir bölümü bitiyor.


10) Son olarak C++ ile yazdığımız DLL'in çalışıp çalışmadığını C# Console Uygulaması üzerinden test edelim.

MyLibrary.Test adında bir C# konsol uygulaması ekleyelim.

11) MyLibrary.Test sağ tıkla

Properties => Build => içerisinde Platform target  x86 seçelim.
Properties => Build Events => Pre-build event command line içerisine aşağıdaki komutu yazalım. Böylece her build ettiğimizde projelerin son halini test projemize almış olacağız.

  xcopy /y "$(SolutionDir)Release" "$(ProjectDir)$(OutDir)"


12) MyLibrary.Test projesi içerisinde Program.cs aşağıdaki gibi extern methodlarını ekleyelim ve projeyi başlangıç projesi olarak seçelim. Ve testimizi yapalım.

using System;
using System.Runtime.InteropServices;

namespace MyLibrary.Test
{
    class Program
    {

        [DllImport("MyLibrary.Native.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SayMyName")]
        [return: MarshalAs(UnmanagedType.LPWStr)]
        public static extern string SayMyName([MarshalAs(UnmanagedType.LPWStr)]string name);

        [DllImport("MyLibrary.Native.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Sum")]
        public static extern int Sum(int x, int y);

        static void Main(string[] args)
        {
            Console.WriteLine(SayMyName("Heisenberg"));
            Console.WriteLine(Sum(1, 2));
        }
    }
}
Bitmiş Proje Kodları:MyLibrary.dll

4 Nisan 2018

C# PDF'leri birleştirme

Kullanılan Paket : iTextSharp


using System.IO;
using iTextSharp.text.pdf;
using iTextSharp.text;

namespace PdfMerge
{
    class PdfHelper
    {
         public static void MergePdfs(string[] paths, string outputPath)
        {
            byte[] mergePdf = null;
            using (var ms = new MemoryStream())
            {
                using (var doc = new Document())
                using (var copy = new PdfCopy(doc, ms))
                {
                    doc.Open();
                    foreach (var path in paths)
                        using (var reader = new PdfReader(path))
                        {
                            int n = reader.NumberOfPages;
                            for (int page = 0; page < n;)
                                copy.AddPage(copy.GetImportedPage(reader, ++page));
                        }
                }
                mergePdf = ms.ToArray();
                File.WriteAllBytes(outputPath, mergePdf);
            }
        }
    }
}