/// <summary> /// <para>add MagicOnion service to generic host with specific types or assemblies</para> /// </summary> /// <remarks>you must not pass null to options</remarks> public static IHostBuilder UseMagicOnion(this IHostBuilder hostBuilder, IEnumerable <ServerPort> ports, MagicOnionOptions options, IEnumerable <Type> types = null, Assembly[] searchAssemblies = null, IEnumerable <ChannelOption> channelOptions = null) { return(hostBuilder.ConfigureServices((ctx, services) => { var serviceLocator = new ServiceLocatorBridge(services); options.ServiceLocator = serviceLocator; // replace it. // build immediately(require register service before create it). MagicOnionServiceDefinition serviceDefinition; if (searchAssemblies != null) { serviceDefinition = MagicOnionEngine.BuildServerServiceDefinition(searchAssemblies, options); } else if (types != null) { serviceDefinition = MagicOnionEngine.BuildServerServiceDefinition(types, options); } else { if (options != null) { serviceDefinition = MagicOnionEngine.BuildServerServiceDefinition(options); } else { serviceDefinition = MagicOnionEngine.BuildServerServiceDefinition(); } } // store service definition services.AddSingleton <MagicOnionServiceDefinition>(serviceDefinition); // should transient or singleton? // in AddHostedService<T> implementation, singleton is used // https://github.com/aspnet/Extensions/blob/8b2482fa68c548e904e4aa1ae38a29c72dcd32a5/src/Hosting/Abstractions/src/ServiceCollectionHostedServiceExtensions.cs#L18 services.AddSingleton <IHostedService, MagicOnionServerService>(serviceProvider => { serviceLocator.provider = serviceProvider; // set built provider. return new MagicOnionServerService(serviceDefinition, ports, channelOptions); }); })); }
private static void AddMagicOnionHostedServiceDefinition( this IServiceCollection services, string configurationName = null, IEnumerable <Type> types = null, Assembly[] searchAssemblies = null ) { if (services.Any(x => (x.ImplementationInstance as MagicOnionHostedServiceDefinition)?.Name == configurationName)) { throw new InvalidOperationException($"MagicOnion ServiceDefinition for '{configurationName}' is already registerd."); } services.AddSingleton <MagicOnionHostedServiceDefinition>(serviceProvider => { var hostingOptions = serviceProvider.GetService <IOptionsMonitor <MagicOnionHostingOptions> >().Get(configurationName); var options = hostingOptions.Service; var serviceLocator = new ServiceLocatorBridge(services); options.ServiceLocator = serviceLocator; // Build a MagicOnion ServiceDefinition from assemblies/types. MagicOnionServiceDefinition serviceDefinition; if (searchAssemblies != null) { serviceDefinition = MagicOnionEngine.BuildServerServiceDefinition(searchAssemblies, options); } else if (types != null) { serviceDefinition = MagicOnionEngine.BuildServerServiceDefinition(types, options); } else { if (options != null) { serviceDefinition = MagicOnionEngine.BuildServerServiceDefinition(options); } else { serviceDefinition = MagicOnionEngine.BuildServerServiceDefinition(); } } return(new MagicOnionHostedServiceDefinition(configurationName, serviceDefinition)); }); }