Beispiel #1
0
        public void InvokeLogAddBuilderMethodWithActionDelegate()
        {
            //Arrange
            const LogLevel     defaultLogLevel     = LogLevel.Information;
            const int          defaultEventId      = 1;
            const ConsoleColor defaultConsoleColor = ConsoleColor.Cyan;
            var serviceCollection = new ServiceCollection();

            //Act
            serviceCollection.AddLogging(loggingBuilder =>
            {
                var helper          = new ExtMethodInvoker("LogDemoExtLib");
                var actionInputType = helper.ExtensionLibAssembly.GetType("LogDemoExtLib.IColoredConsoleLoggerConfiguration", true);
                var configAction    =
                    CreateDelegateHelper.CreateAssignValueAction(actionInputType, "logConfig", new Dictionary <string, object>
                {
                    ["LogLevel"] = defaultLogLevel,
                    ["EventId"]  = defaultEventId,
                    ["Color"]    = defaultConsoleColor
                });

                helper.Invoke <ILoggingBuilder>(
                    new ExtMethodInfo
                {
                    MethodName   = "AddColoredConsoleLog",
                    ExtendedType = loggingBuilder.GetType().GetInterface("ILoggingBuilder")
                },
                    loggingBuilder, configAction);
            });

            var serviceProvider = serviceCollection.BuildServiceProvider();
            var loggerProvider  = (ILoggerProvider)serviceProvider.GetService(typeof(ILoggerProvider));

            //Assert
            Assert.NotNull(loggerProvider);
            var logger = loggerProvider.CreateLogger($"{nameof(InvokeLogAddBuilderMethodWithOptionObjectTest)}");

            Assert.NotNull(logger);
            Assert.True(logger.IsEnabled(defaultLogLevel));
            var consoleLogger = logger as ColoredConsoleLogger;

            Assert.NotNull(consoleLogger);
            Assert.Equal(defaultEventId, consoleLogger.LoggerConfiguration.EventId);
            Assert.Equal(defaultConsoleColor, consoleLogger.LoggerConfiguration.Color);
        }
Beispiel #2
0
        /// <summary>
        /// Initialize a normal Orleans ClientBuilder
        /// </summary>
        /// <param name="logger">Logger to log ClientBuilder operation information</param>
        /// <param name="clusterInfo"></param>
        /// <param name="providerOption"></param>
        /// <param name="applicationPartTypes">Application parts (optional)</param>
        /// <returns></returns>
        public static IClientBuilder CreateClientBuilder(ILogger logger,
                                                         ClusterInfoOption clusterInfo,
                                                         OrleansProviderOption providerOption,
                                                         IEnumerable <Type> applicationPartTypes = null)
        {
            var clientBuilder = new ClientBuilder()
                                .ConfigureCluster(clusterInfo, TimeSpan.FromSeconds(20), TimeSpan.FromMinutes(60))
                                .Configure <StatisticsOptions>(options =>
            {
                options.CollectionLevel = StatisticsLevel.Critical;
            });

            switch (providerOption.DefaultProvider.ToLower())
            {
            case "sqldb":
            {
                logger.LogTrace("Using SQL DB provider");
                var sqlDbSetting = providerOption.SQLDB.Cluster;
                try
                {
                    var helper = new ExtMethodInvoker("Orleans.Clustering.AdoNet");
                    var adoNetClusteringClientOptionsType  = helper.ExtensionLibAssembly.GetType("Orleans.Configuration.AdoNetClusteringClientOptions", true);
                    var adoNetClusteringClientOptionsValue = new Dictionary <string, object>
                    {
                        ["ConnectionString"] = sqlDbSetting.DbConn,
                        ["Invariant"]        = sqlDbSetting.Invariant ?? @"System.Data.SqlClient"
                    };
                    var configSqlDbClusteringAction =
                        CreateDelegateHelper.CreateAssignValueAction(adoNetClusteringClientOptionsType, "options", adoNetClusteringClientOptionsValue);

                    clientBuilder = helper.Invoke <IClientBuilder>(
                        new ExtMethodInfo {
                            MethodName = "UseAdoNetClustering", ExtendedType = typeof(IClientBuilder)
                        },
                        clientBuilder, configSqlDbClusteringAction);
                }
                catch (Exception ex)
                {
                    throw new SqlDbLibLoadFailedException(ex);
                }
            }
            break;

            case "mysql":
            {
                logger.LogTrace("Using MySQL DB provider");
                var mysqlDbSetting = providerOption.SQLDB.Cluster;
                try
                {
                    var helper = new ExtMethodInvoker("Orleans.Clustering.AdoNet");
                    var adoNetClusteringClientOptionsType  = helper.ExtensionLibAssembly.GetType("Orleans.Configuration.AdoNetClusteringClientOptions", true);
                    var adoNetClusteringClientOptionsValue = new Dictionary <string, object>
                    {
                        ["ConnectionString"] = mysqlDbSetting.DbConn,
                        ["Invariant"]        = mysqlDbSetting.Invariant ?? @"MySql.Data.MySqlClient"
                    };
                    var configSqlDbClusteringAction =
                        CreateDelegateHelper.CreateAssignValueAction(adoNetClusteringClientOptionsType, "options", adoNetClusteringClientOptionsValue);

                    clientBuilder = helper.Invoke <IClientBuilder>(
                        new ExtMethodInfo {
                            MethodName = "UseAdoNetClustering", ExtendedType = typeof(IClientBuilder)
                        },
                        clientBuilder, configSqlDbClusteringAction);
                }
                catch (Exception ex)
                {
                    throw new MySqlLibLoadFailedException(ex);
                }
            }
            break;

            case "mongodb":
            {
                logger.LogTrace("Using MongoDB provider...");
                var mongoSetting = providerOption.MongoDB.Cluster;
                try
                {
                    var helper = new ExtMethodInvoker("Orleans.Providers.MongoDB");
                    clientBuilder = helper.Invoke <IClientBuilder>(
                        new ExtMethodInfo {
                            MethodName = "UseMongoDBClient", ExtendedType = typeof(IClientBuilder)
                        },
                        clientBuilder, mongoSetting.DbConn);

                    var mongoDbMembershipTableOptionsType =
                        helper.ExtensionLibAssembly.GetType("Orleans.Providers.MongoDB.Configuration.MongoDBGatewayListProviderOptions", true);
                    var mongoDbMembershipTableOptionsValue = new Dictionary <string, object>
                    {
                        ["DatabaseName"] = mongoSetting.DbName
                    };
                    if (!string.IsNullOrEmpty(mongoSetting.CollectionPrefix))
                    {
                        mongoDbMembershipTableOptionsValue["CollectionPrefix"] = mongoSetting.CollectionPrefix;
                    }
                    var configMongoDbClusteringAction =
                        CreateDelegateHelper.CreateAssignValueAction(mongoDbMembershipTableOptionsType, "options", mongoDbMembershipTableOptionsValue);

                    clientBuilder = helper.Invoke <IClientBuilder>(
                        new ExtMethodInfo {
                            MethodName = "UseMongoDBClustering", ExtendedType = typeof(IClientBuilder)
                        },
                        clientBuilder, configMongoDbClusteringAction);
                }
                catch (Exception ex)
                {
                    throw new MongoDbLibLoadFailedException(ex);
                }
            }
            break;
            }

            if (applicationPartTypes != null)
            {
                clientBuilder.ConfigureApplicationParts(manager =>
                {
                    foreach (var applicationPartType in applicationPartTypes)
                    {
                        manager.AddApplicationPart(applicationPartType.Assembly).WithReferences();
                    }
                });
            }

            return(clientBuilder);
        }
Beispiel #3
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);
            }
        }
Beispiel #4
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);
        }
        private static void ConfigureServices(IServiceCollection services)
        {
            services.AddLogging(loggingBuilder =>
            {
                //Add Trace logger
                loggingBuilder.AddColoredConsoleLog(config =>
                {
                    config.LogLevel = LogLevel.Trace;
                    config.Color    = ConsoleColor.Green;
                });

                //Add Debug logger
                loggingBuilder.AddColoredConsoleLog(
                    new DefaultConsoleLoggerConfiguration {
                    LogLevel = LogLevel.Debug, Color = ConsoleColor.Cyan
                });

                var helper = new ExtMethodInvoker("LogDemoExtLib");

                //Add Information logger's original code:
                //loggingBuilder.AddColoredConsoleLog(config =>
                //{
                //    config.LogLevel = LogLevel.Information;
                //    config.Color = ConsoleColor.Gray;
                //});
                var actionInputType = helper.ExtensionLibAssembly.GetType("LogDemoExtLib.IColoredConsoleLoggerConfiguration", true);
                var configAction    =
                    CreateDelegateHelper.CreateAssignValueAction(actionInputType, "logConfig", new Dictionary <string, object>
                {
                    ["LogLevel"] = LogLevel.Information,
                    ["Color"]    = ConsoleColor.Gray
                });
                helper.Invoke <ILoggingBuilder>(
                    new ExtMethodInfo
                {
                    MethodName   = "AddColoredConsoleLog",
                    ExtendedType = loggingBuilder.GetType().GetInterface("ILoggingBuilder")
                },
                    loggingBuilder, configAction);

                //Add Warning logger's original code:
                //loggingBuilder.AddColoredConsoleLog(new DefaultConsoleLoggerConfiguration());
                var configObjectType =
                    helper.ExtensionLibAssembly.GetType("LogDemoExtLib.DefaultConsoleLoggerConfiguration", true);
                var configObj = Activator.CreateInstance(configObjectType);
                helper.Invoke <ILoggingBuilder>(
                    new ExtMethodInfo
                {
                    MethodName   = "AddColoredConsoleLog",
                    ExtendedType = loggingBuilder.GetType().GetInterface("ILoggingBuilder")
                },
                    loggingBuilder, configObj);

                //Add Error logger
                loggingBuilder.AddColoredConsoleLog(
                    new DefaultConsoleLoggerConfiguration {
                    LogLevel = LogLevel.Error, Color = ConsoleColor.Red
                });

                //Add Critical logger
                loggingBuilder.AddColoredConsoleLog(config =>
                {
                    config.LogLevel = LogLevel.Critical;
                    config.Color    = ConsoleColor.Magenta;
                });

                loggingBuilder.AddFilter <ColoredConsoleLoggerProvider>(typeof(MyClass).Namespace, LogLevel.Trace);
            });
            services.AddTransient <MyClass>();
        }