Archive

Archive for July, 2020

300% performance increase on #MySQL inserts in C#

This may be obvious to anybody who frequently uses MySQL in C#, but for someone who’s come from the SQL Server world, you may quickly realise that the connection pool management is not done as well in MySQL as it is in SQL Server. I guess it is something lacking in the MySQL connector.

Anyway, long story short – if your code for inserts in mysql is as follows (pseudocode:)

Foreach(item in collection)

{

Open Connection

Run SQL

Close Connection

}

Then you can have a huge (300%) performance increase by doing the following:

Open Connection

Foreach (item in collection)

{

Run SQL

}

Close Connection

It’s pretty obvious, but you don’t have to do this sort of refactoring with the SQL Server driver, since the connection pool is managed under-the-hood.

Categories: Uncategorized

Designing a .NET application with removable features

Normally, if you remove a class file from an application, it will just break, but let’s imagine, you want to allow that, so that, a sysops engineer can delete sensitive code from your application that may not be required in a given circumstance.

So, to design an application that will allow you to just delete a file without breaking the application, takes alot of forethought, and here’s one possible way of doing it.

TL;DR; here’s the github repo: https://github.com/infiniteloopltd/PluginDemo

So, First off, I’ll describe this proof of concept application. It has two features, Addition and Subtraction, which are named Addition.cs and Subtraction.cs in the Features folder. Either of these files can be deleted, and it won’t break the application, but evidently the ability to perform that operation will be removed.

So, First, I define an Interface, which features must adhere to; as follows;

namespace PluginDemo
{
    public interface IFeature
    {
        string Description { get; }

        int Execute(int a, int b);
    }
}

So, each feature has a Description, and it can perform some numerical operation on two numbers. Here is how Addition.cs implements this interface;

namespace PluginDemo
{
    class Addition : IFeature
    {
        public string Description
        {
            get
            {
                return "Addition";
            }
        }

        public int Execute(int a, int b)
        {
            return a + b;
        }
    }
}

Now, the magic is in the reflection, where we generate a dynamic list at runtime of all classes in the assembly that implement IFeature. (except IFeature itself), which is defined in a class named FeatureManager

using System;
using System.Collections.Generic;
using System.Reflection;

namespace PluginDemo
{
    public static class FeatureManager
    {
        private static readonly List<IFeature> _features = new List<IFeature>();

        static FeatureManager()
        {
            var dll = Assembly.GetExecutingAssembly();
            foreach (var type in dll.GetTypes())
            {
                if (typeof(IFeature).IsAssignableFrom(type) && !type.IsInterface)
                {
                    _features.Add(Activator.CreateInstance(type) as IFeature);
                }
            }
        }

        public static List<IFeature> Features
        {
            get
            {
                return _features;
            }
        }
    }
}

Now, we can list all available features by calling;

foreach (var feature in FeatureManager.Features)
{
   Console.WriteLine(feature.Description);
}

And, we can use this feature list to check for the availability of a feature, and call it, if it is available.

var addition = FeatureManager.Features.FirstOrDefault(f => f.Description == "Addition");
if (addition != null)
{
  Console.WriteLine("1 + 2 = " + addition.Execute(1,2) );
}

Here, as you can see in the above code. If the file, Addition.cs is deleted, then the addition object is null, but no exception is thrown.

Categories: Uncategorized

Print a #PDF from C# using #Spire.NET

There are many ways to print a PDF in C#, but I wanted one that was unobtrusive, and didn’t depend on any particular software being installed on the client machine. – So I’m using Spire.NET

TL DR; Here is the github repo: https://github.com/infiniteloopltd/PrintPDF

I am also using a image printer driver called Joy Image Printer (http://www.joyprinter.com/) – which enables me to test this, witout wasting paper. The output image has watermarking, so it’s not for production, just testing. It’s also unobtrusive, and doesn’t pop up any windows.

So, the first step is that I wanted to list all the printers installed on the client machine, and allow the user select one by number. Then it loads a static PDF into Spire, and calls the print method. The Free version of Spire (https://www.e-iceblue.com/Introduce/pdf-for-net-introduce.html) is limited to 10 pages, but that was fine for my purposes.

var iSelection = 1;
Console.WriteLine(“Which printer do you wish to use:”);
foreach (string printer in PrinterSettings.InstalledPrinters)
{
Console.WriteLine(iSelection + “:” + printer);
iSelection++;
}
iSelection = Convert.ToInt16(Console.ReadLine());
var printerName = PrinterSettings.InstalledPrinters[–iSelection];
// Install-Package Spire.PDF -Version 6.7.6
// http://www.joyprinter.com/index.html — handy for development
var document = new PdfDocument();
document.LoadFromFile(“hello-world.pdf”);
document.PrintSettings.PrinterName = printerName;
document.Print();
document.Dispose();

Categories: Uncategorized