350 lines
13 KiB
C#
350 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using Kreta.Core.CustomAttributes;
|
|
|
|
namespace Kreta.Core
|
|
{
|
|
/// <summary>
|
|
/// Extension
|
|
/// </summary>
|
|
public static class Extensions
|
|
{
|
|
#region Convert Extensions
|
|
|
|
/// <summary>
|
|
/// Converts to a bool? value to int
|
|
/// </summary>
|
|
/// <param name="origin">The origin.</param>
|
|
/// <returns></returns>
|
|
public static int ToNullableInt(this bool? origin) => origin == true ? 1 : 0;
|
|
|
|
/// <summary>
|
|
/// Converts to a bool value to int
|
|
/// </summary>
|
|
/// <param name="origin">if set to <c>true</c> [origin].</param>
|
|
/// <returns></returns>
|
|
public static int ToNullableInt(this bool origin) => origin ? 1 : 0;
|
|
|
|
/// <summary>
|
|
/// Converts to a bool? value to int
|
|
/// </summary>
|
|
/// <param name="origin">The origin.</param>
|
|
/// <returns></returns>
|
|
public static int ToBit(this bool? origin) => origin.ToNullableInt();
|
|
|
|
/// <summary>
|
|
/// Converts to a bool value to int
|
|
/// </summary>
|
|
/// <param name="origin">if set to <c>true</c> [origin].</param>
|
|
/// <returns></returns>
|
|
public static int ToBit(this bool origin) => origin.ToNullableInt();
|
|
|
|
/// <summary>
|
|
/// Converts to a int? value to bool
|
|
/// </summary>
|
|
/// <param name="origin">The origin.</param>
|
|
/// <returns></returns>
|
|
public static bool ToBool(this int? origin) => origin == 1;
|
|
|
|
/// <summary>
|
|
/// Converts to a string value to bool
|
|
/// </summary>
|
|
/// <param name="origin">The origin.</param>
|
|
/// <returns></returns>
|
|
public static bool ToBool(this string origin) => string.Equals(origin, "T", StringComparison.OrdinalIgnoreCase) || string.Equals(origin, "TRUE", StringComparison.OrdinalIgnoreCase);
|
|
|
|
/// <summary>
|
|
/// Determines whether [is not null and positive] [the specified value].
|
|
/// </summary>
|
|
/// <param name="value">The value.</param>
|
|
/// <returns></returns>
|
|
public static bool IsNotNullAndPositive(this int? value)
|
|
{
|
|
return value.HasValue && 0 < value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether [is not null and positive] [the specified value].
|
|
/// </summary>
|
|
/// <param name="value">The value.</param>
|
|
/// <returns></returns>
|
|
public static bool IsNotNullAndPositive(this int value)
|
|
{
|
|
return 0 < value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Megvizsgálja, hogy az int? lehetséges EntityId-e (nem null és nagyobb mint 0)
|
|
/// </summary>
|
|
/// <param name="value">The value.</param>
|
|
/// <returns></returns>
|
|
public static bool IsEntityId(this int? value)
|
|
{
|
|
return value.IsNotNullAndPositive();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Megvizsgálja, hogy az int lehetséges EntityId-e (nagyobb mint 0)
|
|
/// </summary>
|
|
/// <param name="value">The value.</param>
|
|
/// <returns></returns>
|
|
public static bool IsEntityId(this int value)
|
|
{
|
|
return 0 < value;
|
|
}
|
|
|
|
public static int? ToNullableInt(this string stringValue)
|
|
{
|
|
if (int.TryParse(stringValue, out int intValue))
|
|
{
|
|
return intValue;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts to a bool? value to bool
|
|
/// </summary>
|
|
/// <param name="value">The origin.</param>
|
|
/// <returns>False when it is null</returns>
|
|
public static bool ToBool(this bool? value)
|
|
{
|
|
return value ?? false;
|
|
}
|
|
|
|
public static string ToSDABoolean(this bool value) => value ? "T" : "F";
|
|
|
|
public static bool? ToNullableBoolean(this int? value) => value.HasValue ? (value.Value == 1) : (bool?)null;
|
|
|
|
#endregion
|
|
|
|
#region Validation Extensions
|
|
|
|
public static bool IsValidEmail(this string value)
|
|
{
|
|
//NOTE: A null-t és az üres string-et is validnak vesszük, ha azt szeretnénk, hogy ezek ne legyenek validok, azokat külön kint kell vizsgálni string.IsNullOrWhiteSpace()-vel!
|
|
bool result = new EmailAddressExtendedAttribute(true, true).IsValid(value);
|
|
return result;
|
|
}
|
|
|
|
public static bool IsValidPhone(this string value)
|
|
{
|
|
//NOTE: A null-t és az üres string-et is validnak vesszük, ha azt szeretnénk, hogy ezek ne legyenek validok, azokat külön kint kell vizsgálni string.IsNullOrWhiteSpace()-vel!
|
|
bool result = new PhoneExtendedAttribute(true, true).IsValid(value);
|
|
return result;
|
|
}
|
|
|
|
public static bool Is18EvesElmult(this DateTime szuletesiIdo)
|
|
{
|
|
bool result = szuletesiIdo.Date.AddYears(18) < DateTime.Today;
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region String Extensions
|
|
|
|
public static string Truncate(this string value, int maxChars)
|
|
{
|
|
return value.Length <= maxChars ? value : value.Substring(0, maxChars - 3) + "...";
|
|
}
|
|
|
|
public static string RemoveDiacritics(this string text)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(text))
|
|
{
|
|
return text;
|
|
}
|
|
|
|
text = text.Normalize(NormalizationForm.FormD);
|
|
|
|
var chars = text
|
|
.Where(c => CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
|
|
.ToArray();
|
|
|
|
return new string(chars).Normalize(NormalizationForm.FormC);
|
|
}
|
|
|
|
public static string ReplaceMultipleSpacesAndTrim(this string text, string defaultValue = null)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(text))
|
|
{
|
|
return defaultValue;
|
|
}
|
|
|
|
//NOTE: "\u00A0" = NO-BREAK SPACE
|
|
// "\u0009" = CHARACTER TABULATION
|
|
// "\u0020" = SPACE
|
|
// Replace-elni kell a NO-BREAK SPACE-eket, mert a SPACE-el nem ekvivalens és jöhet be ilyen adat és okozhat problémát.
|
|
// Replace-elni kell a CHARACTER TABULATION-öket, mert a SPACE-el nem ekvivalens és jöhet be ilyen adat és okozhat problémát.
|
|
// Ezt követően replace-eljük a többszörös szóközöket egyre.
|
|
// Ezt követően trim-elünk.
|
|
string result = Regex.Replace(text.Replace("\u00A0", "\u0020").Replace("\u0009", "\u0020"), @"\s+", " ").Trim();
|
|
if (string.IsNullOrWhiteSpace(result))
|
|
{
|
|
return defaultValue;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static string RemoveSpecialCharacters(this string text)
|
|
=> Regex.Replace(text, @"[ \-'`~!@#$%^&*()_|+=?;:"",.<>{ }[\]\\/]", "");
|
|
|
|
#endregion
|
|
|
|
#region Collection Extensions
|
|
|
|
public static int GetSequenceHashCode<T>(this IReadOnlyCollection<T> sequence)
|
|
{
|
|
if (sequence == null || sequence.Count == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return sequence.Select(item => item.GetHashCode()).Aggregate((total, nextCode) => total ^ nextCode);
|
|
}
|
|
|
|
public static void RemoveRange<T>(this List<T> self, IEnumerable<T> items)
|
|
{
|
|
var exceptItems = self.Except(items).ToList();
|
|
self.Clear();
|
|
self.AddRange(exceptItems);
|
|
}
|
|
|
|
public static bool NotNullAndAny<T>(this IEnumerable<T> enumerable)
|
|
{
|
|
return enumerable != null && enumerable.Any();
|
|
}
|
|
|
|
/// <summary>
|
|
/// A generikus objektumlistában sorba rendezzük az adatokat és beállítjuk a lapozást a bejövő paraméterek alapján reflection-el.
|
|
/// </summary>
|
|
/// <typeparam name="T">A T bármilyen típus lehet.</typeparam>
|
|
/// <param name="itemList">A T típusú objektumlista, amivel dolgozunk. Ha ez az érték null, akkor null-al térünk vissza, hogy ne legyen exception.</param>
|
|
/// <param name="orderDictionary">A dictionary, amiben benne van, hogy mely property-k(Key) alapján és milyen irányba(Value) kell rendezni az adatokat. Ha ez az érték null vagy üres, akkor nincs sorbarendezés, hanem az eredeti sorrenddel dolgozunk tovább.</param>
|
|
/// <param name="firstItemIndex">A lapozáshoz az első elem indexe. Ha ez az érték null, akkor nincs lapozás és visszaadunk minden elemet.</param>
|
|
/// <param name="lastItemIndex">A lapozáshoz az utolsó elem indexe. Ha ez az érték null, akkor nincs lapozás és visszaadunk minden elemet.</param>
|
|
/// <returns></returns>
|
|
public static List<T> SortingAndPaging<T>(this IEnumerable<T> itemList, Dictionary<string, ListSortDirection> orderDictionary = null, int? firstItemIndex = null, int? lastItemIndex = null)
|
|
{
|
|
if (itemList == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
List<T> result;
|
|
if (orderDictionary != null && orderDictionary.Count > 0)
|
|
{
|
|
IOrderedEnumerable<T> orderedList = null;
|
|
bool isOrderBy = true;
|
|
foreach (var orderItem in orderDictionary)
|
|
{
|
|
PropertyInfo propInfo = typeof(T).GetProperty(orderItem.Key);
|
|
if (isOrderBy)
|
|
{
|
|
orderedList = orderItem.Value == ListSortDirection.Ascending ?
|
|
itemList.OrderBy(x => propInfo.GetValue(x, null)) :
|
|
itemList.OrderByDescending(x => propInfo.GetValue(x, null));
|
|
isOrderBy = false;
|
|
}
|
|
else
|
|
{
|
|
orderedList = orderItem.Value == ListSortDirection.Ascending ?
|
|
orderedList.ThenBy(x => propInfo.GetValue(x, null)) :
|
|
orderedList.ThenByDescending(x => propInfo.GetValue(x, null));
|
|
}
|
|
}
|
|
|
|
result = orderedList.ToList();
|
|
}
|
|
else
|
|
{
|
|
result = itemList.ToList();
|
|
}
|
|
|
|
if (firstItemIndex.HasValue && lastItemIndex.HasValue)
|
|
{
|
|
if (firstItemIndex <= lastItemIndex)
|
|
{
|
|
int pageSize = lastItemIndex.Value - firstItemIndex.Value + 1;
|
|
if (pageSize < result.Count)
|
|
{
|
|
result = result.Skip(firstItemIndex.Value).Take(pageSize).ToList();
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
|
|
{
|
|
var keys = new HashSet<TKey>();
|
|
foreach (TSource element in source)
|
|
{
|
|
if (keys.Add(keySelector(element)))
|
|
{
|
|
yield return element;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static IEnumerable<T> Difference<T>(this IEnumerable<T> first, IEnumerable<T> second)
|
|
{
|
|
return first.Except(second).Union(second.Except(first));
|
|
}
|
|
|
|
public static void RemoveDictionaryItemByValue(this Dictionary<string, string> self, string value)
|
|
{
|
|
var valuesList = self.Where(s => s.Value == value).ToList();
|
|
valuesList.ForEach(i => self.Remove(i.Key));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Enumeration Extensions
|
|
|
|
/// <summary>
|
|
/// GetAttribute by Type
|
|
/// </summary>
|
|
/// <typeparam name="T">type of attribute</typeparam>
|
|
/// <returns>type of Attribute</returns>
|
|
public static T GetAttribute<T>(this System.Enum value) where T : Attribute
|
|
{
|
|
return (T)value.GetType()
|
|
.GetMember(value.ToString())[0].GetCustomAttributes(typeof(T), false)
|
|
.FirstOrDefault();
|
|
|
|
}
|
|
/// <summary>
|
|
///Get Display Name Attribute
|
|
/// </summary>
|
|
/// <example> [Display(Name = "xy")]</example>
|
|
/// <returns>xy</returns>
|
|
public static string ToDisplayName(this System.Enum value) => value.GetAttribute<DisplayAttribute>()?.Name;
|
|
|
|
#endregion
|
|
|
|
#region DateTimeExtensions
|
|
|
|
public static DateTime StartOfTheDay(this DateTime dateTime)
|
|
{
|
|
return dateTime.Date;
|
|
}
|
|
|
|
public static DateTime EndOfTheDay(this DateTime dateTime)
|
|
{
|
|
return dateTime.Date.AddDays(1).AddTicks(-1);
|
|
}
|
|
|
|
#endregion DateTimeExtensions
|
|
}
|
|
}
|