public static object?CreateFromName(string name, params object?[]?args)
{
ArgumentNullException.ThrowIfNull(name);
#if BROWSER
switch (name)
{
#pragma warning disable SYSLIB0021 // Obsolete: derived cryptographic types
// hardcode mapping for SHA* and HMAC* algorithm names from https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.cryptoconfig?view=net-5.0#remarks
case "SHA":
case "SHA1":
case "System.Security.Cryptography.SHA1":
return(new SHA1Managed());
case "SHA256":
case "SHA-256":
case "System.Security.Cryptography.SHA256":
return(new SHA256Managed());
case "SHA384":
case "SHA-384":
case "System.Security.Cryptography.SHA384":
return(new SHA384Managed());
case "SHA512":
case "SHA-512":
case "System.Security.Cryptography.SHA512":
return(new SHA512Managed());
#pragma warning restore SYSLIB0021
case "System.Security.Cryptography.HMAC":
case "HMACSHA1":
case "System.Security.Cryptography.HMACSHA1":
case "System.Security.Cryptography.KeyedHashAlgorithm":
return(new HMACSHA1());
case "HMACSHA256":
case "System.Security.Cryptography.HMACSHA256":
return(new HMACSHA256());
case "HMACSHA384":
case "System.Security.Cryptography.HMACSHA384":
return(new HMACSHA384());
case "HMACSHA512":
case "System.Security.Cryptography.HMACSHA512":
return(new HMACSHA512());
#pragma warning disable SYSLIB0021 // Obsolete: derived cryptographic types
case "AES":
case "System.Security.Cryptography.AesCryptoServiceProvider":
return(new AesCryptoServiceProvider());
case "AesManaged":
case "System.Security.Cryptography.AesManaged":
return(new AesManaged());
case "Rijndael":
case "System.Security.Cryptography.Rijndael":
#pragma warning disable SYSLIB0022 // Rijndael types are obsolete
return(new RijndaelManaged());
#pragma warning restore SYSLIB0022
#pragma warning restore SYSLIB0021
}
return(null);
#else
// Check to see if we have an application defined mapping
appNameHT.TryGetValue(name, out Type? retvalType);
// We allow the default table to Types and Strings
// Types get used for types in .Algorithms assembly.
// strings get used for delay-loaded stuff in other assemblies such as .Csp.
if (retvalType == null && DefaultNameHT.TryGetValue(name, out object?retvalObj))
{
retvalType = retvalObj as Type;
if (retvalType == null)
{
if (retvalObj is string retvalString)
{
retvalType = Type.GetType(retvalString, false, false);
if (retvalType != null && !retvalType.IsVisible)
{
retvalType = null;
}
if (retvalType != null)
{
// Add entry to the appNameHT, which makes subsequent calls much faster.
appNameHT[name] = retvalType;
}
}
else
{
Debug.Fail("Unsupported Dictionary value:" + retvalObj.ToString());
}
}
}
// Special case asking for "ECDsa" since the default map from .NET Framework uses
// a Windows-only type.
if (retvalType == null &&
(args == null || args.Length == 1) &&
name == ECDsaIdentifier)
{
return(ECDsa.Create());
}
// Maybe they gave us a classname.
if (retvalType == null)
{
retvalType = Type.GetType(name, false, false);
if (retvalType != null && !retvalType.IsVisible)
{
retvalType = null;
}
}
// Still null? Then we didn't find it.
if (retvalType == null)
{
return(null);
}
// Locate all constructors.
MethodBase[] cons = retvalType.GetConstructors(ConstructorDefault);
if (cons == null)
{
return(null);
}
if (args == null)
{
args = Array.Empty <object>();
}
List <MethodBase> candidates = new List <MethodBase>();
for (int i = 0; i < cons.Length; i++)
{
MethodBase con = cons[i];
if (con.GetParameters().Length == args.Length)
{
candidates.Add(con);
}
}
if (candidates.Count == 0)
{
return(null);
}
cons = candidates.ToArray();
// Bind to matching ctor.
ConstructorInfo?rci = Type.DefaultBinder.BindToMethod(
ConstructorDefault,
cons,
ref args,
null,
null,
null,
out object?state) as ConstructorInfo;
// Check for ctor we don't like (non-existent, delegate or decorated with declarative linktime demand).
if (rci == null || typeof(Delegate).IsAssignableFrom(rci.DeclaringType))
{
return(null);
}
// Ctor invoke and allocation.
object retval = rci.Invoke(ConstructorDefault, Type.DefaultBinder, args, null);
// Reset any parameter re-ordering performed by the binder.
if (state != null)
{
Type.DefaultBinder.ReorderArgumentArray(ref args, state);
}
return(retval);
#endif
}