public void Build(Action <ContainerRegistrar> action, ConfigurationStore configStore) { var builder = new ContainerRegistrar(); builder.RegisterComponents(Lifetime.Scoped, Assembly.GetExecutingAssembly()); builder.RegisterService(CreateConnection, Lifetime.Scoped); builder.RegisterService(CreateTaskInvoker, Lifetime.Singleton); builder.RegisterInstance(Startup.ConnectionFactory); action(builder); RegisterBuiltInComponents(builder); RegisterQueues(builder); builder.RegisterService(x => Container, Lifetime.Singleton); builder.RegisterService(x => x); builder.RegisterConcrete <AnalysisDbContext>(); builder.RegisterInstance(configStore); builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); builder.RegisterControllers(Assembly.GetExecutingAssembly()); var ioc = builder.Build(); DependencyResolver.SetResolver(new GriffinDependencyResolver(ioc)); GlobalConfiguration.Configuration.DependencyResolver = new GriffinWebApiDependencyResolver2(ioc); Container = new GriffinContainerAdapter(ioc); }
public void Build(Action <ContainerRegistrar> action, ConfigurationStore configStore) { var builder = new ContainerRegistrar(); //need to invoke first to allow plug-ins to override default behavior. action(builder); builder.RegisterComponents(Lifetime.Scoped, Assembly.GetExecutingAssembly()); builder.RegisterService(CreateUnitOfWork, Lifetime.Scoped); builder.RegisterService(CreateTaskInvoker, Lifetime.Singleton); builder.RegisterService(CreateConnection, Lifetime.Transient); RegisterBuiltInComponents(builder); RegisterQueues(builder); builder.RegisterService(x => Container, Lifetime.Singleton); builder.RegisterService(x => x); builder.RegisterService(CreateAnalysisDbContext); builder.RegisterInstance(configStore); builder.RegisterType(typeof(IConfiguration <>), typeof(ConfigWrapper <>), Lifetime.Transient); builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); builder.RegisterControllers(Assembly.GetExecutingAssembly()); builder.RegisterService(x => configStore.Load <BaseConfiguration>()); var ioc = builder.Build(); DependencyResolver.SetResolver(new GriffinDependencyResolver(ioc)); GlobalConfiguration.Configuration.DependencyResolver = new GriffinWebApiDependencyResolver2(ioc); Container = new GriffinContainerAdapter(ioc); }
public void Should_Resolve_Last_Registration_Of_Instance_When_Requesting_Single_Registration() { // Given var builder = new ContainerRegistrar(); var instance1 = Substitute.For <IFoo>(); var instance2 = Substitute.For <IFoo>(); builder.RegisterInstance(instance1).Singleton(); builder.RegisterInstance(instance2).Singleton(); var container = builder.Build(); // When var result = container.Resolve <IFoo>(); // Then Assert.Same(instance2, result); }
public void Should_Resolve_All_Instances_When_Requesting_Enumerable_Of_Registration() { // Given var builder = new ContainerRegistrar(); var instance1 = Substitute.For <IFoo>(); var instance2 = Substitute.For <IFoo>(); builder.RegisterInstance(instance1).Singleton(); builder.RegisterInstance(instance2).Singleton(); var container = builder.Build(); // When var result = container.Resolve <IEnumerable <IFoo> >().ToList(); // Then Assert.Equal(2, result.Count); Assert.Contains(result, instance => instance == instance1); Assert.Contains(result, instance => instance == instance2); }
public void TestSingleton() { var registrar = new ContainerRegistrar(); registrar.RegisterInstance <MySelf>(new MySelf()); registrar.RegisterConcrete <OneDepencency>(Lifetime.Singleton); var container = registrar.Build(); container.Resolve <OneDepencency>(); }
public void DispatchReal() { var handler = Substitute.For<IExecuteQuery<FakeQuery, string>>(); var registrar = new ContainerRegistrar(); registrar.RegisterInstance(handler); var dispatcher = new QueryDispatcher(registrar.Build()); dispatcher.Execute(new FakeQuery()); }
public void DispatchReal() { var handler = Substitute.For <IExecuteQuery <FakeQuery, string> >(); var registrar = new ContainerRegistrar(); registrar.RegisterInstance(handler); var dispatcher = new QueryDispatcher(registrar.Build()); dispatcher.Execute(new FakeQuery()); }
public void RegisterServiceAsInstance() { var registrar = new ContainerRegistrar(Lifetime.Transient); registrar.RegisterInstance<IThinkNot>(new Will()); registrar.RegisterConcrete<InstanceSubject>(); var c = registrar.Build(); var actual = c.Resolve<InstanceSubject>(); Assert.NotNull(actual); Assert.IsAssignableFrom<InstanceSubject>(actual); }
public void RegisterServiceAsInstance() { var registrar = new ContainerRegistrar(Lifetime.Transient); registrar.RegisterInstance <IThinkNot>(new Will()); registrar.RegisterConcrete <InstanceSubject>(); var c = registrar.Build(); var actual = c.Resolve <InstanceSubject>(); Assert.NotNull(actual); Assert.IsAssignableFrom <InstanceSubject>(actual); }
public static void RegisterHandler(this ContainerRegistrar registrar, object handler) { registrar.RegisterInstance(handler.GetType(), handler); var reg = registrar.Registrations.First(x => x.Services.Any(y => y == handler.GetType())); var bajs = handler.GetType().GetInterfaces(); foreach (var b in bajs) { if (b.IsConstructedGenericType) { reg.AddService(b); } } }
public void Should_Resolve_The_Same_Instances_When_Resolving_Registered_Instance() { // Given var builder = new ContainerRegistrar(); var instance = Substitute.For <IFoo>(); builder.RegisterInstance(instance).Singleton(); var container = builder.Build(); // When var first = container.Resolve <IFoo>(); var second = container.Resolve <IFoo>(); // Then Assert.Same(instance, first); Assert.Same(instance, second); }
public void TestSingleton() { var registrar = new ContainerRegistrar(); registrar.RegisterInstance<MySelf>(new MySelf()); registrar.RegisterConcrete<OneDepencency>(Lifetime.Singleton); var container = registrar.Build(); container.Resolve<OneDepencency>(); }
public static int Main() { // Parse arguments. var args = ArgumentParser.Parse( QuoteAwareStringSplitter .Split(EnvironmentHelper.GetCommandLine()) .Skip(1)); if (args.ContainsKey(Constants.CommandLine.Debug)) { Console.WriteLine($"Attach debugger to process {Process.GetCurrentProcess().Id} to continue. .."); while (!Debugger.IsAttached) { Thread.Sleep(100); } } // Validate the port argument. if (!args.ContainsKey(Constants.CommandLine.Port) || !int.TryParse(args[Constants.CommandLine.Port], out int port)) { throw new ArgumentException("Port not specified or invalid."); } var loggerFactory = new LoggerFactory(); if (args.ContainsKey(Constants.CommandLine.Verbose)) { loggerFactory.AddProvider(new LoggerProvider()); } var registrar = new ContainerRegistrar(); registrar.RegisterModule(new CoreModule()); registrar.RegisterModule(new BakeryModule(loggerFactory)); // Build the container. using (var container = registrar.Build()) { var fileSystem = container.Resolve <IFileSystem>(); var log = container.Resolve <ICakeLog>(); var configurationProvider = container.Resolve <CakeConfigurationProvider>(); var workingDirectory = new DirectoryPath(System.IO.Directory.GetCurrentDirectory()); var configuration = configurationProvider.CreateConfiguration(workingDirectory, args); // Rebuild the container for NuGet and Buffered File System. registrar = new ContainerRegistrar(); registrar.RegisterInstance(configuration); registrar.RegisterModule(new NuGetModule(configuration)); registrar.RegisterModule(new ScriptingModule(fileSystem, log)); registrar.Builder.Update(container); var environment = container.Resolve <ICakeEnvironment>(); var aliasFinder = container.Resolve <IScriptAliasFinder>(); var processor = container.Resolve <Core.Scripting.IScriptProcessor>(); var aliasGenerator = container.Resolve <ICakeAliasGenerator>(); var loadDirectiveProviders = container.Resolve <IEnumerable <ILoadDirectiveProvider> >(); // Rebuild the container for Cached Alias Finder. registrar = new ContainerRegistrar(); registrar.RegisterModule(new CacheModule(aliasFinder, processor, environment, aliasGenerator, loadDirectiveProviders)); registrar.Builder.Update(container); // Get Script generator. var scriptGenerator = container.Resolve <IScriptGenerationService>(); environment.WorkingDirectory = workingDirectory; try { using (var server = new ScriptGenerationServer(scriptGenerator, port, loggerFactory)) { server.Start(); var cancel = new ManualResetEvent(false); server.OnDisconnected += (sender, e) => { cancel.Set(); }; Console.CancelKeyPress += (sender, e) => { cancel.Set(); e.Cancel = true; }; cancel.WaitOne(); server.Stop(); } } catch (Exception e) { loggerFactory.CreateLogger <Program>().LogCritical(0, e, "Unhandled Exception"); throw; } } return(0); }
private async void Startup() { // Print exception messages in English Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture; // Set the AppDomain working directory to the current resource root Environment.CurrentDirectory = Path.GetFullPath(API.GetResourcePath(API.GetCurrentResourceName())); new Logger().Info($"NFive {typeof(Program).Assembly.GetCustomAttributes<AssemblyInformationalVersionAttribute>().First().InformationalVersion}"); // TODO: Check and warn if local CitizenFX.Core.Server.dll is found var config = ConfigurationManager.Load <CoreConfiguration>("core.yml"); // Use configured culture for output Thread.CurrentThread.CurrentCulture = config.Locale.Culture.First(); CultureInfo.DefaultThreadCurrentCulture = config.Locale.Culture.First(); ServerConfiguration.Locale = config.Locale; ServerLogConfiguration.Output = config.Log.Output; var logger = new Logger(config.Log.Core); API.SetGameType(config.Display.Game); API.SetMapName(config.Display.Map); // Setup RPC handlers RpcManager.Configure(config.Log.Comms, this.EventHandlers, this.Players); var events = new EventManager(config.Log.Comms); var comms = new CommunicationManager(events); var rcon = new RconManager(comms); // Load core controllers try { var dbController = new DatabaseController(new Logger(config.Log.Core, "Database"), ConfigurationManager.Load <DatabaseConfiguration>("database.yml"), comms); await dbController.Loaded(); this.controllers.Add(new Name("NFive/Database"), new List <Controller> { dbController }); } catch (Exception ex) { logger.Error(ex, "Database connection error"); logger.Warn("Fatal error, exiting"); Environment.Exit(1); } var eventController = new EventController(new Logger(config.Log.Core, "FiveM"), comms); await eventController.Loaded(); this.controllers.Add(new Name("NFive/RawEvents"), new List <Controller> { eventController }); var sessionController = new SessionController(new Logger(config.Log.Core, "Session"), ConfigurationManager.Load <SessionConfiguration>("session.yml"), comms); await sessionController.Loaded(); this.controllers.Add(new Name("NFive/Session"), new List <Controller> { sessionController }); // Resolve dependencies var graph = DefinitionGraph.Load(); // IoC var assemblies = new List <Assembly>(); assemblies.AddRange(graph.Plugins.Where(p => p.Server?.Include != null).SelectMany(p => p.Server.Include.Select(i => Assembly.LoadFrom(Path.Combine("plugins", p.Name.Vendor, p.Name.Project, $"{i}.net.dll"))))); assemblies.AddRange(graph.Plugins.Where(p => p.Server?.Main != null).SelectMany(p => p.Server.Main.Select(m => Assembly.LoadFrom(Path.Combine("plugins", p.Name.Vendor, p.Name.Project, $"{m}.net.dll"))))); var registrar = new ContainerRegistrar(); registrar.RegisterService <ILogger>(s => new Logger()); registrar.RegisterInstance <IRconManager>(rcon); registrar.RegisterInstance <IBaseScriptProxy>(new BaseScriptProxy(this.EventHandlers, this.Exports, this.Players)); registrar.RegisterInstance <ICommunicationManager>(comms); registrar.RegisterInstance <IClientList>(new ClientList(new Logger(config.Log.Core, "ClientList"), comms)); registrar.RegisterPluginComponents(assemblies.Distinct()); // DI var container = registrar.Build(); var pluginDefaultLogLevel = config.Log.Plugins.ContainsKey("default") ? config.Log.Plugins["default"] : LogLevel.Info; // Load plugins into the AppDomain foreach (var plugin in graph.Plugins) { logger.Info($"Loading {plugin.FullName}"); // Load include files foreach (var includeName in plugin.Server?.Include ?? new List <string>()) { var includeFile = Path.Combine("plugins", plugin.Name.Vendor, plugin.Name.Project, $"{includeName}.net.dll"); if (!File.Exists(includeFile)) { throw new FileNotFoundException(includeFile); } AppDomain.CurrentDomain.Load(File.ReadAllBytes(includeFile)); } // Load main files foreach (var mainName in plugin.Server?.Main ?? new List <string>()) { var mainFile = Path.Combine("plugins", plugin.Name.Vendor, plugin.Name.Project, $"{mainName}.net.dll"); if (!File.Exists(mainFile)) { throw new FileNotFoundException(mainFile); } var asm = Assembly.LoadFrom(mainFile); var sdkVersion = asm.GetCustomAttribute <ServerPluginAttribute>(); if (sdkVersion == null) { throw new Exception("Unable to load outdated SDK plugin"); // TODO } if (sdkVersion.Target != SDK.Server.SDK.Version) { throw new Exception("Unable to load outdated SDK plugin"); } var types = Assembly.LoadFrom(mainFile).GetTypes().Where(t => !t.IsAbstract && t.IsClass).ToList(); // Find migrations foreach (var migrationType in types.Where(t => t.BaseType != null && t.BaseType.IsGenericType && t.BaseType.GetGenericTypeDefinition() == typeof(MigrationConfiguration <>))) { var configuration = (DbMigrationsConfiguration)Activator.CreateInstance(migrationType); var migrator = new DbMigrator(configuration); if (!migrator.GetPendingMigrations().Any()) { continue; } if (!ServerConfiguration.AutomaticMigrations) { throw new MigrationsPendingException($"Plugin {plugin.FullName} has pending migrations but automatic migrations are disabled"); } foreach (var migration in migrator.GetPendingMigrations()) { new Logger(config.Log.Core, "Database").Debug($"[{mainName}] Running migration: {migration}"); migrator.Update(migration); } } // Find controllers foreach (var controllerType in types.Where(t => t.IsSubclassOf(typeof(Controller)) || t.IsSubclassOf(typeof(ConfigurableController <>)))) { var logLevel = config.Log.Plugins.ContainsKey(plugin.Name) ? config.Log.Plugins[plugin.Name] : pluginDefaultLogLevel; var constructorArgs = new List <object> { new Logger(logLevel, plugin.Name) }; // Check if controller is configurable if (controllerType.BaseType != null && controllerType.BaseType.IsGenericType && controllerType.BaseType.GetGenericTypeDefinition() == typeof(ConfigurableController <>)) { // Initialize the controller configuration constructorArgs.Add(ConfigurationManager.InitializeConfig(plugin.Name, controllerType.BaseType.GetGenericArguments()[0])); } // Resolve IoC arguments constructorArgs.AddRange(controllerType.GetConstructors()[0].GetParameters().Skip(constructorArgs.Count).Select(p => container.Resolve(p.ParameterType))); Controller controller = null; try { // Construct controller instance controller = (Controller)Activator.CreateInstance(controllerType, constructorArgs.ToArray()); } catch (Exception ex) { // TODO: Dispose of controller logger.Error(ex, $"Unhandled exception in plugin {plugin.FullName}"); } if (controller == null) { continue; } try { await controller.Loaded(); if (!this.controllers.ContainsKey(plugin.Name)) { this.controllers.Add(plugin.Name, new List <Controller>()); } this.controllers[plugin.Name].Add(controller); } catch (Exception ex) { // TODO: Dispose of controller logger.Error(ex, $"Unhandled exception loading plugin {plugin.FullName}"); } } } } await Task.WhenAll(this.controllers.SelectMany(c => c.Value).Select(s => s.Started())); rcon.Controllers = this.controllers; comms.Event(CoreEvents.ClientPlugins).FromClients().OnRequest(e => e.Reply(graph.Plugins)); logger.Debug($"{graph.Plugins.Count.ToString(CultureInfo.InvariantCulture)} plugin(s) loaded, {this.controllers.Count.ToString(CultureInfo.InvariantCulture)} controller(s) created"); comms.Event(ServerEvents.ServerInitialized).ToServer().Emit(); logger.Info("Server ready"); }
private async void Startup() { // Set the AppDomain working directory to the current resource root Environment.CurrentDirectory = Path.GetFullPath(API.GetResourcePath(API.GetCurrentResourceName())); Logger.Initialize(); new Logger().Info($"NFive {typeof(Program).Assembly.GetCustomAttributes<AssemblyInformationalVersionAttribute>().First().InformationalVersion}"); var config = ConfigurationManager.Load <CoreConfiguration>("nfive.yml"); ServerLogConfiguration.Output = config.Log.Output; //ServerConfiguration.LogLevel = config.Log.Level; var logger = new Logger(config.Log.Core); API.SetGameType(config.Display.Game); API.SetMapName(config.Display.Map); // Setup RPC handlers RpcManager.Configure(config.Log.Rpc, this.EventHandlers); // Client log mirroring new RpcHandler().Event("nfive:log:mirror").On(new Action <IRpcEvent, DateTime, LogLevel, string, string>((e, dt, level, prefix, message) => { new Logger(LogLevel.Trace, $"Client#{e.Client.Handle}|{prefix}").Log(message, level); })); var events = new EventManager(config.Log.Events); var rcon = new RconManager(new RpcHandler()); // Load core controllers var dbController = new DatabaseController(new Logger(config.Log.Core, "Database"), events, new RpcHandler(), rcon, ConfigurationManager.Load <DatabaseConfiguration>("database.yml")); await dbController.Loaded(); this.controllers.Add(new Name("NFive/Database"), new List <Controller> { dbController }); var sessionController = new SessionController(new Logger(config.Log.Core, "Session"), events, new RpcHandler(), rcon, ConfigurationManager.Load <SessionConfiguration>("session.yml")); await sessionController.Loaded(); this.controllers.Add(new Name("NFive/Session"), new List <Controller> { sessionController }); // Resolve dependencies var graph = DefinitionGraph.Load(); var pluginDefaultLogLevel = config.Log.Plugins.ContainsKey("default") ? config.Log.Plugins["default"] : LogLevel.Info; // IoC var assemblies = new List <Assembly>(); assemblies.AddRange(graph.Plugins.Where(p => p.Server?.Include != null).SelectMany(p => p.Server.Include.Select(i => Assembly.LoadFrom(Path.Combine("plugins", p.Name.Vendor, p.Name.Project, $"{i}.net.dll"))))); assemblies.AddRange(graph.Plugins.Where(p => p.Server?.Main != null).SelectMany(p => p.Server.Main.Select(m => Assembly.LoadFrom(Path.Combine("plugins", p.Name.Vendor, p.Name.Project, $"{m}.net.dll"))))); var registrar = new ContainerRegistrar(); registrar.RegisterService <ILogger>(s => new Logger()); registrar.RegisterType <IRpcHandler, RpcHandler>(); registrar.RegisterInstance <IEventManager>(events); registrar.RegisterInstance <IRconManager>(rcon); registrar.RegisterInstance <IClientList>(new ClientList(new Logger(config.Log.Core, "ClientList"), new RpcHandler())); registrar.RegisterSdkComponents(assemblies.Distinct()); // DI var container = registrar.Build(); // Load plugins into the AppDomain foreach (var plugin in graph.Plugins) { logger.Info($"Loading {plugin.FullName}"); // Load include files foreach (var includeName in plugin.Server?.Include ?? new List <string>()) { var includeFile = Path.Combine("plugins", plugin.Name.Vendor, plugin.Name.Project, $"{includeName}.net.dll"); if (!File.Exists(includeFile)) { throw new FileNotFoundException(includeFile); } AppDomain.CurrentDomain.Load(File.ReadAllBytes(includeFile)); } // Load main files foreach (var mainName in plugin.Server?.Main ?? new List <string>()) { var mainFile = Path.Combine("plugins", plugin.Name.Vendor, plugin.Name.Project, $"{mainName}.net.dll"); if (!File.Exists(mainFile)) { throw new FileNotFoundException(mainFile); } var types = Assembly.LoadFrom(mainFile).GetTypes().Where(t => !t.IsAbstract && t.IsClass).ToList(); // Find migrations foreach (var migrationType in types.Where(t => t.BaseType != null && t.BaseType.IsGenericType && t.BaseType.GetGenericTypeDefinition() == typeof(MigrationConfiguration <>))) { var configuration = (DbMigrationsConfiguration)Activator.CreateInstance(migrationType); var migrator = new DbMigrator(configuration); if (!migrator.GetPendingMigrations().Any()) { continue; } if (!ServerConfiguration.AutomaticMigrations) { throw new MigrationsPendingException($"Plugin {plugin.FullName} has pending migrations but automatic migrations are disabled"); } foreach (var migration in migrator.GetPendingMigrations()) { new Logger(config.Log.Core, "Database").Debug($"[{mainName}] Running migration: {migration}"); migrator.Update(migration); } } // Find controllers foreach (var controllerType in types.Where(t => t.IsSubclassOf(typeof(Controller)) || t.IsSubclassOf(typeof(ConfigurableController <>)))) { var logLevel = config.Log.Plugins.ContainsKey(plugin.Name) ? config.Log.Plugins[plugin.Name] : pluginDefaultLogLevel; var constructorArgs = new List <object> { new Logger(logLevel, plugin.Name), events, new RpcHandler(), rcon }; // Check if controller is configurable if (controllerType.BaseType != null && controllerType.BaseType.IsGenericType && controllerType.BaseType.GetGenericTypeDefinition() == typeof(ConfigurableController <>)) { // Initialize the controller configuration constructorArgs.Add(ConfigurationManager.InitializeConfig(plugin.Name, controllerType.BaseType.GetGenericArguments()[0])); } // Resolve IoC arguments constructorArgs.AddRange(controllerType.GetConstructors()[0].GetParameters().Skip(constructorArgs.Count).Select(p => container.Resolve(p.ParameterType))); Controller controller = null; try { // Construct controller instance controller = (Controller)Activator.CreateInstance(controllerType, constructorArgs.ToArray()); } catch (Exception ex) { // TODO: Dispose of controller logger.Error(ex, $"Unhandled exception in plugin {plugin.FullName}"); } if (controller == null) { continue; } try { await controller.Loaded(); if (!this.controllers.ContainsKey(plugin.Name)) { this.controllers.Add(plugin.Name, new List <Controller>()); } this.controllers[plugin.Name].Add(controller); } catch (Exception ex) { // TODO: Dispose of controller logger.Error(ex, $"Unhandled exception loading plugin {plugin.FullName}"); } } } } #pragma warning disable 4014 foreach (var controller in this.controllers.SelectMany(c => c.Value)) { controller.Started(); } #pragma warning restore 4014 rcon.Controllers = this.controllers; new RpcHandler().Event(SDK.Core.Rpc.RpcEvents.ClientPlugins).On(e => e.Reply(graph.Plugins)); events.Raise(ServerEvents.ServerInitialized); logger.Debug($"{graph.Plugins.Count} plugin(s) loaded, {this.controllers.Count} controller(s) created"); }