/// <summary> /// Returns an instance of the <paramref name="type"/>. /// </summary> /// <typeparam name="TParam1">The type of the first parameter to pass to the constructor.</typeparam> /// <typeparam name="TParam2">The type of the second parameter to pass to the constructor.</typeparam> /// <typeparam name="TParam3">The type of the third parameter to pass to the constructor.</typeparam> /// <param name="type">The type to be created.</param> /// <param name="param1">The first parameter to pass to the constructor.</param> /// <param name="param2">The first parameter to pass to the constructor.</param> /// <param name="param3">The first parameter to pass to the constructor.</param> /// <returns>An execution result with an instance of the <paramref name="type"/> if OK, /// otherwise an empty result with exception.</returns> /// <exception cref="ArgumentNullException">The <paramref name="type"/> is null.</exception> /// <exception cref="ArgumentNullException">The <paramref name="param1"/> is null.</exception> /// <exception cref="ArgumentNullException">The <paramref name="param2"/> is null.</exception> /// <exception cref="ArgumentNullException">The <paramref name="param3"/> is null.</exception> public static Optional <object> CreateInstance <TParam1, TParam2, TParam3>( this Type type, TParam1 param1, TParam2 param2, TParam3 param3) where TParam1 : notnull where TParam2 : notnull where TParam3 : notnull { if (type == null) { throw new ArgumentNullException(nameof(type)); } try { var lambdaConstructor = GetLambdaConstructor <Func <TParam1, TParam2, TParam3, object> >( type, new[] { typeof(TParam1), typeof(TParam2), typeof(TParam3) }); return(lambdaConstructor.Invoke(param1, param2, param3)); } catch (Exception exception) when(exception is ArgumentException) { return(OptionalBuilder.Exception <object>(exception)); } }
/// <summary> /// Converts string date to <see cref="DateTime"/> type. /// If error, returns an exception optional. /// </summary> /// <param name="source">A string containing a date and time to convert.</param> /// <param name="provider">An object that supplies culture-specific format information about string.</param> /// <param name="styles"> A bitwise combination of enumeration values that indicates the permitted format /// of string. A typical value to specify is System.Globalization.DateTimeStyles.None.</param> /// <param name="formats">An array of allowable formats of strings.</param> /// <returns>An optional instance.</returns> /// <exception cref="ArgumentNullException">The <paramref name="source"/> is null.</exception> /// <exception cref="ArgumentNullException">The <paramref name="provider"/> is null.</exception> public static Optional <DateTime> ToDateTime( this string source, IFormatProvider provider, DateTimeStyles styles, params string[] formats) { if (source is null) { throw new ArgumentNullException(nameof(source)); } if (provider is null) { throw new ArgumentNullException(nameof(provider)); } try { if (DateTime.TryParseExact(source, formats, provider, styles, out var dateTime)) { return(dateTime); } return(OptionalBuilder.Empty <DateTime>()); } catch (Exception exception) when(exception is ArgumentException) { return(OptionalBuilder.Exception <DateTime>(exception)); } }
/// <summary> /// Invokes the specified member, using the specified binding constraints and matching /// the specified argument list. /// </summary> /// <param name="type"></param> /// <param name="memberName">The string containing the name of the constructor, method, property, or field /// member to invoke. /// -or- /// An empty string ("") to invoke the default /// member. /// -or- /// For IDispatch members, a string representing the DispID, /// for example "[DispID=3]".</param> /// <param name="invokeAttr">A bitmask comprised of one or more System.Reflection.BindingFlags that specify /// how the search is conducted. The access can be one of the BindingFlags such as /// Public, NonPublic, Private, InvokeMethod, GetField, and so on. The type of lookup /// need not be specified. If the type of lookup is omitted, BindingFlags.Public /// | BindingFlags.Instance | BindingFlags.Static are used.</param> /// <param name="binder">An object that defines a set of properties and enables binding, which can involve /// selection of an overloaded method, coercion of argument types, and invocation /// of a member through reflection. /// -or- /// A null reference (Nothing in Visual /// Basic), to use the System.Type.DefaultBinder. Note that explicitly defining a /// System.Reflection.Binder object may be required for successfully invoking method /// overloads with variable arguments.</param> /// <param name="target">The object on which to invoke the specified member.</param> /// <param name="args">An array containing the arguments to pass to the member to invoke.</param> /// <returns>An object representing the return value of the invoked member /// or an empty result with handled exception.</returns> public static Optional <object> TypeInvokeMember( this Type type, string memberName, BindingFlags invokeAttr, Binder binder, object target, object[] args) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (string.IsNullOrWhiteSpace(memberName)) { throw new ArgumentNullException(nameof(memberName)); } try { return(type.InvokeMember(memberName, invokeAttr, binder, target, args, CultureInfo.InvariantCulture)); } catch (Exception exception) when(exception is ArgumentNullException || exception is ArgumentException || exception is MethodAccessException || exception is MissingFieldException || exception is MissingMethodException || exception is TargetException || exception is AmbiguousMatchException || exception is InvalidOperationException) { return(OptionalBuilder.Exception <object>(exception)); } }
/// <summary> /// Converts the current enumeration value to the target one. /// </summary> /// <typeparam name="TEnum">Type of target value.</typeparam> /// <param name="source">The current enumeration value.</param> /// <returns>An new enumeration of <typeparamref name="TEnum"/> type.</returns> /// <exception cref="InvalidOperationException">The conversion failed. See inner exception.</exception> public static Optional <TEnum> ConvertTo <TEnum>(this string source) where TEnum : struct, Enum { try { return((TEnum)Enum.Parse(typeof(TEnum), source)); } catch (OverflowException exception) { return(OptionalBuilder.Exception <TEnum>(exception)); } }
/// <summary> /// Converts a string to a value type. /// </summary> /// <typeparam name="T">Type source.</typeparam> /// <param name="value">The string value.</param> /// <returns>The string value converted to the specified value type.</returns> /// <exception cref="ArgumentNullException">The <paramref name="value"/> is null or empty.</exception> public static Optional <T> ToValueType <T>(this string value) where T : struct, IComparable, IFormattable, IConvertible, IComparable <T>, IEquatable <T> { try { return((T)Convert.ChangeType(value, typeof(T), CultureInfo.CurrentCulture)); } catch (Exception exception) when(exception is InvalidCastException || exception is FormatException || exception is OverflowException) { return(OptionalBuilder.Exception <T>(exception)); } }
/// <summary> /// Returns an instance of the <paramref name="type"/>. /// </summary> /// <param name="type">The type to be created.</param> /// <returns>An execution result with an instance of the <paramref name="type"/> if OK, /// otherwise an empty result with exception.</returns> /// <exception cref="ArgumentNullException">The <paramref name="type"/> is null.</exception> public static Optional <object> CreateInstance(this Type type) { if (type is null) { throw new ArgumentNullException(nameof(type)); } try { var lambdaConstructor = GetLambdaConstructor <Func <object> >(type, Array.Empty <Type>()); return(lambdaConstructor.Invoke()); } catch (Exception exception) when(exception is ArgumentException) { return(OptionalBuilder.Exception <object>(exception)); } }
/// <summary> /// Substitutes the elements of an array of types for the type parameters of the /// current generic type definition and returns a System.Type object representing /// the resulting constructed type. If error, return an optional with exception. /// </summary> /// <param name="type">The type to act on.</param> /// <param name="typeArguments">An array of types to be substituted for the type parameters of the current generic /// type.</param> /// <exception cref="ArgumentNullException">The <paramref name="type"/> is null.</exception> public static Optional <Type> MakeGenericTypeSafe(this Type type, params Type[] typeArguments) { if (type == null) { throw new ArgumentNullException(nameof(type)); } try { return(type.MakeGenericType(typeArguments)); } catch (Exception exception) when(exception is InvalidOperationException || exception is ArgumentException || exception is NotSupportedException) { return(OptionalBuilder.Exception <Type>(exception)); } }
/// <summary> /// Returns the attribute of the <typeparamref name="TAttribute"/> type from the type. /// </summary> /// <typeparam name="TAttribute">Type of attribute.</typeparam> /// <param name="source">enumeration instance to act on.</param> /// <param name="inherit"><see langword="true"/> to inspect the ancestors of element; /// otherwise, <see langword="false"/>.</param> /// <returns>The description string. If not found, returns the enumeration as string.</returns> /// <exception cref="ArgumentNullException">The <paramref name="source"/> is null.</exception> public static Optional <TAttribute> GetAttribute <TAttribute>(this PropertyInfo source, bool inherit = true) where TAttribute : Attribute { if (source is null) { throw new ArgumentNullException(nameof(source)); } try { return(source.GetType().GetTypeInfo().GetCustomAttribute <TAttribute>(inherit)); } catch (Exception exception) when(exception is NotSupportedException || exception is AmbiguousMatchException || exception is TypeLoadException) { return(OptionalBuilder.Exception <TAttribute>(exception)); } }
/// <summary> /// Returns a loaded assembly from its name. /// </summary> /// <param name="assemblyName">The assembly name.</param> /// <returns>If found, returns a loaded assembly otherwise an empty result.</returns> /// <exception cref="ArgumentNullException">The <paramref name="assemblyName"/> is null.</exception> public static Optional <Assembly> AssemblyLoadedFromString(this string assemblyName) { if (assemblyName is null) { throw new ArgumentNullException(nameof(assemblyName)); } try { return(Assembly.Load(assemblyName)); } catch (Exception exception) when(exception is ArgumentException || exception is FileNotFoundException || exception is FileLoadException || exception is BadImageFormatException) { return(OptionalBuilder.Exception <Assembly>(exception)); } }
/// <summary> /// Generates a string of the specified length that contains random characters from the lookup characters. /// <para>The implementation uses the <see cref="RNGCryptoServiceProvider"/>.</para> /// </summary> /// <remarks> /// Inspiration from https://stackoverflow.com/questions/32932679/using-rngcryptoserviceprovider-to-generate-random-string /// </remarks> /// <param name="lookupChar">The string to be used to pick characters from.</param> /// <param name="length">The length of the expected string value.</param> /// <returns>A new string of the specified length with random characters.</returns> /// <exception cref="ArgumentOutOfRangeException">The <paramref name="length"/> is lower or equal to zero.</exception> /// <exception cref="ArgumentNullException">The <paramref name="lookupChar"/> is null.</exception> public static Optional <string> GenerateString(this string lookupChar, int length) { if (length <= 0) { throw new ArgumentOutOfRangeException(nameof(length)); } if (string.IsNullOrWhiteSpace(lookupChar)) { throw new ArgumentNullException(nameof(lookupChar)); } try { var stringResult = new StringBuilder(length); using (var random = new RNGCryptoServiceProvider()) { var count = (int)Math.Ceiling(Math.Log(lookupChar.Length, 2) / 8.0); Diagnostics.Debug.Assert(count <= sizeof(uint)); var offset = BitConverter.IsLittleEndian ? 0 : sizeof(uint) - count; var max = (int)(Math.Pow(2, count * 8) / lookupChar.Length) * lookupChar.Length; var uintBuffer = new byte[sizeof(uint)]; while (stringResult.Length < length) { random.GetBytes(uintBuffer, offset, count); var number = BitConverter.ToUInt32(uintBuffer, 0); if (number < max) { stringResult.Append(lookupChar[(int)(number % lookupChar.Length)]); } } } return(stringResult.ToString()); } catch (Exception exception) when(exception is ArgumentOutOfRangeException || exception is ArgumentException) { return(OptionalBuilder.Exception <string>(exception)); } }
/// <summary> /// Returns type from its string name. /// </summary> /// <param name="typeName">The name of the type to find.</param> /// <returns>if found, returns the type otherwise an empty result.</returns> /// <exception cref="ArgumentNullException">The <paramref name="typeName"/> is null.</exception> public static Optional <Type> TypeFromString(this string typeName) { if (string.IsNullOrWhiteSpace(typeName)) { throw new ArgumentNullException(nameof(typeName)); } try { return(Type.GetType(typeName, true, true)); } catch (Exception exception) when(exception is TargetInvocationException || exception is TypeLoadException || exception is ArgumentException || exception is FileNotFoundException || exception is FileLoadException || exception is BadImageFormatException) { return(OptionalBuilder.Exception <Type>(exception)); } }
/// <summary> /// Converts the value of the current System.DateTime object to its equivalent string /// representation using the specified format and culture-specific format information. /// If error, returns an exception /// </summary> /// <param name="dateTime">The date time to be converted.</param> /// <param name="format">A standard or custom date and time format string.</param> /// <param name="provider">An object that supplies culture-specific formatting information.</param> /// <returns>An optional string representation of value of the current System.DateTime object as specified /// by format and provider.</returns> /// <exception cref="ArgumentNullException">The <paramref name="format"/> is null.</exception> /// <exception cref="ArgumentNullException">The <paramref name="provider"/> is null.</exception> public static Optional <string> DateTimeToString(this DateTime dateTime, string format, IFormatProvider provider) { if (format is null) { throw new ArgumentNullException(nameof(format)); } if (provider is null) { throw new ArgumentNullException(nameof(provider)); } try { return(dateTime.ToString(format, provider)); } catch (Exception exception) when(exception is FormatException || exception is ArgumentOutOfRangeException) { return(OptionalBuilder.Exception <string>(exception)); } }
/// <summary> /// Returns an encrypted string from the value using the specified key. /// <para>The implementation uses the <see cref="SHA512Managed"/>.</para> /// </summary> /// <param name="source">The value to be encrypted.</param> /// <param name="key">The key value to be used for encryption.</param> /// <returns>An encrypted object that contains the encrypted value and its key.</returns> /// <exception cref="ArgumentNullException">The <paramref name="source"/> is null.</exception> /// <exception cref="ArgumentNullException">The <paramref name="key"/> is null.</exception> public static Optional <string> Encrypt(this string source, string key) { if (string.IsNullOrWhiteSpace(source)) { throw new ArgumentNullException(nameof(source)); } if (string.IsNullOrWhiteSpace(key)) { throw new ArgumentNullException(nameof(key)); } try { using var cryptoManaged = new SHA512Managed(); var data = Text.Encoding.UTF8.GetBytes(source); var hash = cryptoManaged.ComputeHash(data); return(BitConverter.ToString(hash).Replace("-", string.Empty, StringComparison.OrdinalIgnoreCase)); } catch (Exception exception) when(exception is Text.EncoderFallbackException || exception is ObjectDisposedException) { return(OptionalBuilder.Exception <string>(exception)); } }
/// <summary> /// Returns the type, if not found, try to load from the assembly. /// </summary> /// <param name="typeName">The name of the type to find.</param> /// <param name="assemblyName">The assembly to act on.</param> /// <returns>if found, returns the type otherwise an empty result.</returns> /// <exception cref="ArgumentNullException">The <paramref name="typeName"/> is null.</exception> /// <exception cref="ArgumentNullException">The <paramref name="assemblyName"/> is null.</exception> public static Optional <Type> TypeFromString(this string typeName, string assemblyName) { if (string.IsNullOrWhiteSpace(assemblyName)) { throw new ArgumentNullException(nameof(assemblyName)); } if (string.IsNullOrWhiteSpace(typeName)) { throw new ArgumentNullException(nameof(typeName)); } var resultFromType = TypeFromString(typeName); if (resultFromType.Any()) { return(resultFromType); } var resultFromAss = AssemblyLoadedFromString(assemblyName); if (resultFromAss.Any()) { var resultLoadedType = resultFromAss.Single() .GetExportedTypes() .FirstOrEmpty(t => t.FullName.Equals(typeName, StringComparison.InvariantCultureIgnoreCase)); return(resultLoadedType .Map(value => value)); } var exception = default(Exception) !; resultFromAss.WhenException(ex => exception = ex); return(OptionalBuilder.Exception <Type>(exception)); }