G9AssemblyManagement 1.4.5

.NET Standard 2.0 .NET Framework 3.5
dotnet add package G9AssemblyManagement --version 1.4.5
NuGet\Install-Package G9AssemblyManagement -Version 1.4.5
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="G9AssemblyManagement" Version="1.4.5" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add G9AssemblyManagement --version 1.4.5
#r "nuget: G9AssemblyManagement, 1.4.5"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install G9AssemblyManagement as a Cake Addin
#addin nuget:?package=G9AssemblyManagement&version=1.4.5

// Install G9AssemblyManagement as a Cake Tool
#tool nuget:?package=G9AssemblyManagement&version=1.4.5

G9TM G9AssemblyManagement

NuGet version (G9AssemblyManagement) Azure DevOps Pipeline Build Status Github Repository

G9AssemblyManagement

❇️Guide

Type Tools

This helper tool provides many various utilities for working by the types.

Tool for getting inherited types from a specified type:

var result = G9Assembly.TypeTools.GetInheritedTypesFromType(typeof(IPAddress));
Console.WriteLine(result.Count); //  1
Console.WriteLine(result[0].Name); // ReadOnlyIPAddress
  • Indeed, the type 'ReadOnlyIPAddress' is derived from the type 'IPAddress.'

This tool checks whether a specified type is a built-in .NET type or not:

// Some built-in .NET Types
var v1 = 1;
var v2 = DateTime.Now;
var v3 = IPAddress.Any;
// Custom type
var v4 = new CustomType();

Console.WriteLine(G9Assembly.TypeTools.IsTypeBuiltInDotNetType(v1.GetType())); // true
Console.WriteLine(G9Assembly.TypeTools.IsTypeBuiltInDotNetType(v1.GetType())); // true
Console.WriteLine(G9Assembly.TypeTools.IsTypeBuiltInDotNetType(v3.GetType())); // true
Console.WriteLine(G9Assembly.TypeTools.IsTypeBuiltInDotNetType(v4.GetType())); // false

A practical tool for changing the type of an object along with an intelligent value-changing process in possible conditions:

// Changes to string and number
var consoleColorString = G9Assembly.TypeTools.SmartChangeType<string>(ConsoleColor.DarkMagenta); 
// "DarkMagenta"
var consoleColorNumber = G9Assembly.TypeTools.SmartChangeType<int>(ConsoleColor.DarkMagenta); 
// 5

// Changes to primary type from string and number
var consoleColor = G9Assembly.TypeTools.SmartChangeType<ConsoleColor>(consoleColorString); 
// ConsoleColor.DarkMagenta
consoleColor = G9Assembly.TypeTools.SmartChangeType<ConsoleColor>(consoleColorNumber); 
// ConsoleColor.DarkMagenta

Instance Tools

This helper tool provides many practical utilities for working by the instances.

We sometimes need to access some instances of an object that aren't specified where they have been created, a process that is a little similar to dependency injection. In this case, this tool provides two ways of doing that.
Sample classes:

// In this scenario, we must inherit the abstract class 'G9AClassInitializer' in our desired classes.

// First sample
public class MyCustomClassA : G9AClassInitializer
{
    public string GetClassName()
    {
        return nameof(MyCustomClassA);
    }
}

// Second sample
public class MyCustomClassB : G9AClassInitializer
{
    public string GetClassName()
    {
        return nameof(MyCustomClassB);
    }
}

First way:

// In the following, each created instance of the above samples is accessible in the following way:

private static void Main()
{
    // MyCustomClassA
    var instance1 = new MyCustomClassA();
    var instance2 = new MyCustomClassA();
    var instance3 = new MyCustomClassA();

    // MyCustomClassB
    var instance4 = new MyCustomClassB();
    var instance5 = new MyCustomClassB();

    var instancesOfClassA = G9Assembly.InstanceTools.GetInstancesOfType<MyCustomClassA>();
    Console.WriteLine(instancesOfClassA.Count); // 3
    Console.WriteLine(instancesOfClassA[0].GetClassName()); // MyCustomClassA

    var instancesOfClassB = G9Assembly.InstanceTools.GetInstancesOfType<MyCustomClassB>();
    Console.WriteLine(instancesOfClassA.Count); // 2
    Console.WriteLine(instancesOfClassA[0].GetClassName()); // MyCustomClassB
}

Second way:

// Or, with a listener, we can control the new instance, removed instance, and exceptions:
private static void Main()
{
     var instanceListener =
        G9Assembly.InstanceTools.AssignInstanceListener<MyCustomClassA>
        (
            // On assign
            newInstance =>
            {
                // Do anything
            },
            // On Unassigning
            instance =>
            {
                // Do anything
            },
            // On receive exception
            ex =>
            {
                // Do anything
            }
        );
}

Sometimes, we need to create an instance of a type that there are many ways depending on the conditions:

// Method to create an instance from a type, first way:
G9Assembly.InstanceTools.CreateInstanceFromType<CustomType>();
// Method to create an instance from a type, second way:
G9Assembly.InstanceTools.CreateInstanceFromType(typeof(CustomType));
// Method to create an instance from a type with the constructor that has parameters
G9Assembly.InstanceTools.CreateInstanceFromTypeWithConstructorParameters(typeof(CustomType), "param1", "param2");
// Method to create an uninitialized instance from a type
G9Assembly.InstanceTools.CreateUninitializedInstanceFromType<IPAddress>();
// Method to create an instance from a generic type
G9Assembly.InstanceTools.CreateInstanceFromGenericType(
    typeof(GenericCustomType<>), typeof(IPAddress));
// Method to create an instance from a generic type with the constructor that has parameters
G9Assembly.InstanceTools.CreateInstanceFromGenericTypeWithConstructorParameters(
    typeof(GenericCustomType<,,>),
    // Custom generic types
    new[] { typeof(IPAddress), typeof(int), typeof(string) },
    // Specifies parameters
    "Param 1", "param 2" );

Reflection Tools

This tool provides many helpful methods for working with object members (reflection). All of the methods shown below have many functional parameters like the access modifier, custom filter, and so on that aren't shown:

// Note: The output of the whole reflection methods below is an array.

// Method to get fields of an object
var fields = G9Assembly.ReflectionTools.GetFieldsOfObject(myCustomObject);
// Method to get properties of an object
var properties = G9Assembly.ReflectionTools.GetPropertiesOfObject(myCustomObject);

// Common methods between fields and properties
Console.WriteLine(fields[0].GetValue()); // Method for getting the value of fields/properties.
properties[0].SetValue("Custom value"); // Method for setting a new value for fields/properties.

// Method to get Methods of an object
var methods = G9Assembly.ReflectionTools.GetMethodsOfObject(myCustomObject)
methods[0].CallMethod(); // method without result
var result1 = methods[1].CallMethodWithResult<int>(
    // If the desired method has parameters.
    6, 3); // method with result.

// Method to get generic methods of an object
var generigMethods = G9Assembly.ReflectionTools.GetGenericMethodsOfObject(object1);
generigMethods[0].CallMethod(); // method without result
var result2 = generigMethods[1].CallMethodWithResult<int>(
    // Specifies the generic types for the method.
    new[] { typeof(int), typeof(string), typeof(IPAddress) },
    // If the desired method has parameters.
    1, "G9TM", IPAddress.Broadcast); // method with result.


// There are also similar methods for working on type members.
// Method to get properties of a type
G9Assembly.ReflectionTools.GetPropertiesOfType(typeof(myCustomObject));
// Method to get fields of a type
G9Assembly.ReflectionTools.GetFieldsOfType(typeof(myCustomObject));
// Method to get properties of a type
G9Assembly.ReflectionTools.GetPropertiesOfType(typeof(myCustomObject));
// Method to get Methods of a type
G9Assembly.ReflectionTools.GetMethodsOfType(typeof(myCustomObject));
// Method to get generic methods of a type
G9Assembly.ReflectionTools.GetGenericMethodsOfType(typeof(myCustomObject));

Merging two objects

The merger tool provides an operational process for merging two objects. With that, you can make a custom process for integrating two things under many conditions. The method of merging is explained below.
Sample classes

public class MyCustomClassA
{
    public int Age = 99;
    public string Name = "St1";
    public DateTime CurrentDateTime = DateTime.Now;
    public float Percent = 99.9f;
}

// Second sample
public class MyCustomClassB
{
    public string Age = "eight";
    public string Name = "St2";
    public DateTime CurrentDateTime = DateTime.Now;
    public string Percent = "39.9f";
}

Method of merging

private static void Main()
{
    var objectA = new MyCustomClassA();
    var objectB = new MyCustomClassB();

    G9Assembly.ObjectAndReflectionTools
    // In this case, the members' values of object B are set on Object A.
    .MergeObjectsValues(objectA, objectB, 
        // Specifies the desired access modifier.
        G9EAccessModifier.Public,
        // Specifies that if two members' values don't have a shared type and can't transfer their values, the process must ignore them.
        // In this case, both objects have the same member with the name "Percent," But in the first one, it's Float, and in the second one, it's String. So, a mismatching occurs, but the core ignores it according to this setting (AllowMismatchValues).
        G9EValueMismatchChecking.AllowMismatchValues, 
        // Specifies that if a mismatch occurs between two members' values, an automatic try to change type must happen or not.
        // If it is set to 'true,' the value of "Percent" will automatically convert from String to Float.
        false, 
        // Specifies a custom filter for searching object's members if needed.
        // In this case, members with the name "CurrentDateTime" are ignored.
        member => member.Name != "CurrentDateTime",
        // Specifies a custom process for desired members if needed.
        // Notice: The function's result specifies whether the custom process handled merging or not.
        // If it's returned 'true.' Specifies that the custom process has done the merging process, and the core mustn't do anything.
        // If it's returned 'false.' Specifies that the custom process skipped the merging process, So the core must do it.
        // In the below case, the custom process just does the merging process on the member with the name "Age":
        (m1, m2) =>
        {
            // For the "Age" member
            if (m1.Name == "Age")
            {
                switch (m2.GetValue<string>())
                {
                    case "nine":
                        m1.SetValue(9);
                        break;
                    case "eight":
                        m1.SetValue(8);
                        break;
                    default:
                        m1.SetValue(0);
                        break;
                }

                // Returns true if the desired process performs the value-changing.
                // In simple words, it's done it.
                return true;
            }

            // Returns false if the value-changing process needs to pass to the core.
            return false;
        });

        // Result
        Console.WriteLine(objectA.Age); // 8
        Console.WriteLine(objectA.Name); // St2
        Console.WriteLine(objectA.Percent); // 99.9
}

Cryptography Tools

This small tool provides the essential methods for cryptography.

There are many hashing methods, and the most practical of them is provided here:

private static void Main()
{
    const string testText = "Programmers never die because they are tiny gods.";
    // message-digest algorithm
    var md5 = G9Assembly.CryptographyTools
        .StringToCustomHash(G9EHashAlgorithm.MD5, testText);
    // Secure Hash Algorithm 1
    var sha1 = G9Assembly.CryptographyTools
        .StringToCustomHash(G9EHashAlgorithm.SHA1, testText);
    // Secure Hash Algorithm 256
    var sha256 = G9Assembly.CryptographyTools
        .StringToCustomHash(G9EHashAlgorithm.SHA256, testText);
    // Secure Hash Algorithm 384
    var sha384 = G9Assembly.CryptographyTools
        .StringToCustomHash(G9EHashAlgorithm.SHA384, testText);
    // Secure Hash Algorithm 512
    var sha512 = G9Assembly.CryptographyTools
        .StringToCustomHash(G9EHashAlgorithm.SHA512, testText);
    // cyclic redundancy checksum
    var crc32 = G9Assembly.CryptographyTools
        .StringToCustomHash(G9EHashAlgorithm.CRC32, testText);
}

And also, there are many cryptography methods, and the most practical of them (AES type) is provided here:

private static void Main()
{
    const string testText = "Programmers never die because they are tiny gods.";
    const string standardKey = "eShVmYp3s6v9y$B&";
    const string standardIv = "gUkXp2s5v8x/A?D(";

    // AES encryption algorithm
    var aesEncryptionText =
        G9Assembly.CryptographyTools
            .AesEncryptString(
                // Specifies plain text.
                testText,
                // Specifies custom private key.
                standardKey,
                // Specifies custom initialization vector.
                standardIv,
                // Specifies the custom config for encryption and decryption.
                // It's optional; by default, the values below are set for that.
                new G9DtAESConfig(
                    paddingMode: PaddingMode.PKCS7,
                    cipherMode: CipherMode.CBC,
                    keySize: 128,
                    blockSize: 128,
                    // Specifies that if the key size isn't standard. The process must fix it or not. (With an arbitrary process)
                    enableAutoFixKeySize: false
                ));

    // Note: The only differences between the above and below methods are two things.
    // The first one is their name, and the second one is their first parameter.

    // AES encryption algorithm
    var aesDecryptionText =
        G9Assembly.CryptographyTools
            .AesDecryptString(
                // Specifies cipher text.
                aesEncryptionText,
                // Specifies custom private key.
                standardKey,
                // Specifies custom initialization vector.
                standardIv,
                // Specifies the custom config for encryption and decryption.
                // It's optional; by default, the values below are set for that.
                new G9DtAESConfig(
                    paddingMode: PaddingMode.PKCS7,
                    cipherMode: CipherMode.CBC,
                    keySize: 128,
                    blockSize: 128,
                    // Specifies that if the key size isn't standard. The process must fix it or not. (With an arbitrary process)
                    enableAutoFixKeySize: false
                ));
}

Performance Tools

A helpful tool that is more used for testing performances.

The first one is used for testing multi-thread requests. It's like a simulated area that runs a custom code block many times:

private static void Main()
{
    var desiredNumberOfRepetitions = 999999;
    G9Assembly.PerformanceTools.MultiThreadShockTest(
        // Provides a random number.
        randomNumber =>
        {
            // Your custom code block for testing.
        },
        // Specifies desired a number of repetitions.
        desiredNumberOfRepetitions
    );
}

The second method compares two code blocks in terms of speed and memory usage:

private static void Main()
{
    // First
    void StringSum1()
    {
        var basisData = string.Empty;
        basisData += "AaA";
        basisData += basisData;
        basisData += basisData;
        basisData += basisData;
        _ = string.IsNullOrEmpty(basisData);
    }

    // Second
    void StringSum2()
    {
        var basisData = string.Empty;
        basisData = basisData + "AaA";
        basisData = basisData + "AaA";
        basisData = basisData + "AaA";
        basisData = basisData + "AaA";
        _ = string.IsNullOrEmpty(basisData);
    }
    
    // Single-core and multi-core test
    var desiredNumberOfRepetitions = 999999;
     var comparativeResult = G9Assembly.PerformanceTools
        .ComparativePerformanceTester(
            // Specifies that test must perform in both states of single-core and multi-core.
            G9EPerformanceTestMode.Both,
            // Specifies desired a number of repetitions.
            desiredNumberOfRepetitions,
            // Specifies the desired code blocks for testing.
            StringSum1, StringSum2);
}
  • Note: The output of this method has many details that are beyond the scope of this article.

Input Output Tools

In simple terms, it provides useful I/O tools.

Checking a path on the computer in terms of validation can consist of many things, like validation, path existence, and drive existence. Here with a method all of them are handled:

private static void Main()
{
    // Note: Assumes that the computer has the I drive but doesn't have the X drive.

    // Directory paths
    const string directory1 = @"I:\Project\!G9TM!\Page";
    const string directory2 = @"\Project\!G9TM!\Page";
    const string directory3 = @"I:\Project\!!!!!!!";
    const string directory4 = @"X:\Project\!G9TM!\Page";
    const string directory5 = @"\asd|asd|asd";

    // Notes about the following methods:
    // Note 1: The second parameter specifies whether the directory drive in terms of existence must be checked or not.
    // Note 2: The third parameter specifies whether the directory path in terms of existence must be checked or not.
    // Note 3: The result of the below methods is an Enum type.

    Console.WriteLine(G9Assembly.InputOutputTools
        .CheckDirectoryPathValidation(directory1, true, false));
    // Result: G9EPatchCheckResult.Correct

    Console.WriteLine(G9Assembly.InputOutputTools
        .CheckDirectoryPathValidation(directory2, true, false));
    // Result: G9EPatchCheckResult.Correct

    Console.WriteLine(G9Assembly.InputOutputTools
        .CheckDirectoryPathValidation(directory3, true, true));
    // Result: G9EPatchCheckResult.PathExistenceIsIncorrect

    Console.WriteLine(G9Assembly.InputOutputTools
        .CheckDirectoryPathValidation(directory4, true, true));
    // Result: G9EPatchCheckResult.PathDriveIsIncorrect

    Console.WriteLine(G9Assembly.InputOutputTools
        .CheckDirectoryPathValidation(directory5, true, true));
    // Result: G9EPatchCheckResult.PathNameIsIncorrect

    // File paths
    const string file1 = @"I:\Project\!G9TM!\Page\First.png";
    const string file2 = @"\Project\!G9TM!\Page\First.png";
    const string file3 = @"I:\Project\!!!!!!!\First.png";
    const string file4 = @"X:\Project\!G9TM!\Page\First.png";
    const string file5 = @"\Fi|r|st.png";
    const string file6 = @"okay.png";
    const string file7 = @"okay.p-n|g";

    Console.WriteLine(G9Assembly.InputOutputTools
        .CheckFilePathValidation(file1, false, false));
    // G9EPatchCheckResult.Correct

    Console.WriteLine(G9Assembly.InputOutputTools
        .CheckFilePathValidation(file2, true, false));
    // G9EPatchCheckResult.Correct

    Console.WriteLine(G9Assembly.InputOutputTools
        .CheckFilePathValidation(file3, true, true));
    // G9EPatchCheckResult.PathExistenceIsIncorrect

    Console.WriteLine(G9Assembly.InputOutputTools
        .CheckFilePathValidation(file4, true, true));
    // G9EPatchCheckResult.PathDriveIsIncorrect

    Console.WriteLine(G9Assembly.InputOutputTools
        .CheckFilePathValidation(file5, true, true));
    // G9EPatchCheckResult.PathNameIsIncorrect

    Console.WriteLine(G9Assembly.InputOutputTools
        .CheckFilePathValidation(file6, true, false));
    // G9EPatchCheckResult.Correct

    Console.WriteLine(G9Assembly.InputOutputTools
        .CheckFilePathValidation(file7, true, true));
    // G9EPatchCheckResult.PathNameIsIncorrect

}

Method to make a wait system for access to the file with specified access and custom options.

G9Assembly.InputOutputTools.WaitForAccessToFile(
    // Specifies the full path of desired file.
    filePath,
    // Specifies a callback for invoking.
    // The specified callback invokes when the desired specified access would be available. In addition,
    // it has a parameter that provides a usable opened file stream on your specified file.
    fs =>
    {
        var data = Encoding.UTF8.GetBytes("Programmers never die because they are tiny gods!");
        fs.Write(data, 0, data.Length);
    },
    // Specifies how the operating system should open a file.
    FileMode.CreateNew,
    // Defines constants for read, write, or read/write access to a file.
    FileAccess.Write,
    // Contains constants for controlling the kind of access other objects can have to the same file.
    FileShare.Write,
    // Specifies how many times must be tried.
    9,
    // Specifies how much time must be considered between each try in milliseconds.
    99);

END

Be the best you can be; the future depends on it. 🚀

Product Versions
.NET net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows net7.0 net7.0-android net7.0-ios net7.0-maccatalyst net7.0-macos net7.0-tvos net7.0-windows
.NET Core netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1
.NET Standard netstandard2.0 netstandard2.1
.NET Framework net35 net40 net403 net45 net451 net452 net46 net461 net462 net463 net47 net471 net472 net48
MonoAndroid monoandroid
MonoMac monomac
MonoTouch monotouch
Tizen tizen40 tizen60
Xamarin.iOS xamarinios
Xamarin.Mac xamarinmac
Xamarin.TVOS xamarintvos
Xamarin.WatchOS xamarinwatchos
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on G9AssemblyManagement:

Package Downloads
G9JSONHandler

A pretty small .NET library has been developed for working with JSON. This library provides many helpful attributes for members like Comment, Encryption, CustomName, Ordering, Ignoring, CustomParser, etc. On the other hand, with the custom parser structure, you can define your desired parsing process for specific types, or with a preferred config, you can customize the parsing process, which leads to more flexibility.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.4.5 335 9/25/2022
1.4.4.2 705 9/20/2022
1.4.4.1 131 9/20/2022
1.4.4 136 9/19/2022
1.4.3.3 258 9/11/2022
1.4.3.2 156 9/11/2022
1.4.3.1 157 9/11/2022
1.4.2.7 247 9/7/2022
1.4.2.6 267 8/31/2022
1.4.2.5 144 8/31/2022
1.4.2.3 348 8/28/2022
1.4.2.2 345 8/25/2022
1.4.0.1 242 8/20/2022
1.3.3.5 151 8/18/2022
1.3.3.4 146 8/18/2022
1.3.3.2 152 8/17/2022
1.3.3.1 432 8/17/2022
1.2.0 273 8/10/2022
1.1.5 254 8/9/2022
1.1.4 160 8/8/2022
1.1.3 257 8/8/2022
1.1.2 163 8/7/2022
1.1.1 155 8/6/2022
1.1.0 162 8/5/2022
1.0.0.3 164 8/3/2022
1.0.0.1 228 8/19/2021
1.0.0 210 8/19/2021

-- Added I/O Part.
-- Redigned Structure.
-- Completed tests.