using System; using System.Collections.Generic; using System.Reflection; using System.Threading; using AspClassic.Scripting.Utils; namespace AspClassic.Scripting.Runtime; internal sealed class LanguageConfiguration { private readonly AssemblyQualifiedTypeName _providerName; private readonly string _displayName; private readonly IDictionary _options; private LanguageContext _context; public LanguageContext LanguageContext => _context; public AssemblyQualifiedTypeName ProviderName => _providerName; public string DisplayName => _displayName; public LanguageConfiguration(AssemblyQualifiedTypeName providerName, string displayName, IDictionary options) { _providerName = providerName; _displayName = displayName; _options = options; } internal LanguageContext LoadLanguageContext(ScriptDomainManager domainManager, out bool alreadyLoaded) { if (_context == null) { Assembly assembly = domainManager.Platform.LoadAssembly(_providerName.AssemblyName.FullName); Type type = assembly.GetType(_providerName.TypeName); if (type == null) { throw new InvalidOperationException($"Failed to load language '{_displayName}': assembly '{assembly.Location}' does not contain type '{_providerName.TypeName}'"); } if (!type.IsSubclassOf(typeof(LanguageContext))) { throw new InvalidOperationException($"Failed to load language '{_displayName}': type '{type}' is not a valid language provider because it does not inherit from LanguageContext"); } LanguageContext value; try { value = (LanguageContext)Activator.CreateInstance(type, domainManager, _options); } catch (TargetInvocationException ex) { throw new TargetInvocationException($"Failed to load language '{_displayName}': {ex.InnerException.Message}", ex.InnerException); } catch (Exception ex2) { throw new InvalidImplementationException(Strings.InvalidCtorImplementation(type, ex2.Message), ex2); } alreadyLoaded = Interlocked.CompareExchange(ref _context, value, null) != null; } else { alreadyLoaded = true; } return _context; } }