Added more documentation. Simplified and cleaned up code. Added new MySqlDataReader extensions to help with reading single rows or many rows. Added more helper session functions and new MySqlCommand extensions.

This commit is contained in:
MattMo 2023-01-30 18:21:30 -08:00
parent c7602f6b0a
commit 2d85bf4d62
9 changed files with 555 additions and 225 deletions

@ -1,4 +1,5 @@
using System;
using MySql.Data.MySqlClient;
using System;
namespace MontoyaTech.MySqlPlus.Example
{
@ -32,19 +33,21 @@ namespace MontoyaTech.MySqlPlus.Example
{
var session = new MySqlSession("server=db.zone2d.com;user=root;database=zone2d;port=3306;password=-+W6!?Kv-6wDL2Vj5f=kC^Q&;SslMode=Required");
//var car = new Car() { Make = "Chevy", Model = "Camaro" };
session.Insert(new Car() { Make = "Chevy", Model = "Camaro", Year = 2011 });
//session.Insert(car);
session.Insert(new Car() { Make = "GMC", Model = "Sierra", Year = 2000 });
//car.Model = null;
var cars = session.GetAll<Car>();
//session.Update(car);
foreach (var car in cars)
Console.WriteLine($"Make: {car.Make}, Model: {car.Model}, Year: {car.Year}");
var car2 = session.Get<Car>(9);
cars[0].Make = "test";
session.Insert(car2);
session.Update(cars[0]);
//session.Delete(car);
foreach (var car in cars)
session.Delete(car);
Console.WriteLine("Done.");
Console.ReadLine();

@ -9,6 +9,11 @@ using System.Threading.Tasks;
namespace MontoyaTech.MySqlPlus
{
/// <summary>
/// The outline of a MySqlColumn attribute that specify's information about a field
/// and how it's setup in a MySql Row.
/// </summary>
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class MySqlColumn : Attribute
{
public bool Id = false;

@ -0,0 +1,66 @@
using Mysqlx.Resultset;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace MontoyaTech.MySqlPlus
{
/// <summary>
/// A set of extensions to help work with MySqlColumns.
/// </summary>
public static class MySqlColumnExtensions
{
/// <summary>
/// Gets the FieldInfo and MySqlColumn for an Id column on a given row and returns
/// whether or not we found it.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="row"></param>
/// <param name="idField"></param>
/// <param name="idColumn"></param>
public static bool GetMySqlId<T>(this T row, out FieldInfo idField, out MySqlColumn idColumn)
{
var type = typeof(T);
return GetMySqlId(type, out idField, out idColumn);
}
/// <summary>
/// Gets the FieldInfo and MySqlColumn for an Id column on a given row type and returns
/// whether or not we found it.
/// </summary>
/// <param name="type"></param>
/// <param name="idField"></param>
/// <param name="idColumn"></param>
/// <returns></returns>
public static bool GetMySqlId(this Type type, out FieldInfo idField, out MySqlColumn idColumn)
{
idField = null;
idColumn = null;
var fields = type.GetFields();
if (fields == null || fields.Length == 0)
return false;
for (int i = 0; i < fields.Length; i++)
{
var column = fields[i].GetCustomAttribute<MySqlColumn>();
if (column != null && column.Id)
{
idField = fields[i];
idColumn = column;
return true;
}
}
return false;
}
}
}

@ -0,0 +1,261 @@
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace MontoyaTech.MySqlPlus
{
/// <summary>
/// A set of extensions to help work with MySqlCommands.
/// </summary>
public static class MySqlCommandExtensions
{
/// <summary>
/// Setups this MySqlCommand to insert a row in the db.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="command"></param>
/// <param name="row"></param>
/// <exception cref="Exception"></exception>
public static void Insert<T>(this MySqlCommand command, T row)
{
//Get the type of T
var type = typeof(T);
//Get the row information.
var rowAttribute = type.GetCustomAttribute<MySqlRow>();
//Get all the fields.
var fields = type.GetFields();
if (fields == null || fields.Length == 0)
throw new Exception("Found no public fields on given row.");
//Start building the query.
var builder = new StringBuilder();
//Write the insert section.
builder.Append($"INSERT INTO `{(rowAttribute == null || string.IsNullOrWhiteSpace(rowAttribute.Name) ? type.Name : rowAttribute.Name)}` ");
//Write the set values section.
builder.Append("SET ");
bool seperate = false;
for (int i = 0; i < fields.Length; i++)
{
var column = fields[i].GetCustomAttribute<MySqlColumn>();
if (column == null)
continue;
//Skip id columns because they are auto incremented.
if (column.Id)
continue;
if (seperate)
builder.Append(", ");
builder.Append($"`{(string.IsNullOrWhiteSpace(column.Name) ? fields[i].Name : column.Name)}` = @{i}");
command.Parameters.AddWithValue($"@{i}", fields[i].GetValue(row));
seperate = true;
}
//Set the command text.
command.CommandText = builder.ToString();
}
/// <summary>
/// Setups this MySqlCommand to update a row in the db.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="command"></param>
/// <param name="row"></param>
/// <exception cref="Exception"></exception>
public static void Update<T>(this MySqlCommand command, T row)
{
//Get the type of T
var type = typeof(T);
//Get the row information.
var rowAttribute = type.GetCustomAttribute<MySqlRow>();
//Get all the fields.
var fields = type.GetFields();
if (fields == null || fields.Length == 0)
throw new Exception("Found no public fields on given row.");
//Start building the query.
var builder = new StringBuilder();
//Write the update section
builder.Append($"UPDATE `{(rowAttribute == null || string.IsNullOrWhiteSpace(rowAttribute.Name) ? type.Name : rowAttribute.Name)}` ");
//Write the set values section
builder.Append("SET ");
FieldInfo idField = null;
MySqlColumn idColumn = null;
bool seperate = false;
for (int i = 0; i < fields.Length; i++)
{
var column = fields[i].GetCustomAttribute<MySqlColumn>();
if (column == null)
continue;
//Skip id columns because they are auto incremented.
if (column.Id)
{
idField = fields[i];
idColumn = column;
continue;
}
if (seperate)
builder.Append(", ");
builder.Append($"`{(string.IsNullOrWhiteSpace(column.Name) ? fields[i].Name : column.Name)}` = @{i}");
command.Parameters.AddWithValue($"@{i}", fields[i].GetValue(row));
seperate = true;
}
//Make sure we have an id column.
if (idField == null)
throw new Exception("Given row does not contain an id column");
//Write the where clause
builder.Append($" WHERE `{(string.IsNullOrWhiteSpace(idColumn.Name) ? idField.Name : idColumn.Name)}`=@id LIMIT 1");
command.Parameters.AddWithValue("@id", idField.GetValue(row));
//Set the command text.
command.CommandText = builder.ToString();
}
/// <summary>
/// Setups this MySqlCommand to get a row from the db by it's id.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="command"></param>
/// <param name="id"></param>
/// <exception cref="Exception"></exception>
public static void Get<T>(this MySqlCommand command, ulong id)
{
//Get the type of T
var type = typeof(T);
//Get the row information.
var rowAttribute = type.GetCustomAttribute<MySqlRow>();
//Get all the fields.
var fields = type.GetFields();
if (fields == null || fields.Length == 0)
throw new Exception("Found no public fields on given row.");
//Get the id field
if (!type.GetMySqlId(out FieldInfo idField, out MySqlColumn idColumn))
throw new Exception("Failed to find the id column on the given row.");
//Set the command text.
command.CommandText = $"SELECT * FROM `{(rowAttribute == null || string.IsNullOrWhiteSpace(rowAttribute.Name) ? type.Name : rowAttribute.Name)}` WHERE `{(string.IsNullOrWhiteSpace(idColumn.Name) ? idField.Name : idColumn.Name)}`=@id LIMIT 1";
//Add the id parameter.
command.Parameters.AddWithValue("@id", id);
}
/// <summary>
/// Setups this MySqlCommand to get all the rows of a given type from the db.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="command"></param>
public static void GetAll<T>(this MySqlCommand command)
{
//Get the type of T
var type = typeof(T);
//Get the row information.
var rowAttribute = type.GetCustomAttribute<MySqlRow>();
//Set the command text.
command.CommandText = $"SELECT * FROM `{(rowAttribute == null || string.IsNullOrWhiteSpace(rowAttribute.Name) ? type.Name : rowAttribute.Name)}`";
}
/// <summary>
/// Setups this MySqlCommand to delete a row from the db by it's id from an instance of the row.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="command"></param>
/// <param name="row"></param>
/// <exception cref="Exception"></exception>
public static void Delete<T>(this MySqlCommand command, T row)
{
//Get the type of T
var type = typeof(T);
//Get the row information.
var rowAttribute = type.GetCustomAttribute<MySqlRow>();
//Start building the query.
var builder = new StringBuilder();
//Write the delete from section
builder.Append($"DELETE FROM `{(rowAttribute == null || string.IsNullOrWhiteSpace(rowAttribute.Name) ? type.Name : rowAttribute.Name)}` ");
//Get the id the column and field info
if (!row.GetMySqlId(out FieldInfo idField, out MySqlColumn idColumn))
throw new Exception("Failed to find Id column on row.");
//Write the where clause
builder.Append($"WHERE `{(string.IsNullOrWhiteSpace(idColumn.Name) ? idField.Name : idColumn.Name)}`=@id LIMIT 1");
//Add the id parameter.
command.Parameters.AddWithValue("@id", idField.GetValue(row));
//Set the command text.
command.CommandText = builder.ToString();
}
/// <summary>
/// Setups this MySqlCommand to delete a row from the db by it's id.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="command"></param>
/// <param name="id"></param>
public static void Delete<T>(this MySqlCommand command, ulong id)
{
//Get the type of T
var type = typeof(T);
//Get the row information.
var rowAttribute = type.GetCustomAttribute<MySqlRow>();
//Start building the query.
var builder = new StringBuilder();
//Write the delete from section
builder.Append($"DELETE FROM `{(rowAttribute == null || string.IsNullOrWhiteSpace(rowAttribute.Name) ? type.Name : rowAttribute.Name)}` ");
//Get the id the column and field info
if (!type.GetMySqlId(out FieldInfo idField, out MySqlColumn idColumn))
throw new Exception("Failed to find Id column on row.");
//Write the where clause
builder.Append($"WHERE `{(string.IsNullOrWhiteSpace(idColumn.Name) ? idField.Name : idColumn.Name)}`=@id LIMIT 1");
//Add the id parameter.
command.Parameters.AddWithValue("@id", id);
//Set the command text.
command.CommandText = builder.ToString();
}
}
}

@ -0,0 +1,131 @@
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace MontoyaTech.MySqlPlus
{
/// <summary>
/// A set of extensions to help work with a MySqlDataReader.
/// </summary>
public static class MySqlDataReaderExtensions
{
/// <summary>
/// Reads a row from a MySqlDataReader and returns an instance of the row.
/// This function will return null if it can't read the row.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="reader"></param>
/// <returns></returns>
public static T Read<T>(this MySqlDataReader reader)
{
var row = typeof(T).CreateInstance<T>();
if (Read<T>(reader, row))
return row;
return default;
}
/// <summary>
/// Reads a row from a MySqlDataReader into an existing instance of a row and
/// returns whether or not it succeeded
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="reader"></param>
/// <param name="row"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static bool Read<T>(this MySqlDataReader reader, T row)
{
if (!reader.Read())
return false;
var type = typeof(T);
var fields = type.GetFields();
if (fields == null || fields.Length == 0)
throw new Exception("Found no public fields on given row.");
for (int i = 0; i < fields.Length; i++)
{
var column = fields[i].GetCustomAttribute<MySqlColumn>();
if (column == null)
continue;
else
column.ReadValue(row, fields[i], reader);
}
return true;
}
/// <summary>
/// Reads a row from a MySqlDataReader and returns whether or not it succeeded.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="reader"></param>
/// <param name="row"></param>
/// <returns></returns>
public static bool Read<T>(this MySqlDataReader reader, out T row)
{
row = default(T);
if (!reader.Read())
return false;
var type = typeof(T);
var fields = type.GetFields();
if (fields == null || fields.Length == 0)
throw new Exception("Found no public fields on given row.");
row = type.CreateInstance<T>();
for (int i = 0; i < fields.Length; i++)
{
var column = fields[i].GetCustomAttribute<MySqlColumn>();
if (column == null)
continue;
else
column.ReadValue(row, fields[i], reader);
}
return true;
}
/// <summary>
/// Reads all the rows from a MySqlDataReader.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="reader"></param>
/// <returns></returns>
public static List<T> ReadAll<T>(this MySqlDataReader reader)
{
var rows = new List<T>();
ReadAll<T>(reader, rows);
return rows;
}
/// <summary>
/// Reads all the rows from a MySqlDataReader into an existing list.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="reader"></param>
/// <param name="rows"></param>
public static void ReadAll<T>(this MySqlDataReader reader, List<T> rows)
{
while (reader.Read<T>(out T row))
rows.Add(row);
}
}
}

@ -6,8 +6,24 @@
<Nullable>disable</Nullable>
<AssemblyName>MontoyaTech.MySqlPlus</AssemblyName>
<RootNamespace>MontoyaTech.MySqlPlus</RootNamespace>
<Title>MontoyaTech.MySqlPlus</Title>
<Version>1.0.0</Version>
<Company>MontoyaTech</Company>
<Description>A simple C# library to help work with MySql.</Description>
<Copyright>MontoyaTech 2023</Copyright>
<PackageProjectUrl>https://code.montoyatech.com/MontoyaTech/MySqlPlus</PackageProjectUrl>
<RepositoryUrl>https://code.montoyatech.com/MontoyaTech/MySqlPlus</RepositoryUrl>
<PackageIcon>Logo_Symbol_Black_Outline.png</PackageIcon>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<None Include="..\Logo_Symbol_Black_Outline.png">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="MySql.Data" Version="8.0.32" />
</ItemGroup>

@ -6,6 +6,11 @@ using System.Threading.Tasks;
namespace MontoyaTech.MySqlPlus
{
/// <summary>
/// The outline of a MySqlRow attribute that is used to specify
/// information about a MySqlRow.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
public class MySqlRow : Attribute
{
public string Name;

@ -63,70 +63,22 @@ namespace MontoyaTech.MySqlPlus
/// <exception cref="Exception"></exception>
public ulong Insert<T>(T row)
{
var command = new MySqlCommand();
//Get the type of T
var type = typeof(T);
//Get the row information.
var rowAttribute = type.GetCustomAttribute<MySqlRow>();
//Get all the fields.
var fields = type.GetFields();
if (fields == null || fields.Length == 0)
throw new Exception("Found no public fields on given row.");
//Start building the query.
var builder = new StringBuilder();
//Write the insert section.
builder.Append($"INSERT INTO `{(rowAttribute == null || string.IsNullOrWhiteSpace(rowAttribute.Name) ? type.Name : rowAttribute.Name)}` ");
//Write the set values section.
builder.Append("SET ");
FieldInfo idField = null;
bool seperate = false;
for (int i = 0; i < fields.Length; i++)
using (var command = new MySqlCommand())
{
var column = fields[i].GetCustomAttribute<MySqlColumn>();
command.Insert(row);
if (column == null)
continue;
this.Connection.ExecuteNonQuery(command);
//Skip id columns because they are auto incremented.
if (column.Id)
if (row.GetMySqlId(out FieldInfo idField, out MySqlColumn idColumn))
{
idField = fields[i];
continue;
if (Type.GetTypeCode(idField.FieldType) == TypeCode.UInt64)
idField.SetValue(row, (ulong)command.LastInsertedId);
else
idField.SetValue(row, command.LastInsertedId);
}
if (seperate)
builder.Append(", ");
builder.Append($"`{(string.IsNullOrWhiteSpace(column.Name) ? fields[i].Name : column.Name)}` = @{i}");
command.Parameters.AddWithValue($"@{i}", fields[i].GetValue(row));
seperate = true;
return (ulong)command.LastInsertedId;
}
//Execute the insert command.
command.CommandText = builder.ToString();
this.Connection.ExecuteNonQuery(command);
//Set the id on the row if we can.
if (idField != null)
{
if (Type.GetTypeCode(idField.FieldType) == TypeCode.UInt64)
idField.SetValue(row, (ulong)command.LastInsertedId);
else
idField.SetValue(row, command.LastInsertedId);
}
return (ulong)command.LastInsertedId;
}
/// <summary>
@ -136,70 +88,12 @@ namespace MontoyaTech.MySqlPlus
/// <param name="row"></param>
public void Update<T>(T row)
{
var command = new MySqlCommand();
//Get the type of T
var type = typeof(T);
//Get the row information.
var rowAttribute = type.GetCustomAttribute<MySqlRow>();
//Get all the fields.
var fields = type.GetFields();
if (fields == null || fields.Length == 0)
throw new Exception("Found no public fields on given row.");
//Start building the query.
var builder = new StringBuilder();
//Write the update section
builder.Append($"UPDATE `{(rowAttribute == null || string.IsNullOrWhiteSpace(rowAttribute.Name) ? type.Name : rowAttribute.Name)}` ");
//Write the set values section
builder.Append("SET ");
FieldInfo idField = null;
MySqlColumn idColumn = null;
bool seperate = false;
for (int i = 0; i < fields.Length; i++)
using (var command = new MySqlCommand())
{
var column = fields[i].GetCustomAttribute<MySqlColumn>();
command.Update(row);
if (column == null)
continue;
//Skip id columns because they are auto incremented.
if (column.Id)
{
idField = fields[i];
idColumn = column;
continue;
}
if (seperate)
builder.Append(", ");
builder.Append($"`{(string.IsNullOrWhiteSpace(column.Name) ? fields[i].Name : column.Name)}` = @{i}");
command.Parameters.AddWithValue($"@{i}", fields[i].GetValue(row));
seperate = true;
this.Connection.ExecuteNonQuery(command);
}
//Make sure we have an id column.
if (idField == null)
throw new Exception("Given row does not contain an id column");
//Write the where clause
builder.Append($" WHERE `{(string.IsNullOrWhiteSpace(idColumn.Name) ? idField.Name : idColumn.Name)}`=@id LIMIT 1");
command.Parameters.AddWithValue("@id", idField.GetValue(row));
//Execute the command.
command.CommandText = builder.ToString();
this.Connection.ExecuteNonQuery(command);
}
/// <summary>
@ -210,7 +104,7 @@ namespace MontoyaTech.MySqlPlus
/// <returns></returns>
public T Get<T>(ulong id)
{
var instance = typeof(T).ForceCreateInstanceFromType<T>();
var instance = typeof(T).CreateInstance<T>();
this.Get<T>(instance, id);
@ -225,67 +119,28 @@ namespace MontoyaTech.MySqlPlus
/// <param name="id"></param>
public void Get<T>(T row, ulong id)
{
var command = new MySqlCommand();
//Get the type of T
var type = typeof(T);
//Get the row information.
var rowAttribute = type.GetCustomAttribute<MySqlRow>();
//Get all the fields.
var fields = type.GetFields();
if (fields == null || fields.Length == 0)
throw new Exception("Found no public fields on given row.");
//Find the id field
FieldInfo idField = null;
MySqlColumn idColumn = null;
for (int i = 0; i < fields.Length; i++)
using (var command = new MySqlCommand())
{
var column = fields[i].GetCustomAttribute<MySqlColumn>();
command.Get<T>(id);
if (column != null && column.Id)
{
idField = fields[i];
idColumn = column;
break;
}
using (var reader = this.Connection.ExecuteReader(command))
reader.Read(row);
}
}
//Make sure we have an id field.
if (idField == null)
throw new Exception("Failed to find id column for row.");
command.CommandText = $"SELECT * FROM `{(rowAttribute == null || string.IsNullOrWhiteSpace(rowAttribute.Name) ? type.Name : rowAttribute.Name)}` WHERE `{(string.IsNullOrWhiteSpace(idColumn.Name) ? idField.Name : idColumn.Name)}`=@id LIMIT 1";
command.Parameters.AddWithValue("@id", id);
using (var reader = this.Connection.ExecuteReader(command))
/// <summary>
/// Gets all the rows of a given type in the db.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public List<T> GetAll<T>()
{
using (var command = new MySqlCommand())
{
if (reader.Read())
{
for (int i = 0; i < fields.Length; i++)
{
var column = fields[i].GetCustomAttribute<MySqlColumn>();
command.GetAll<T>();
if (column == null)
{
continue;
}
else if (column.Id)
{
if (Type.GetTypeCode(fields[i].FieldType) == TypeCode.UInt64)
fields[i].SetValue(row, (ulong)id);
else
fields[i].SetValue(row, (long)id);
}
else
{
column.ReadValue(row, fields[i], reader);
}
}
}
using (var reader = this.Connection.ExecuteReader(command))
return reader.ReadAll<T>();
}
}
@ -296,53 +151,27 @@ namespace MontoyaTech.MySqlPlus
/// <param name="row"></param>
public void Delete<T>(T row)
{
var command = new MySqlCommand();
//Get the type of T
var type = typeof(T);
//Get the row information.
var rowAttribute = type.GetCustomAttribute<MySqlRow>();
//Get all the fields.
var fields = type.GetFields();
if (fields == null || fields.Length == 0)
throw new Exception("Found no public fields on given row.");
//Start building the query.
var builder = new StringBuilder();
//Write the delete from section
builder.Append($"DELETE FROM `{(rowAttribute == null || string.IsNullOrWhiteSpace(rowAttribute.Name) ? type.Name : rowAttribute.Name)}` ");
//Find the id column.
FieldInfo idField = null;
MySqlColumn idColumn = null;
for (int i = 0; i < fields.Length; i++)
using (var command = new MySqlCommand())
{
var column = fields[i].GetCustomAttribute<MySqlColumn>();
command.Delete(row);
if (column != null && column.Id)
{
idField = fields[i];
idColumn = column;
break;
}
this.Connection.ExecuteNonQuery(command);
}
}
//Make sure we found the id
if (idField == null)
throw new Exception("Failed to find id column for row.");
/// <summary>
/// Deletes a row in the db by it's id.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="id"></param>
public void Delete<T>(ulong id)
{
using (var command = new MySqlCommand())
{
command.Delete<T>(id);
//Write the where clause
builder.Append($"WHERE `{(string.IsNullOrWhiteSpace(idColumn.Name) ? idField.Name : idColumn.Name)}`=@id LIMIT 1");
command.Parameters.AddWithValue("@id", idField.GetValue(row));
command.CommandText = builder.ToString();
this.Connection.ExecuteNonQuery(command);
this.Connection.ExecuteNonQuery(command);
}
}
/// <summary>

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
@ -11,7 +12,13 @@ namespace MontoyaTech.MySqlPlus
/// </summary>
internal static class TypeExentions
{
public static T ForceCreateInstanceFromType<T>(this Type type)
/// <summary>
/// Creates an instance of a given type.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="type"></param>
/// <returns></returns>
public static T CreateInstance<T>(this Type type)
{
if (type == null)
return default;
@ -32,6 +39,13 @@ namespace MontoyaTech.MySqlPlus
return default;
}
/// <summary>
/// Converts a given object to a given type with better auto conversion support.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
/// <exception cref="NotSupportedException"></exception>
public static T ConvertToType<T>(this object obj)
{
if (obj == null)