예제 #1
0
        /// <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));
            }
        }
예제 #2
0
        /// <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));
            }
        }
예제 #3
0
        /// <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 (&quot;&quot;) to invoke the default
        /// member. /// -or- /// For IDispatch members, a string representing the DispID,
        /// for example &quot;[DispID=3]&quot;.</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));
            }
        }
예제 #4
0
 /// <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));
     }
 }
예제 #5
0
 /// <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));
     }
 }
예제 #6
0
        /// <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));
            }
        }
예제 #7
0
 /// <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));
     }
 }
예제 #8
0
        /// <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));
            }
        }
예제 #9
0
        /// <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));
            }
        }
예제 #10
0
        /// <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));
            }
        }
예제 #11
0
        /// <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));
            }
        }
예제 #12
0
        /// <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));
            }
        }
예제 #13
0
        /// <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));
            }
        }
예제 #14
0
        /// <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));
        }