using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Text; using SuperSocket.Common; using SuperSocket.SocketBase; using SuperSocket.SocketBase.Config; using SuperSocket.SocketBase.Provider; using SuperSocket.SocketEngine.Configuration; using SuperSocket.SocketBase.Metadata; using Microsoft.Extensions.Logging; namespace SuperSocket.SocketEngine { class AppDomainWorkItemFactoryInfoLoader : WorkItemFactoryInfoLoader { public AppDomainWorkItemFactoryInfoLoader(IConfigurationSource config, ILoggerFactory passedInLogFactory) : base(config, passedInLogFactory) { InitliazeValidationAppDomain(); } public AppDomainWorkItemFactoryInfoLoader(IConfigurationSource config) : base(config) { InitliazeValidationAppDomain(); } //private AppDomain m_ValidationAppDomain; //private TypeValidator m_Validator; private void InitliazeValidationAppDomain() { //m_ValidationAppDomain = AppDomain.CreateDomain("ValidationDomain"); var validatorType = typeof(TypeValidator); //m_Validator = (TypeValidator)m_ValidationAppDomain.CreateInstanceAndUnwrap(validatorType.Assembly.FullName, validatorType.FullName); } protected override string ValidateProviderType(string typeName) { //if (!m_Validator.ValidateTypeName(typeName)) // throw new Exception(string.Format("Failed to load type {0}!", typeName)); return typeName; } protected override ServerTypeMetadata GetServerTypeMetadata(string typeName) { //return m_Validator.GetServerTypeMetadata(typeName); return null; } public override void Dispose() { //if (m_ValidationAppDomain != null) //{ // AppDomain.Unload(m_ValidationAppDomain); // m_ValidationAppDomain = null; //} base.Dispose(); } } class DefaultBootstrapAppDomainWrap : DefaultBootstrap { private IBootstrap m_Bootstrap; public DefaultBootstrapAppDomainWrap(IBootstrap bootstrap, IConfigurationSource config, string startupConfigFile) : base(config, startupConfigFile) { m_Bootstrap = bootstrap; } protected override IWorkItem CreateWorkItemInstance(string serviceTypeName, StatusInfoAttribute[] serverStatusMetadata) { return null; } internal override bool SetupWorkItemInstance(IWorkItem workItem, WorkItemFactoryInfo factoryInfo) { return workItem.Setup(m_Bootstrap, factoryInfo.Config, factoryInfo.ProviderFactories.ToArray()); } internal override WorkItemFactoryInfoLoader GetWorkItemFactoryInfoLoader(IConfigurationSource config, ILoggerFactory logFactory) { return new AppDomainWorkItemFactoryInfoLoader(config, logFactory); } } /// /// AppDomainBootstrap /// partial class AppDomainBootstrap : MarshalByRefObject, SocketBase.ILoggerProvider, IBootstrap, IDisposable { private IBootstrap m_InnerBootstrap; /// /// Gets all the app servers running in this bootstrap /// public IEnumerable AppServers { get { return m_InnerBootstrap.AppServers; } } /// /// Gets the config. /// public IRootConfig Config { get { return m_InnerBootstrap.Config; } } /// /// Gets the bootstrap logger. /// ILogger SocketBase.ILoggerProvider.Logger { get { var loggerProvider = m_InnerBootstrap as SocketBase.ILoggerProvider; if (loggerProvider == null) return null; return loggerProvider.Logger; } } /// /// Gets the startup config file. /// public string StartupConfigFile { get { return m_InnerBootstrap.StartupConfigFile; } } /// /// Initializes a new instance of the class. /// public AppDomainBootstrap(IConfigurationSource config) { string startupConfigFile = string.Empty; if (config == null) throw new ArgumentNullException("config"); var configSectionSource = config as ConfigurationSection; if (configSectionSource != null) startupConfigFile = configSectionSource.GetConfigSource(); //Keep serializable version of configuration if(!config.GetType().IsSerializable) config = new ConfigurationSource(config); //Still use raw configuration type to bootstrap m_InnerBootstrap = CreateBootstrapWrap(this, config, startupConfigFile); AppDomain.CurrentDomain.SetData("Bootstrap", this); } protected virtual IBootstrap CreateBootstrapWrap(IBootstrap bootstrap, IConfigurationSource config, string startupConfigFile) { return new DefaultBootstrapAppDomainWrap(this, config, startupConfigFile); } /// /// Initializes the bootstrap with the configuration /// /// public bool Initialize() { return m_InnerBootstrap.Initialize(); } /// /// Initializes the bootstrap with the configuration and config resolver. /// /// The server config resolver. /// public bool Initialize(Func serverConfigResolver) { return m_InnerBootstrap.Initialize(serverConfigResolver); } /// /// Initializes the bootstrap with the configuration and config resolver. /// /// The log factory. /// public bool Initialize(ILoggerFactory logFactory) { return m_InnerBootstrap.Initialize(logFactory); } /// /// Initializes the bootstrap with a listen endpoint replacement dictionary /// /// The listen end point replacement. /// public bool Initialize(IDictionary listenEndPointReplacement) { return m_InnerBootstrap.Initialize(listenEndPointReplacement); } /// /// Initializes the bootstrap with the configuration /// /// The server config resolver. /// The log factory. /// public bool Initialize(Func serverConfigResolver, ILoggerFactory logFactory) { if (logFactory != null) throw new Exception("You cannot pass in logFactory, if your isolation level is AppDomain!"); return m_InnerBootstrap.Initialize(serverConfigResolver, logFactory); } /// /// Starts this bootstrap. /// /// public StartResult Start() { return m_InnerBootstrap.Start(); } /// /// Stops this bootstrap. /// public void Stop() { m_InnerBootstrap.Stop(); } public string BaseDirectory { get { return m_InnerBootstrap.BaseDirectory; } } void IDisposable.Dispose() { var disposableBootstrap = m_InnerBootstrap as IDisposable; if (disposableBootstrap != null) disposableBootstrap.Dispose(); } } }