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();
}
}
}