@manhng

Welcome to my blog!

Transaction Scope

June 13, 2021 15:43

Transaction Scope (edit)

Implementing an Implicit Transaction using Transaction Scope | Microsoft Docs

Implementing an Implicit Transaction using Transaction Scope | Microsoft Docs

TransactionScope: A simple way to handle transactions in .NET | Code Wala (2018)

TransactionScope Considered Annoying | Josh the Coder (2020)

  • Transaction Management
  • Transaction or TransactionScope
  • TransactionScope
  • TransactionScope Timeout
  • Multiple databases
  • Dapper
  • Dapper CommandTimeout
  • Logging
  • Autofac DI using in Console Application

All About TransactionScope - CodeProject

Handling Transactions in .NET Using TransactionScope (codeguru.com)

  1. using (var transactionScope = new TransactionScope())
  2. using (var transactionScope = new TransactionScope(TransactionScopeOption.Required)) // default
  3. using (var transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew))

c# - Advanced System.Transactions debugging - Stack Overflow

<configuration>
 <system.diagnostics>
  <sources>
   <source name="System.Transactions" switchValue="Information">
   <listeners>
    <add name="tx" type="System.Diagnostics.XmlWriterTraceListener" initializeData= "tx.log" />
   </listeners>
  </source>
 </sources>
</system.diagnostics>

[SOLVED] => Transaction scope timeout on 10 minutes (entityframework.net)

Transaction Scope uses the Machine config setting as the maximum timeout. The default machine timeout is 10 minutes.

TransactionScope Has a Default Timeout (stephencleary.com)

Passing TimeSpan.Zero into the TransactionScope constructor will instruct it to use the maximum timeout (TransactionManager.MaximumTimeout, which has a default value of 10 minutes) instead of the default. Unfortunately, the maximum timeout can only be increased by editing the machine.config file.

using new TransactionScope() Considered Harmful | Microsoft Docs

public class TransactionUtils {
    public static TransactionScope CreateTransactionScope() {
        var transactionOptions = new TransactionOptions();
        transactionOptions.IsolationLevel = IsolationLevel.ReadCommitted;
        transactionOptions.Timeout = TransactionManager.MaximumTimeout;
        return new TransactionScope(TransactionScopeOption.Required, transactionOptions);
    }
}

Show me the code


using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions() {
IsolationLevel = System.Transactions.IsolationLevel.Serializable,
Timeout = TimeSpan.FromMinutes(10)
}))


private
void SomeMethod()
{ try { using (var _transactionScope = new TransactionScope(TransactionScopeOption.Required, transactionOptions)) { using (SqlConnection _connection = new SqlConnection(connectionstring)) { _connection.Open(); DoSomething()... } _transactionScope.Complete(); } } catch (TransactionAbortedException e) { nlog.Error(string.Format("The transaction has been aborted: {0}", e.Message)); throw; } catch (Exception e) { throw; } }

Autofac DI container in Console App

dependency injection - Correct use of Autofac in C# console application - Stack Overflow

c# - Autofac DI container in console app - Code Review Stack Exchange

DI in .NET Core Console Application

Dependency injection in .NET Core console applications (gunnarpeipman.com)

TransactionScope & Transaction in EF6

Entity Framework (EF) TransactionScope vs Database.BeginTransaction (vunvulearadu.blogspot.com)

Unit Testing

c# - Full integration test for a Console application - Code Review Stack Exchange

How to unit test C# Dynamics CRM interface code (alexanderdevelopment.net)

jordimontana82/fake-xrm-easy: The testing framework for Dynamics CRM and Dynamics 365 which runs on an In-Memory context and deals with mocks or fakes for you (github.com)

Console Application Basic

June 12, 2021 00:51

Console Application Basic (edit)

  • JsonTextWriter
  • Console Formatting (Indent) (PadLeft)
  • Console Output/Input Encoding
  • NLog & Log4Net
  • Debug Mode
  • Unicode characters (Janpanese)

Oracle database: Unicode Database and Unicode Datatype

Ký tự hán tự (kanji character): 鄭 瑋萱

Supporting Multilingual Databases with Unicode (oracle.com)

Console Application | Microsoft Docs

Tutorial: Create a simple C# console app - Visual Studio | Microsoft Docs

Tutorial: Extend a simple C# console app - Visual Studio | Microsoft Docs

Perfect console application in .net Core: add unit tests – Michał Białecki Blog (michalbialecki.com) (.NET Core) (HAY HAY HAY)

Perfect console application in .net Core: set up dependency injection – Michał Białecki Blog (michalbialecki.com) (SimpleInjector) (Unit Testing) (Dependency Injection)

C#: Building a Useful, Extensible .NET Console Application Template for Development and Testing - CodeProject (HAY HAY HAY)

Some Best Practices for C# Application Development (Explained) - CodeProject (HAY HAY HAY)

Command line - Correct way to implement C# console application? - Stack Overflow (HAY HAY HAY)

C# Logging best practices in 2021 with examples and tools · Raygun Blog (HAY HAY HAY)

C# Console Application Examples (50+ C# Examples) – Programming, Pseudocode Example, C# Programming Example (csharp-console-examples.com)

Error messages should be written to stderr aka Console.Error, and normal output to stdout aka Console.Out. This is particularly important for "filter" type console apps whose output (stdout) can be piped to another process, e.g. in a batch file.

Generally if you encounter an error, write an error message to Console.Error and return a non-zero result. Or if it's an exception, just don't bother handling it.

To return a result code, you can either pass it as an argument to Environment.Exit, set the Environment.ExitCode property, or return a non-zero value from main.

For simple console apps I would:

  • have a helper class to parse the command line.

  • have a facade class that provides a testable API for the functionality implemented by your command line tool. Like most .NET APIs, this would normally throw an exception if an error occurs.

  • the main program simply uses the helper to parse the command line and calls the API passing the arguments passed from the command line. It optionally catches exceptions thrown from the API, logs them, writes a user-oriented error message to Console.Error and sets a non-zero return code.

But I wouln't consider this to be the one true way: there isn't really such a thing which is why you're unlikely to find the book you're looking for.

Debug mode

private void PrintFirstName()
{
string firstName = string.Empty;
#if DEBUG
firstName = GetFirstName();
#endif
Console.WriteLine(firstName);
}
[Conditional("DEBUG")]
private void PrintFirstName()
{
string firstName = GetFirstName();
Console.WriteLine(firstName);
}

try {
//Do something
}
catch(ex as Exception) {
logger.Error(ex);
throw;
}

Show me the code

Console.Title = typeof(Program).Name;

Console.OutputEncoding = Encoding.UTF8;
Console.InputEncoding = Encoding.UTF8;

// Set the Foreground color to blue
Console.ForegroundColor = ConsoleColor.Blue;

// Set the Background color to black
Console.ForegroundColor = ConsoleColor.Blue;

Console.BackgroundColor = ConsoleColor.Red;
Console.ForegroundColor = ConsoleColor.Black;

// Clear output screen
Console.Clear();

// Restore the original console colors.
Console.ResetColor();

public class ConsoleFormatting
{
    public static string Indent(int count)
    {
        return "".PadLeft(count);
    }
}

JsonWriter writer;

public Calculator()
{
    StreamWriter logFile = File.CreateText("calculatorlog.json");
    logFile.AutoFlush = true;
    writer = new JsonTextWriter(logFile);
    ....
}

Program.cs

ConsoleApplicationBase/Program.cs at master · TypecastException/ConsoleApplicationBase (github.com)

Console Command

ConsoleApplicationBase/ConsoleCommand.cs at master · TypecastException/ConsoleApplicationBase (github.com)

Console Formatting (HAY HAY HAY)

ConsoleApplicationBase/ConsoleFormatting.cs at master · TypecastException/ConsoleApplicationBase (github.com)

CLI

Please use the .net port of the apache commons cli API. This works great.

http://sourceforge.net/projects/dotnetcli/

And the original API for concepts and introduction

http://commons.apache.org/cli/

Unicode characters

C# Unicode (Japanese Characters) - Stack Overflow

There are two conditions that must be satisfied in order for this to work:

  1. The console's output encoding must be able to represent Japanese characters
  2. The console's font must be able to render them

Condition 1 should be fairly simple to deal with; just set System.Console.OutputEncoding to an appropriate Encoding, such as a UTF8Encoding. (Of course, this won't work on Windows 9x, since that doesn't really support encodings or Unicode. But you aren't using that, now, are you?)

Satisfying condition 2 is a bit more involved:

  1. First, an appropriate font must be installed on the user's system. If there aren't any installed yet, the user will have to install some, perhaps by:

    • Opening intl.cpl ("Regional and Language Options" in the Control Panel on Windows XP in English)
    • Going to the "Languages" tab
    • Enabling "Install files for East Asian languages"
    • Clicking "OK"
  2. Actually getting the console to use such a font seems to be fairly hairy; see the question: How to display japanese Kanji inside a cmd window under windows? for more about that.

c# - How to write Unicode characters to the console? - Stack Overflow

Besides Console.OutputEncoding = System.Text.Encoding.UTF8;

for some characters you need to install extra fonts (ie. Chinese).

In Windows 10 first go to Region & language settings and install support for required language: enter image description here

After that you can go to Command Prompt Proporties (or Defaults if you like) and choose some font that supports your language (like KaiTi in Chinese case): enter image description here

Now you are set to go: enter image description here

References

Console.OutputEncoding Property (System) | Microsoft Docs

Encoding.UTF8 Property (System.Text) | Microsoft Docs

Change Console Foreground And Background Color In C# (c-sharpcorner.com)

C# | How to change Foreground Color of Text in Console - GeeksforGeeks

C# Convert console output UTF-8 to display in textbox - special characters problems (microsoft.com)

Run a C# .NET console application as a windows service

June 1, 2021 22:44

Run a C# .NET console application as a windows service (edit)

Run a C# .NET console application as a windows service

zaagan/HybridSvx: A Hybrid of a Windows Console App And a Windows Service (github.com)

manhng83/HybridSvx: A Hybrid of a Windows Console App And a Windows Service (github.com)

.NET Core

https://blog.computedcloud.com/background-services-in-net-core-console-app/

https://docs.hangfire.io/en/latest/deployment-to-production/making-aspnet-app-always-running.html

Task Scheduler in Windows

Chú ý: Phải add Users cho full quyền truy cập vào thư mục %LocalAppData%\HybridSvx\

How To Create a Scheduled Task in Windows 10 (c-sharpcorner.com)

Windows Admin: Using Task Scheduler to Run Processes Later (howtogeek.com)

Setup A Task Scheduler To Run Application Periodically In C# (c-sharpcorner.com)

Run a C# .NET console application as a windows service

Run a C# .NET console application as a windows service

Deploy to %LocalAppData%\HybridSvx\

This article will guide you through the necessary steps on creating a flexible hybrid application that is a mixture of a console application and a windows service. Takeaways : ⇒ Learn to create a runnable application which can later on be installed as a windows service. ⇒ A working template for your future usages available on Github.

Table Of Contents

Background

Most of the time, when I am assigned a new task like integrating a 3rd party tool or a plugin into my .NET based application, I simply rely on trying it out first hand via a simple Console application and quickly integrating the necessary parts. And that is what probably any .NET developer would do (some might have a different approach).

But, sometimes there are requirements where the task is to create a job or a service with a repetitive flow and made runnable in a scheduled fashion. Some common scenarios are creating a job for delivering messages and updates,  performing backups, doing cleanups and many more of such stuffs.

There are many options to achieve these requirements by using a third party tool. Some of those tools are: Hangfire, Quartz, Topshelf etc.

But, since I would have already tried out and tested the feature via a console application, my next step would be simply to deploy the code as a service. This generally involves, creating a new windows service application and integrating my previously tested code.

But instead of creating a new application, I do some tweaks here and there, improvise the old console application and make it behave as a windows service and vice-versa.  I can then easily install this console app as a windows service into my system whenever I want.

Lets see how it is done …

The Console Application

Basically we start by creating a new console application. Here is a simple console application that simply just writes to a file.

Program.cs file
class Program
{
    static void Main(string[] args)
    {
        DataProcessor dataProcessor = new DataProcessor();
        dataProcessor.Execute();
    }
}
DataProcessor.cs file
using System;
using System.IO;
using System.Reflection;

namespace HybridSvx
{
    internal class DataProcessor
    {

        internal void Execute()
        {
            try
            {
                LogMessage();
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception: " + e.Message);
            }
        }


        /// <summary>
        /// Writes a simple message to a file in the application directory
        /// </summary>
        private void LogMessage()
        {
            string assemblyName = Assembly.GetCallingAssembly().GetName().Name;
            string fileName = string.Format(assemblyName + "-{0:yyyy-MM-dd}.log", DateTime.Now);
            string filePath = AppDomain.CurrentDomain.BaseDirectory + fileName;

            string message = "Execution completed at " + DateTime.Now.ToShortTimeString();

            Console.WriteLine(message);
            using (StreamWriter sw = new StreamWriter(filePath, true))
            {
                sw.WriteLine(message);
                sw.Close();
            }
        }

    }
}

Setting Up The Windows Service

The next step would be to include the necessary libraries and write some code that are required in order to create a windows service. The steps are as follows:

Step 1: Add New Item

In your Visual Studio Console Project ⇒ Right click the project ⇒ Add ⇒ New Item

Add-New-Windows-Service-1
Step 2 : Add a new Windows Service

Search and select Windows Service ⇒ Provide a name eg: ‘HybridSvxService.cs‘ ⇒ Click Add

New-Windows-Service

This will add a new file which will contain your code that needs to be executed by the windows service.

The Windows service needs to be running continuously, else it will automatically stop after it has completed its execution. Hence, in order to make the service run continuously, we will introduce a simple timer as follows :

using System.ServiceProcess;
using System.Timers;

namespace HybridSvx
{
    partial class HybridSvxService : ServiceBase
    {
        private static Timer aTimer;

        public HybridSvxService()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            aTimer = new Timer(10000); // 10 Seconds
            aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            aTimer.Enabled = true;
        }

        private static void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            DataProcessor dataProcessor = new DataProcessor();
            dataProcessor.Execute();
        }

        protected override void OnStop()
        {
            aTimer.Stop();
        }

    }
}
Step 3 : Setup the Installer Class

You first need to add a reference to the System.Configuration.Install assembly via Project ⇒ Add ⇒ Reference.

Next, Add a new Class with a meaningful name eg ‘HybridSvxServiceInstaller.cs‘ and paste in the following code :

using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace HybridSvx
{
    [RunInstaller(true)]
    public class HybridSvxServiceInstaller : Installer
    {
        public HybridSvxServiceInstaller()
        {
            ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller();
            ServiceInstaller serviceInstaller = new ServiceInstaller();

            // Setup the Service Account type per your requirement
            serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
            serviceProcessInstaller.Username = null;
            serviceProcessInstaller.Password = null;

            serviceInstaller.ServiceName = "HybridSvx";
            serviceInstaller.DisplayName = "HybridSvx Service";
            serviceInstaller.StartType = ServiceStartMode.Automatic;
            serviceInstaller.Description = "My custom hybrid service";

            this.Installers.Add(serviceProcessInstaller);
            this.Installers.Add(serviceInstaller);
        }

    }
}

The above code will provide your windows service with the necessary foundation for custom installation like the Service name and description, service account type etc.

Configure Self Installer

Adding a Self installer within the windows service itself, removes the hurdle of depending on a tool like InstallUtil.exe for installation. This makes the installation much easier and straight forward.

In your project, create a new class file with the name SelfInstaller.cs and paste the following code:

using System.Configuration.Install;
using System.Reflection;

namespace HybridSvx
{
    public class SelfInstaller
    {
        private static readonly string _exePath = Assembly.GetExecutingAssembly().Location;
        public static bool InstallMe()
        {
            bool result;
            try
            {
                ManagedInstallerClass.InstallHelper(new string[] {
                    SelfInstaller._exePath
                });
            }
            catch
            {
                result = false;
                return result;
            }
            result = true;
            return result;
        }

        public static bool UninstallMe()
        {
            bool result;
            try
            {
                ManagedInstallerClass.InstallHelper(new string[] {
                    "/u", SelfInstaller._exePath
                });
            }
            catch
            {
                result = false;
                return result;
            }
            result = true;
            return result;
        }

    }
}

Customize Program.cs

The final tweak would be to customize the Program.cs to support the functioning of both a console application and the windows service.

Summary : If you install the application, it will work as a windows service and if you directly run it, it will behave as a console application.

Code :

using System;
using System.ServiceProcess;

namespace HybridSvx
{
    class Program
    {
        static void Main(string[] args)
        {
            if ((!Environment.UserInteractive))
            {
                Program.RunAsAService();
            }
            else
            {
                if (args != null && args.Length > 0)
                {
                    if (args[0].Equals("-i", StringComparison.OrdinalIgnoreCase))
                    {
                        SelfInstaller.InstallMe();
                    }
                    else
                    {
                        if (args[0].Equals("-u", StringComparison.OrdinalIgnoreCase))
                        {
                            SelfInstaller.UninstallMe();
                        }
                        else
                        {
                            Console.WriteLine("Invalid argument!");
                        }
                    }
                }
                else
                {
                    Program.RunAsAConsole();
                }
            }
        }

        static void RunAsAConsole()
        {
            DataProcessor dataProcessor = new DataProcessor();
            dataProcessor.Execute();
        }

        static void RunAsAService()
        {
            ServiceBase[] servicesToRun = new ServiceBase[]
           {
                new HybridSvxService()
           };
            ServiceBase.Run(servicesToRun);
        }


    }
}

Running the Program

Now, you have a working application that can either run as a console application or be installed as a windows service. Here is how you can run the application in both ways :

As a Console Application

Simply double click to run the application

As a Windows Service
  1. Navigate to the project output directory and locate HybridSvx.exe.
  2. Fire up a command prompt with an administrator privilege.
  3. To Install ⇒ type HybridSvx.exe -i
  4. To Uninstall ⇒ type HybridSvx.exe -u
  5. To View the service ⇒ Press Win + R ⇒ type services.msc
Services-msc

Console Application (C#)

May 3, 2018 13:21

C# Console Application in .NET Framework 4.5 (edit)

Display Unicode in console window of a C# Console Application

How to write Unicode characters to the console?
https://stackoverflow.com/questions/5750203/how-to-write-unicode-characters-to-the-console

Size of console application font
https://www.codeproject.com/Questions/626384/Size-of-console-application-font

Changing Console Font Programmatically (HAY)
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/c276b9ae-dc4c-484a-9a59-1ee66cf0f1cc/c-changing-console-font-programmatically?forum=csharpgeneral

Console.OutputEncoding = Encoding.UTF8;

Show/Hide the console window of a C# Console Application

https://amitpatriwala.wordpress.com/2008/04/14/hide-console-application/

https://stackoverflow.com/questions/3571627/show-hide-the-console-window-of-a-c-sharp-console-application

class Program
{
    [DllImport("user32.dll")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    private static void Main(string[] args)
    {
        Console.Title = "eBill.Net";

        IntPtr hWnd = FindWindow(null, "eBill.Net");

        if (hWnd != IntPtr.Zero)
        {
            //Hide the window
            ShowWindow(hWnd, 0); // 0 = SW_HIDE
        }

        ...

    }

}

C# Console Application - Config

Project properties > Build > General

Check into "Allow unsafe code" to display Unicode (UTF8) in console window output

App.Config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<appSettings>
<add key="BareTailExePath" value="D:\Tools\BareTail\baretail.exe" />
</appSettings>
<connectionStrings>
<add name="MainConnectionString" connectionString="Data Source=localhost; Initial Catalog=DbTest; User Id=sa; Password=123456; Persist Security Info=False; MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
</connectionStrings>
<!-- log4net -->
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Logs\\Api.Test.log" />
<appendToFile value="true" />
<encoding value="UTF-8" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="5MB" />
<staticLogFileName value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%date{dd-MM-yy HH:mm:ss} %-5level %message%newline" />
</layout>
</appender>

<appender name="TraceAppender" type="log4net.Appender.TraceAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{dd-MM-yy HH:mm:ss} %-5level %message%newline" />
</layout>
</appender>

<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %message%newline" />
</layout>
</appender>

<root>
<level value="All" />
<appender-ref ref="RollingFileAppender" />
<appender-ref ref="TraceAppender" />
<appender-ref ref="ConsoleAppender" />
</root>
</log4net>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

Properties\AssemblyInfo.cs

[assembly: log4net.Config.XmlConfigurator(Watch = true)]

C# Console Application - Code

using Dapper;
using log4net;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;

namespace Api.Test
{
    internal class Program
    {
        private static readonly HttpClient client = new HttpClient();

        private static void Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;
            Console.ForegroundColor = ConsoleColor.Blue;
            Console.BackgroundColor = ConsoleColor.Yellow;

            string CurrentDir = Directory.GetCurrentDirectory();
            string LogFilePath = Path.Combine(CurrentDir, "Logs", "API.GATEWAY.TEST.log");

            try
            {
                //Xóa trắng log file
                File.WriteAllText(LogFilePath, string.Empty, Encoding.UTF8);
            }
            catch (Exception ex)
            {
                MyLogger.Log.Error(ex.ToString());
                CloseViewLogFile();
                ViewLogFile(LogFilePath);
            }
        }

        public static bool WaitForFileInUse(string filename, TimeSpan timeToWait)
        {
            bool ready = false;

            if (!File.Exists(filename)) ready = true;

            while (!ready)
                try
                {
                    File.Open(filename, FileMode.Open, FileAccess.Write, FileShare.None).Dispose();
                    ready = true;
                }
                catch (IOException)
                {
                    if (timeToWait.TotalMilliseconds <= 0)
                        break;
                    int wait = (int)Math.Min(timeToWait.TotalMilliseconds, 1000.0);
                    timeToWait -= TimeSpan.FromMilliseconds(wait);
                    System.Threading.Thread.Sleep(wait); // sleep one second
                }

            return ready;
        }

        private static void CloseViewLogFile()
        {
            try
            {
                foreach (Process baretail in Process.GetProcessesByName("baretail"))
                    baretail.Kill();
            }
            catch (Exception ex)
            {
                MyLogger.Log.Error(ex.ToString());
            }
        }

        private static void OpenMicrosoftExcel(string file)
        {
            if (!File.Exists(file)) return;
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.FileName = "EXCEL.EXE";
            startInfo.Arguments = file;
            Process.Start(startInfo);
        }

        private static void OpenNotepad2(string file)
        {
            if (!File.Exists(file)) return;
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.FileName = "NOTEPAD2.EXE";
            startInfo.Arguments = file;
            Process.Start(startInfo);
        }

        private static void ViewLogFile(string file)
        {
            if (!File.Exists(file)) return;
            string BareTailExePath = ConfigurationManager.AppSettings["BareTailExePath"];
            if (!File.Exists(BareTailExePath)) return;
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.FileName = BareTailExePath;
            startInfo.Arguments = file;
            Process.Start(startInfo);
        }

        private static void UpdateExcelFile(string filePath, List listInfoSchemaColumns)
        {
            FileInfo file = new FileInfo(filePath);
            using (ExcelPackage excelPackage = new ExcelPackage(file))
            {
                ExcelWorkbook excelWorkBook = excelPackage.Workbook;

                #region Sheet 1: Stored Procedure

                //Sheet 1: Stored Procedure
                List excelWorksheets = excelWorkBook.Worksheets.ToList();

                ExcelWorksheet sheet1 = excelWorksheets[0]; //Sheet 1

                //Update column B2 -> Bn
                for (int i = 0, n = listInfoSchemaColumns.Count; i < n; i++)
                {
                    sheet1.Cells[i + 2, 2].Value = listInfoSchemaColumns[i].COLUMN_NAME;
                }

                #endregion Sheet 1: Stored Procedure

                excelPackage.Save();
            }
        }

        private static void CreateExcelFile(string filePath)
        {
            ExcelPackage ExcelPkg = new ExcelPackage();
            ExcelWorksheet wsSheet1 = ExcelPkg.Workbook.Worksheets.Add("Sheet1");
            using (ExcelRange Rng = wsSheet1.Cells[2, 2, 2, 2])
            {
                Rng.Value = "Welcome to Everyday be coding - tutorials for beginners";
                Rng.Style.Font.Size = 16;
                Rng.Style.Font.Bold = true;
                Rng.Style.Font.Italic = true;
            }
            wsSheet1.Protection.IsProtected = false;
            wsSheet1.Protection.AllowSelectLockedCells = false;
            ExcelPkg.SaveAs(new FileInfo(filePath));
        }
    }

    public class JsonUtils
    {
        public static string SerializeObject(object obj)
        {
            if (obj == null) return string.Empty;

            DefaultContractResolver contractResolver = new DefaultContractResolver
            {
                NamingStrategy = new CamelCaseNamingStrategy()
            };

            return JsonConvert.SerializeObject(obj, new JsonSerializerSettings
            {
                ContractResolver = contractResolver,
                Formatting = Formatting.None
            });
        }

        ///
        /// Convert to JSON object from Stringified value
        ///
        ///
        ///
        /// 
        public static T DeserializeObject(string stringify) where T : class
        {
            if (stringify == null) return null;
            var result = JsonConvert.DeserializeObject(stringify);
            return result;
        }
    }

    internal class MyLogger
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(MyLogger));

        public static ILog Log
        {
            get { return MyLogger.log; }
        }
    }

    #region Models

    public class InfoSchemaColumns
    {
        public string COLUMN_NAME { get; set; }
        public string IS_NULLABLE { get; set; }
        public string DATA_TYPE { get; set; }
    }

    #endregion Models

    #region Data Access Layer

    public class ConnectionFactory : IDisposable
    {
        public static string ConnectionString { get; } = ConfigurationManager.ConnectionStrings["MainConnectionString"].ConnectionString;

        //phương thức trả về đối tượng kết nối
        public static IDbConnection GetInstance()
        {
            IDbConnection connection = new SqlConnection(ConnectionString);
            return connection;
        }

        public void Dispose()
        {
            this.Dispose();
        }
    }

    public class StoredProcedureFactory
    {
        public string Execute(Dictionary<string, object> parameters, string spname)
        {
            var error = "";
            using (var con = ConnectionFactory.GetInstance())
            {
                con.Open();
                var param = new DynamicParameters();
                foreach (var key in parameters.Keys)
                {
                    param.Add(key, parameters[key]);
                }
                param.Add("Error", dbType: DbType.String, size: 4000, direction: ParameterDirection.Output);
                con.Execute(spname, param, commandType: CommandType.StoredProcedure);
                error = param.Get("Error");
            }
            return error;
        }

        public IEnumerable GetList(string spname)
        {
            IEnumerable data;
            using (var con = ConnectionFactory.GetInstance())
            {
                data = con.Query(spname, commandType: CommandType.StoredProcedure);
            }
            return data;
        }

        public T GetOneBy(Dictionary<string, object> parameters, string spname)
        {
            T entity;
            using (var con = ConnectionFactory.GetInstance())
            {
                var param = new DynamicParameters();
                foreach (var key in parameters.Keys)
                {
                    param.Add(key, parameters[key]);
                }
                entity = con.Query(spname, param, commandType: CommandType.StoredProcedure).FirstOrDefault();
            }
            return entity;
        }

        public IEnumerable GetListBy(Dictionary<string, object> parameters, string spname)
        {
            IEnumerable data;
            using (var con = ConnectionFactory.GetInstance())
            {
                var param = new DynamicParameters();
                foreach (var key in parameters.Keys)
                {
                    param.Add(key, parameters[key]);
                }
                data = con.Query(spname, param, commandType: CommandType.StoredProcedure);
            }
            return data;
        }

        public List GetMultiListBy(Dictionary<string, object> parameters, string spname)
        {
            List data = new List();
            using (var con = ConnectionFactory.GetInstance())
            {
                var param = new DynamicParameters();
                foreach (var key in parameters.Keys)
                {
                    param.Add(key, parameters[key]);
                }
                using (var multi = con.QueryMultiple(spname, param, commandType: CommandType.StoredProcedure))
                {
                    var list1 = multi.Read().FirstOrDefault();
                    var list2 = multi.Read().FirstOrDefault();
                    var list3 = multi.Read().FirstOrDefault();
                    var list4 = multi.Read().FirstOrDefault();
                    data.Add(list1);
                    data.Add(list2);
                    data.Add(list3);
                    data.Add(list4);
                }
            }
            return data;
        }
    }

    #endregion Data Access Layer
}

Categories

Recent posts