예제 #1
0
        private static (SiloConfigOption, OrleansProviderOption, OrleansDashboardOption) GetServerConfig(IConfigurationSection config)
        {
            var siloConfigOption = new SiloConfigOption();

            config.GetSection("SiloConfig").Bind(siloConfigOption);

            var orleansProviderOption = new OrleansProviderOption();

            config.GetSection("Provider").Bind(orleansProviderOption);

            var orleansDashboardOption = new OrleansDashboardOption();

            config.GetSection("Dashboard").Bind(orleansDashboardOption);

            return(siloConfigOption, orleansProviderOption, orleansDashboardOption);
        }
예제 #2
0
        private static ISiloBuilder ApplyOrleansDashboard(this ISiloBuilder siloBuilder, OrleansDashboardOption orleansDashboard, ILogger logger)
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                try
                {
                    var helper = new ExtMethodInvoker("Orleans.TelemetryConsumers.Linux");
                    siloBuilder = helper.Invoke <ISiloBuilder>(
                        new ExtMethodInfo {
                        MethodName = "UseLinuxEnvironmentStatistics", ExtendedType = typeof(ISiloBuilder)
                    },
                        siloBuilder);
                }
                catch (Exception exception)
                {
                    throw new LinuxTelemetryLibLoadFailedException(exception);
                }
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                try
                {
                    var helper = new ExtMethodInvoker("Orleans.TelemetryConsumers.Counters");
                    siloBuilder = helper.Invoke <ISiloBuilder>(
                        new ExtMethodInfo {
                        MethodName = "UsePerfCounterEnvironmentStatistics", ExtendedType = typeof(ISiloBuilder)
                    },
                        siloBuilder);
                }
                catch (Exception exception)
                {
                    throw new WindowsPerformanceCountersTelemetryLibLoadFailedException(exception);
                }
            }

            logger.LogInformation($"Enable Orleans Dashboard on this host {orleansDashboard.Port} port");

            try
            {
#if NETCOREAPP2_1
                var helper = new ExtMethodInvoker("GranDen.Orleans.NetCoreGenericHost.OrleansDashboard");
                var dashboardOptionsType = helper.ExtensionLibAssembly.GetType("GranDen.Orleans.NetCoreGenericHost.OrleansDashboard.DashboardOptions", true);
#else
                var helper = new ExtMethodInvoker("OrleansDashboard");
                var dashboardOptionsType = helper.ExtensionLibAssembly.GetType("OrleansDashboard.DashboardOptions", true);
#endif
                var configAction =
                    CreateDelegateHelper.CreateAssignValueAction(dashboardOptionsType, "options", new Dictionary <string, object> {
                    ["Port"] = orleansDashboard.Port
                });

                siloBuilder = helper.Invoke <ISiloBuilder>(
                    new ExtMethodInfo {
                    MethodName = "UseDashboard", ExtendedType = typeof(ISiloBuilder)
                },
                    siloBuilder, configAction);

                return(siloBuilder);
            }
            catch (Exception exception)
            {
                throw new DashboardLoadFailedException(exception);
            }
        }
예제 #3
0
        /// <summary>
        /// Actual implementation of SiloBuilder various configuration
        /// </summary>
        /// <param name="siloBuilder"></param>
        /// <param name="siloConfig"></param>
        /// <param name="orleansProvider"></param>
        /// <param name="grainLoadOption"></param>
        /// <param name="orleansDashboard"></param>
        /// <param name="logger"></param>
        /// <returns></returns>
        public static ISiloBuilder ConfigSiloBuilder(this ISiloBuilder siloBuilder,
                                                     SiloConfigOption siloConfig, OrleansProviderOption orleansProvider, GrainLoadOption grainLoadOption,
                                                     OrleansDashboardOption orleansDashboard, ILogger logger)
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                if (IsRunningOnContainer())
                {
                    // Default config will cause bug when running on Linux Docker Container:
                    // https://github.com/dotnet/orleans/issues/5552#issuecomment-486938815
                    logger.LogInformation("Running in Linux Container, turn off \"FastKillOnProcessExit\" setting.");
                    siloBuilder.Configure <ProcessExitHandlingOptions>(options =>
                    {
                        options.FastKillOnProcessExit = false;
                    });
                }
            }

            if (IsRunningOnContainer())
            {
                logger.LogInformation("Running in Container, use autodetect Dns Host Name instead of configuration");
                siloBuilder.ConfigureEndpoints(Dns.GetHostName(), siloConfig.SiloPort, siloConfig.GatewayPort,
                                               listenOnAnyHostAddress: siloConfig.ListenOnAnyHostAddress);
            }
            else if (IpAddressNotSpecified(siloConfig.AdvertisedIp))
            {
                siloBuilder.ConfigureEndpoints(siloConfig.SiloPort, siloConfig.GatewayPort,
                                               listenOnAnyHostAddress: siloConfig.ListenOnAnyHostAddress);
            }
            else
            {
                try
                {
                    var advertisedIp = IPAddress.Parse(siloConfig.AdvertisedIp.Trim());
                    siloBuilder.ConfigureEndpoints(advertisedIp, siloConfig.SiloPort, siloConfig.GatewayPort,
                                                   siloConfig.ListenOnAnyHostAddress);
                }
                catch (FormatException)
                {
                    siloBuilder.ConfigureEndpoints(Dns.GetHostName(), siloConfig.SiloPort, siloConfig.GatewayPort,
                                                   listenOnAnyHostAddress: siloConfig.ListenOnAnyHostAddress);
                }
            }

            if (orleansDashboard.Enable)
            {
                siloBuilder.ApplyOrleansDashboard(orleansDashboard, logger);
            }

            if (!string.IsNullOrEmpty(siloConfig.SiloName))
            {
                siloBuilder.Configure <SiloOptions>(options => { options.SiloName = siloConfig.SiloName; });
            }

            siloBuilder.Configure <StatisticsOptions>(options =>
            {
                options.CollectionLevel = StatisticsLevel.Critical;
            });

            siloBuilder.Configure <SiloMessagingOptions>(options =>
            {
                options.ResponseTimeout             = TimeSpan.FromMinutes(siloConfig.ResponseTimeoutMinutes);
                options.ResponseTimeoutWithDebugger = TimeSpan.FromMinutes(siloConfig.ResponseTimeoutMinutes + 60);
            }).Configure <ClusterOptions>(options =>
            {
                options.ClusterId = siloConfig.ClusterId;
                options.ServiceId = siloConfig.ServiceId;
            });

            if (!string.IsNullOrEmpty(siloConfig.AzureApplicationInsightKey))
            {
                try
                {
                    var helper = new ExtMethodInvoker("Orleans.TelemetryConsumers.AI");
                    siloBuilder = helper.Invoke <ISiloBuilder>(
                        new ExtMethodInfo {
                        MethodName = "AddApplicationInsightsTelemetryConsumer", ExtendedType = typeof(ISiloBuilder)
                    },
                        siloBuilder, siloConfig.AzureApplicationInsightKey);
                }
                catch (Exception exception)
                {
                    throw new AzureApplicationInsightLibLoadFailedException(exception);
                }
            }

            if (siloConfig.IsMultiCluster.HasValue && siloConfig.IsMultiCluster.Value)
            {
                if (siloConfig.GossipChannels == null || siloConfig.GossipChannels.Any())
                {
                    throw new OrleansSiloHostConfigException("Gossip Channels configuration value(s) required.");
                }

                siloBuilder.Configure <MultiClusterOptions>(options =>
                {
                    options.HasMultiClusterNetwork = true;

                    if (siloConfig.DefaultMultiCluster != null && siloConfig.DefaultMultiCluster.Any())
                    {
                        options.DefaultMultiCluster = siloConfig.DefaultMultiCluster;
                    }
                    else
                    {
                        options.DefaultMultiCluster.Add(siloConfig.ClusterId);
                    }

                    options.GossipChannels = siloConfig.GossipChannels;
                    options.UseGlobalSingleInstanceByDefault = siloConfig.UseGlobalSingleInstanceByDefault;
                });
            }

            var dllPaths = grainLoadOption.LoadPaths.Select(PathResolver).ToList();

            if (dllPaths.Count > 0)
            {
                PlugInLoaderCache = new Dictionary <string, PluginLoader>(dllPaths.Count);
            }

            siloBuilder.ConfigureApplicationParts(parts =>
            {
                parts.AddFromApplicationBaseDirectory().WithReferences();

                if (dllPaths.Count > 0)
                {
                    foreach (var assembly in dllPaths.Select(GetNonMainExeFolderAssembly))
                    {
                        if (assembly.GetTypes().Select(t => t.Namespace).Any(x => x == "OrleansGeneratedCode"))
                        {
                            parts.AddDynamicPart(assembly);
                        }
                        else
                        {
                            throw new OrleansSiloHostConfigException(
                                $"Module \'{dllPaths}\' has no orleans support code gen");
                        }
                    }
                }
            });

            foreach (var serviceConfigAction in GetGrainServiceConfigurationAction(grainLoadOption, PathResolver))
            {
                logger.LogInformation($"Configure DI using {serviceConfigAction}");

                siloBuilder.ConfigureApplicationParts(serviceConfigAction.AppPartConfigurationAction);

                var diConfigAction = serviceConfigAction.ServiceConfigurationAction;

                if (diConfigAction != null)
                {
                    siloBuilder.ConfigureServices(diConfigAction);
                }
            }

            if (siloConfig.ExlcudeGrains.Any())
            {
                siloBuilder.Configure <GrainClassOptions>(options =>
                {
                    options.ExcludedGrainTypes.AddRange(siloConfig.ExlcudeGrains);
                });
            }

            switch (orleansProvider.DefaultProvider)
            {
            case "MongoDB":
            {
                var mongoDbConfig = orleansProvider.MongoDB;

                var mongoDbClusterConfig  = mongoDbConfig.Cluster;
                var mongoDbStorageConfig  = mongoDbConfig.Storage;
                var mongoDbReminderConfig = mongoDbConfig.Reminder;

                ExtMethodInvoker helper;
                try
                {
                    helper = new ExtMethodInvoker("Orleans.Providers.MongoDB");

                    if (!string.IsNullOrEmpty(mongoDbClusterConfig.DbConn))
                    {
                        siloBuilder = helper.Invoke <ISiloBuilder>(
                            new ExtMethodInfo
                            {
                                MethodName = "UseMongoDBClient", ExtendedType = typeof(ISiloBuilder)
                            },
                            siloBuilder, mongoDbClusterConfig.DbConn);
                    }
                    else if (!string.IsNullOrEmpty(mongoDbStorageConfig.DbConn))
                    {
                        siloBuilder = helper.Invoke <ISiloBuilder>(
                            new ExtMethodInfo
                            {
                                MethodName = "UseMongoDBClient", ExtendedType = typeof(ISiloBuilder)
                            },
                            siloBuilder, mongoDbStorageConfig.DbConn);
                    }
                    else if (!string.IsNullOrEmpty(mongoDbReminderConfig.DbConn))
                    {
                        siloBuilder = helper.Invoke <ISiloBuilder>(
                            new ExtMethodInfo
                            {
                                MethodName = "UseMongoDBClient", ExtendedType = typeof(ISiloBuilder)
                            },
                            siloBuilder, mongoDbReminderConfig.DbConn);
                    }
                }
                catch (Exception ex)
                {
                    throw new MongoDbLibLoadFailedException(ex);
                }

                try
                {
                    var mongoDbMembershipTableOptionsType =
                        helper.ExtensionLibAssembly.GetType(
                            "Orleans.Providers.MongoDB.Configuration.MongoDBMembershipTableOptions", true);
                    var mongoDbMembershipTableOptionsValue = new Dictionary <string, object>
                    {
                        ["DatabaseName"] = mongoDbClusterConfig.DbName
                    };
                    if (!string.IsNullOrEmpty(mongoDbClusterConfig.CollectionPrefix))
                    {
                        mongoDbMembershipTableOptionsValue["CollectionPrefix"] =
                            mongoDbClusterConfig.CollectionPrefix;
                    }

                    var configMongoDbClusteringAction =
                        CreateDelegateHelper.CreateAssignValueAction(mongoDbMembershipTableOptionsType, "options",
                                                                     mongoDbMembershipTableOptionsValue);

                    siloBuilder = helper.Invoke <ISiloBuilder>(
                        new ExtMethodInfo
                        {
                            MethodName = "UseMongoDBClustering", ExtendedType = typeof(ISiloBuilder)
                        },
                        siloBuilder, configMongoDbClusteringAction);
                }
                catch (Exception ex)
                {
                    throw new MongoDbClusterLibLoadFailedException(ex);
                }

                try
                {
                    var mongoDbGrainStorageOptionsType =
                        helper.ExtensionLibAssembly.GetType(
                            "Orleans.Providers.MongoDB.Configuration.MongoDBGrainStorageOptions", true);
                    var mongoDbGrainStorageOptionsValue = new Dictionary <string, object>
                    {
                        ["DatabaseName"] = mongoDbStorageConfig.DbName,
                    };
                    if (!string.IsNullOrEmpty(mongoDbStorageConfig.CollectionPrefix))
                    {
                        mongoDbGrainStorageOptionsValue["CollectionPrefix"] = mongoDbStorageConfig.CollectionPrefix;
                    }

                    var configMongoDbGrainStorageAction =
                        CreateDelegateHelper.CreateAssignValueAction(mongoDbGrainStorageOptionsType, "options",
                                                                     mongoDbGrainStorageOptionsValue);

                    siloBuilder = helper.Invoke <ISiloBuilder>(
                        new ExtMethodInfo
                        {
                            MethodName = "AddMongoDBGrainStorage", ExtendedType = typeof(ISiloBuilder)
                        },
                        siloBuilder, "Default", configMongoDbGrainStorageAction);
                }
                catch (Exception ex)
                {
                    throw new MongoDbGrainStorageLibLoadFailedException(ex);
                }

                try
                {
                    var mongoDbRemindersOptionsType =
                        helper.ExtensionLibAssembly.GetType(
                            "Orleans.Providers.MongoDB.Configuration.MongoDBRemindersOptions", true);
                    var mongoDbRemindersOptionsValue = new Dictionary <string, object>
                    {
                        ["DatabaseName"] = mongoDbReminderConfig.DbName
                    };
                    if (!string.IsNullOrEmpty(mongoDbReminderConfig.CollectionPrefix))
                    {
                        mongoDbRemindersOptionsValue["CollectionPrefix"] = mongoDbReminderConfig.CollectionPrefix;
                    }

                    var configMongoDbRemindersAction =
                        CreateDelegateHelper.CreateAssignValueAction(mongoDbRemindersOptionsType, "options",
                                                                     mongoDbRemindersOptionsValue);

                    siloBuilder = helper.Invoke <ISiloBuilder>(
                        new ExtMethodInfo {
                            MethodName = "UseMongoDBReminders", ExtendedType = typeof(ISiloBuilder)
                        },
                        siloBuilder, configMongoDbRemindersAction);
                }
                catch (Exception ex)
                {
                    throw new MongoDbReminderLibLoadFailedException(ex);
                }
            }
            break;

            case "SQLDB":
            {
                var sqlDbConfig = orleansProvider.SQLDB;

                try
                {
                    var clusterExtMethodHelper = new ExtMethodInvoker("Orleans.Clustering.AdoNet");

                    var adoNetClusteringSiloOptionsType =
                        clusterExtMethodHelper.ExtensionLibAssembly.GetType(
                            "Orleans.Configuration.AdoNetClusteringSiloOptions", true);
                    var adoNetClusteringSiloOptionsValue = new Dictionary <string, object>
                    {
                        ["Invariant"]        = sqlDbConfig.Cluster.Invariant ?? @"System.Data.SqlClient",
                        ["ConnectionString"] = sqlDbConfig.Cluster.DbConn
                    };
                    var configAdoNetClusteringAction =
                        CreateDelegateHelper.CreateAssignValueAction(adoNetClusteringSiloOptionsType, "options",
                                                                     adoNetClusteringSiloOptionsValue);
                    siloBuilder = clusterExtMethodHelper.Invoke <ISiloBuilder>(
                        new ExtMethodInfo {
                            MethodName = "UseAdoNetClustering", ExtendedType = typeof(ISiloBuilder)
                        },
                        siloBuilder, configAdoNetClusteringAction);
                }
                catch (Exception ex)
                {
                    throw new SqlServerClusterLibLoadFailedException(ex);
                }

                try
                {
                    var storageExtMethodHelper        = new ExtMethodInvoker("Orleans.Persistence.AdoNet");
                    var adoNetGrainStorageOptionsType =
                        storageExtMethodHelper.ExtensionLibAssembly.GetType(
                            "Orleans.Configuration.AdoNetGrainStorageOptions", true);
                    var adoNetGrainStorageOptionsValue = new Dictionary <string, object>
                    {
                        ["Invariant"]        = sqlDbConfig.Storage.Invariant ?? @"System.Data.SqlClient",
                        ["ConnectionString"] = sqlDbConfig.Storage.DbConn
                    };
                    var configAdoNetStorageAction =
                        CreateDelegateHelper.CreateAssignValueAction(adoNetGrainStorageOptionsType, "options",
                                                                     adoNetGrainStorageOptionsValue);
                    siloBuilder = storageExtMethodHelper.Invoke <ISiloBuilder>(
                        new ExtMethodInfo
                        {
                            MethodName = "AddAdoNetGrainStorage", ExtendedType = typeof(ISiloBuilder)
                        },
                        siloBuilder, "Default", configAdoNetStorageAction);
                }
                catch (Exception ex)
                {
                    throw new SqlServerGrainStorageLibLoadFailedException(ex);
                }

                try
                {
                    var reminderExtMethodHelper        = new ExtMethodInvoker("Orleans.Reminders.AdoNet");
                    var adoNetReminderTableOptionsType =
                        reminderExtMethodHelper.ExtensionLibAssembly.GetType(
                            "Orleans.Configuration.AdoNetReminderTableOptions", true);
                    var adoNetReminderTableOptionsValue = new Dictionary <string, object>
                    {
                        ["Invariant"]        = sqlDbConfig.Reminder.Invariant ?? @"System.Data.SqlClient",
                        ["ConnectionString"] = sqlDbConfig.Reminder.DbConn
                    };
                    var configAdoNetReminderAction =
                        CreateDelegateHelper.CreateAssignValueAction(adoNetReminderTableOptionsType, "options",
                                                                     adoNetReminderTableOptionsValue);
                    siloBuilder = reminderExtMethodHelper.Invoke <ISiloBuilder>(
                        new ExtMethodInfo
                        {
                            MethodName = "UseAdoNetReminderService", ExtendedType = typeof(ISiloBuilder)
                        },
                        siloBuilder, configAdoNetReminderAction);
                }
                catch (Exception ex)
                {
                    throw new SqlServerReminderLibLoadFailedException(ex);
                }
            }
            break;

            case "MYSQL":
            {
                var config = orleansProvider.SQLDB;

                try
                {
                    var clusterExtMethodHelper          = new ExtMethodInvoker("Orleans.Clustering.AdoNet");
                    var adoNetClusteringSiloOptionsType =
                        clusterExtMethodHelper.ExtensionLibAssembly.GetType(
                            "Orleans.Configuration.AdoNetClusteringSiloOptions", true);
                    var adoNetClusteringSiloOptionsValue = new Dictionary <string, object>
                    {
                        ["Invariant"]        = config.Cluster.Invariant ?? @"MySql.Data.MySqlClient",
                        ["ConnectionString"] = config.Cluster.DbConn
                    };
                    var configAdoNetClusteringAction =
                        CreateDelegateHelper.CreateAssignValueAction(adoNetClusteringSiloOptionsType, "options",
                                                                     adoNetClusteringSiloOptionsValue);
                    siloBuilder = clusterExtMethodHelper.Invoke <ISiloBuilder>(
                        new ExtMethodInfo {
                            MethodName = "UseAdoNetClustering", ExtendedType = typeof(ISiloBuilder)
                        },
                        siloBuilder, configAdoNetClusteringAction);
                }
                catch (Exception ex)
                {
                    throw new MySqlClusterLibLoadFailedException(ex);
                }

                try
                {
                    var storageExtMethodHelper        = new ExtMethodInvoker("Orleans.Persistence.AdoNet");
                    var adoNetGrainStorageOptionsType =
                        storageExtMethodHelper.ExtensionLibAssembly.GetType(
                            "Orleans.Configuration.AdoNetGrainStorageOptions", true);
                    var adoNetGrainStorageOptionsValue = new Dictionary <string, object>
                    {
                        ["Invariant"]        = config.Storage.Invariant ?? @"MySql.Data.MySqlClient",
                        ["ConnectionString"] = config.Storage.DbConn
                    };
                    var configAdoNetStorageAction =
                        CreateDelegateHelper.CreateAssignValueAction(adoNetGrainStorageOptionsType, "options",
                                                                     adoNetGrainStorageOptionsValue);
                    siloBuilder = storageExtMethodHelper.Invoke <ISiloBuilder>(
                        new ExtMethodInfo
                        {
                            MethodName = "AddAdoNetGrainStorage", ExtendedType = typeof(ISiloBuilder)
                        },
                        siloBuilder, "Default", configAdoNetStorageAction);
                }
                catch (Exception ex)
                {
                    throw new MySqlGrainStorageLibLoadFailedException(ex);
                }

                try
                {
                    var reminderExtMethodHelper        = new ExtMethodInvoker("Orleans.Reminders.AdoNet");
                    var adoNetReminderTableOptionsType =
                        reminderExtMethodHelper.ExtensionLibAssembly.GetType(
                            "Orleans.Configuration.AdoNetReminderTableOptions", true);
                    var adoNetReminderTableOptionsValue = new Dictionary <string, object>
                    {
                        ["Invariant"]        = config.Reminder.Invariant ?? @"MySql.Data.MySqlClient",
                        ["ConnectionString"] = config.Reminder.DbConn
                    };
                    var configAdoNetReminderAction =
                        CreateDelegateHelper.CreateAssignValueAction(adoNetReminderTableOptionsType, "options",
                                                                     adoNetReminderTableOptionsValue);
                    siloBuilder = reminderExtMethodHelper.Invoke <ISiloBuilder>(
                        new ExtMethodInfo
                        {
                            MethodName = "UseAdoNetReminderService", ExtendedType = typeof(ISiloBuilder)
                        },
                        siloBuilder, configAdoNetReminderAction);
                }
                catch (Exception ex)
                {
                    throw new MySqlReminderLibLoadFailedException(ex);
                }
            }
            break;

            case "InMemory":
            {
                if (IpAddressNotSpecified(siloConfig.AdvertisedIp))
                {
                    siloBuilder.UseDevelopmentClustering(option =>
                        {
                            option.PrimarySiloEndpoint = new IPEndPoint(IPAddress.Loopback, siloConfig.SiloPort);
                        });

                    if (string.IsNullOrEmpty(siloConfig.AdvertisedIp.Trim()) || siloConfig.AdvertisedIp == "*")
                    {
                        siloBuilder.ConfigureEndpoints("localhost", siloConfig.SiloPort, siloConfig.GatewayPort,
                                                       listenOnAnyHostAddress: siloConfig.ListenOnAnyHostAddress);
                    }
                    else
                    {
                        siloBuilder.ConfigureEndpoints(siloConfig.AdvertisedIp, siloConfig.SiloPort,
                                                       siloConfig.GatewayPort, listenOnAnyHostAddress: siloConfig.ListenOnAnyHostAddress);
                    }
                }
                else
                {
                    var advertisedIp = IPAddress.Parse(siloConfig.AdvertisedIp.Trim());
                    siloBuilder.UseDevelopmentClustering(option =>
                        {
                            option.PrimarySiloEndpoint = new IPEndPoint(advertisedIp, siloConfig.SiloPort);
                        })
                    .ConfigureEndpoints(advertisedIp, siloConfig.SiloPort, siloConfig.GatewayPort,
                                        siloConfig.ListenOnAnyHostAddress);
                }

                try
                {
                    siloBuilder.UseInMemoryGrainStorage()
                    .UseInMemoryReminderService();
                }
                catch (Exception ex)
                {
                    throw new InMemoryGrainStorageLibLoadFailedException(ex);
                }
            }
            break;

            default:
            {
                siloBuilder.UseLocalhostClustering(
                    serviceId: siloConfig.ServiceId,
                    clusterId: siloConfig.ClusterId,
                    siloPort: siloConfig.SiloPort,
                    gatewayPort: siloConfig.GatewayPort)
                .UseInMemoryGrainStorage()
                .UseInMemoryReminderService();
            }
            break;
            }

            return(siloBuilder);
        }
예제 #4
0
        private static void ConfigSiloBuilder(ISiloBuilder siloBuilder,
                                              SiloConfigOption siloConfig, OrleansProviderOption orleansProvider, GrainLoadOption grainLoadOption, OrleansDashboardOption orleansDashboard)
        {
            if (orleansDashboard.Enable)
            {
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    siloBuilder.UseLinuxEnvironmentStatistics();
                }

                Log.Information($"Enable Orleans Dashboard (https://github.com/OrleansContrib/OrleansDashboard) on this host {orleansDashboard.Port} port");
                siloBuilder.UseDashboard(options =>
                {
                    options.Port = orleansDashboard.Port;
                });
            }

            if (!string.IsNullOrEmpty(siloConfig.SiloName))
            {
                siloBuilder.Configure <SiloOptions>(options => { options.SiloName = siloConfig.SiloName; });
            }

            siloBuilder.Configure <SiloMessagingOptions>(options =>
            {
                options.ResponseTimeout             = TimeSpan.FromMinutes(siloConfig.ResponseTimeoutMinutes);
                options.ResponseTimeoutWithDebugger = TimeSpan.FromMinutes(siloConfig.ResponseTimeoutMinutes + 60);
            }).Configure <ClusterOptions>(options =>
            {
                options.ClusterId = siloConfig.ClusterId;
                options.ServiceId = siloConfig.ServiceId;
            });

            if (!string.IsNullOrEmpty(siloConfig.AzureApplicationInsightKey))
            {
                siloBuilder.AddApplicationInsightsTelemetryConsumer(siloConfig.AzureApplicationInsightKey);
            }

            if (siloConfig.IsMultiCluster.HasValue && siloConfig.IsMultiCluster.Value)
            {
                if (siloConfig.GossipChannels == null || siloConfig.GossipChannels.Any())
                {
                    throw new OrleansSiloHostConfigException("Gossip Channels configuration value(s) required.");
                }

                siloBuilder.Configure <MultiClusterOptions>(options =>
                {
                    options.HasMultiClusterNetwork = true;

                    if (siloConfig.DefaultMultiCluster != null && siloConfig.DefaultMultiCluster.Any())
                    {
                        options.DefaultMultiCluster = siloConfig.DefaultMultiCluster;
                    }
                    else
                    {
                        options.DefaultMultiCluster.Add(siloConfig.ClusterId);
                    }

                    options.GossipChannels = siloConfig.GossipChannels;
                });
            }

            string pathResolver(string path)
            {
                if (!path.Contains("{GrainLoadPath}"))
                {
                    return(Path.GetFullPath(path, AssemblyUtil.GetCurrentAssemblyPath()));
                }

                var loadPathStr = Environment.GetEnvironmentVariable("GrainLoadPath");

                if (string.IsNullOrEmpty(loadPathStr))
                {
                    return(Path.GetFullPath(path, AssemblyUtil.GetCurrentAssemblyPath()));
                }
                var expendedPathStr = path.Replace("{GrainLoadPath}", loadPathStr);

                var ret = expendedPathStr;

                var envCwd = Environment.CurrentDirectory;
                var cwd    = Directory.GetCurrentDirectory();

                if (!Path.IsPathRooted(expendedPathStr))
                {
                    ret = !string.IsNullOrEmpty(envCwd)
                        ? Path.GetFullPath(expendedPathStr, envCwd)
                        : Path.GetFullPath(ret, cwd);
                }

                return(ret);
            }

            siloBuilder.ConfigureApplicationParts(parts =>
            {
                parts.AddFromApplicationBaseDirectory().WithReferences();

                var dllPaths = grainLoadOption.LoadPaths;

                ConfigOtherFolderGrainLoad(parts, dllPaths, pathResolver);
            });

            foreach (var serviceConfigAction in GetGrainServiceConfigurationAction(grainLoadOption, pathResolver))
            {
                Log.Information($"Configure DI using {serviceConfigAction}");

                siloBuilder.ConfigureApplicationParts(serviceConfigAction.AppPartConfigurationAction);
                siloBuilder.ConfigureServices(serviceConfigAction.ServiceConfigurationAction);
            }

            if (IpAddressNotSpecified(siloConfig.AdvertisedIp))
            {
                siloBuilder.ConfigureEndpoints(siloConfig.SiloPort, siloConfig.GatewayPort,
                                               listenOnAnyHostAddress: siloConfig.ListenOnAnyHostAddress);
            }
            else
            {
                var advertisedIp = IPAddress.Parse(siloConfig.AdvertisedIp.Trim());
                siloBuilder.ConfigureEndpoints(advertisedIp, siloConfig.SiloPort, siloConfig.GatewayPort,
                                               siloConfig.ListenOnAnyHostAddress);
            }

            switch (orleansProvider.DefaultProvider)
            {
            case "MongoDB":
                var mongoDbConfig = orleansProvider.MongoDB;
                siloBuilder.UseMongoDBClustering(options =>
                {
                    var cluster = mongoDbConfig.Cluster;

                    options.ConnectionString = cluster.DbConn;
                    options.DatabaseName     = cluster.DbName;

                    if (!string.IsNullOrEmpty(cluster.CollectionPrefix))
                    {
                        options.CollectionPrefix = cluster.CollectionPrefix;
                    }
                })
                .AddMongoDBGrainStorageAsDefault(optionsBuilder =>
                {
                    var storage = mongoDbConfig.Storage;
                    optionsBuilder.Configure(options =>
                    {
                        options.ConnectionString = storage.DbConn;
                        options.DatabaseName     = storage.DbName;

                        if (!string.IsNullOrEmpty(storage.CollectionPrefix))
                        {
                            options.CollectionPrefix = storage.CollectionPrefix;
                        }
                    });
                })
                .UseMongoDBReminders(options =>
                {
                    var reminder = mongoDbConfig.Reminder;

                    options.ConnectionString = reminder.DbConn;
                    options.DatabaseName     = reminder.DbName;

                    if (!string.IsNullOrEmpty(reminder.CollectionPrefix))
                    {
                        options.CollectionPrefix = reminder.CollectionPrefix;
                    }
                });
                break;

            default:
                siloBuilder.UseLocalhostClustering().UseInMemoryReminderService();
                break;
            }
        }