aspclassic-core/AspClassic.Scripting/Runtime/LanguageConfiguration.cs
Jelle Luteijn 484dbfc9d9 progress
2022-05-15 11:19:49 +02:00

67 lines
2.1 KiB
C#

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<string, object> _options;
private LanguageContext _context;
public LanguageContext LanguageContext => _context;
public AssemblyQualifiedTypeName ProviderName => _providerName;
public string DisplayName => _displayName;
public LanguageConfiguration(AssemblyQualifiedTypeName providerName, string displayName, IDictionary<string, object> 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;
}
}