public async Task <IHardwareRepresentation> GenerateHardware( IEnumerable <string> assembliesPaths, IHardwareGenerationConfiguration configuration) { Argument.ThrowIfNull(assembliesPaths, nameof(assembliesPaths)); if (!assembliesPaths.Any()) { throw new ArgumentException("No assemblies were specified."); } if (assembliesPaths.Count() != assembliesPaths.Distinct().Count()) { throw new ArgumentException( "The same assembly was included multiple times. Only supply each assembly to generate hardware from once."); } try { HardwareRepresentation hardwareRepresentation = null; await _host .Run <ITransformer, IHardwareImplementationComposer, IDeviceManifestSelector>( async (transformer, hardwareImplementationComposer, deviceManifestSelector) => { var hardwareDescription = await transformer.Transform(assembliesPaths, configuration); var hardwareImplementation = await hardwareImplementationComposer.Compose(hardwareDescription); var deviceManifest = deviceManifestSelector .GetSupporteDevices() .FirstOrDefault(manifest => manifest.Name == configuration.DeviceName); if (deviceManifest == null) { throw new HastlayerException( "There is no supported device with the name " + configuration.DeviceName + "."); } hardwareRepresentation = new HardwareRepresentation { SoftAssemblyPaths = assembliesPaths, HardwareDescription = hardwareDescription, HardwareImplementation = hardwareImplementation, DeviceManifest = deviceManifest }; }, ShellName, false); return(hardwareRepresentation); } catch (Exception ex) when(!ex.IsFatal()) { var message = "An error happened during generating the Hastlayer hardware representation for the following assemblies: " + string.Join(", ", assembliesPaths); await _host.Run <ILoggerService>(logger => Task.Run(() => logger.Error(ex, message))); throw new HastlayerException(message, ex); } }
/// <summary> /// Runs a process inside the Orchard App Host that retrieves a value. The method is thread-safe. /// </summary> public static async Task <TResult> RunGet <TResult>(this IOrchardAppHost appHost, Func <IWorkContextScope, Task <TResult> > getterProcess, string shellName = ShellSettings.DefaultName, bool wrapInTransaction = true) { TResult result = default(TResult); Func <IWorkContextScope, Task> process = async scope => { result = await getterProcess(scope); }; await appHost.Run(scope => process(scope), shellName, wrapInTransaction); return(result); }
private static Task Run(this IOrchardAppHost appHost, Func <IWorkContextScope, Task> process, string shellName, bool wrapInTransaction) { if (wrapInTransaction) { return(appHost.RunInTransaction(process, shellName)); } else { return(appHost.Run(process, shellName)); } }
public async void Sweep() { await _orchardAppHost.Run(async scope => { var tasks = scope.Resolve <IEnumerable <IAsyncBackgroundTask> >(); if (!tasks.Any()) { return; } // Not wrapping tasks in a transaction since this could also be run from a transient host. await Task.WhenAll(tasks.Select(task => task.Sweep())); }, _shellSettings.Name); }
public static Task RunInTransaction(this IOrchardAppHost appHost, Func <IWorkContextScope, Task> process, string shellName) { return(appHost.Run(async scope => { var transactionManager = scope.Resolve <ITransactionManager>(); transactionManager.Demand(); try { await process(scope); } catch (Exception) { transactionManager.Cancel(); throw; } }, shellName)); }
public static Task Run <TService1, TService2, TService3, TService4, TService5, TService6, TService7>(this IOrchardAppHost appHost, Func <TService1, TService2, TService3, TService4, TService5, TService6, TService7, Task> process, string shellName = ShellSettings.DefaultName, bool wrapInTransaction = true) { return(appHost.Run(scope => process(scope.Resolve <TService1>(), scope.Resolve <TService2>(), scope.Resolve <TService3>(), scope.Resolve <TService4>(), scope.Resolve <TService5>(), scope.Resolve <TService6>(), scope.Resolve <TService7>()), shellName, wrapInTransaction)); }
public static Task Run(this IOrchardAppHost appHost, Func <IWorkContextScope, Task> process) { return(appHost.Run(process, ShellSettings.DefaultName)); }
private async Task LoadHost() { var moduleFolderPaths = new List <string>(); // Since Hast.Core either exists or not we need to start by probing for the Hast.Abstractions folder. var abstractionsPath = Path.GetDirectoryName(GetType().Assembly.Location); var currentDirectory = Path.GetFileName(abstractionsPath); if (currentDirectory.Equals("Debug", StringComparison.OrdinalIgnoreCase) || currentDirectory.Equals("Release", StringComparison.OrdinalIgnoreCase)) { abstractionsPath = Path.GetDirectoryName(abstractionsPath); } currentDirectory = Path.GetFileName(abstractionsPath); if (currentDirectory.Equals("bin", StringComparison.OrdinalIgnoreCase)) { abstractionsPath = Path.GetDirectoryName(abstractionsPath); } // Now we're at the level above the current project's folder. abstractionsPath = Path.GetDirectoryName(abstractionsPath); var coreFound = false; while (abstractionsPath != null && !coreFound) { var abstractionsSubFolder = Path.Combine(abstractionsPath, "Hast.Abstractions"); if (Directory.Exists(abstractionsSubFolder)) { abstractionsPath = abstractionsSubFolder; coreFound = true; } else { abstractionsPath = Path.GetDirectoryName(abstractionsPath); } } // There won't be an Abstractions folder, nor a Core one when the app is being run from a deployment folder // (as opposed to a solution). if (!string.IsNullOrEmpty(abstractionsPath)) { moduleFolderPaths.Add(abstractionsPath); } if (_configuration.Flavor == HastlayerFlavor.Developer) { var corePath = !string.IsNullOrEmpty(abstractionsPath) ? Path.Combine(Path.GetDirectoryName(abstractionsPath), "Hast.Core") : null; if (corePath != null && Directory.Exists(corePath)) { moduleFolderPaths.Add(corePath); } } var importedExtensions = new[] { typeof(Hastlayer).Assembly, typeof(IProxyGenerator).Assembly, typeof(IHardwareImplementationComposer).Assembly, typeof(ITransformer).Assembly, typeof(Nexys4DdrManifestProvider).Assembly } .ToList(); if (_configuration.Flavor == HastlayerFlavor.Client) { importedExtensions.Add(typeof(Remote.Client.RemoteTransformer).Assembly); } // Adding imported extensions last so they can override anything. importedExtensions.AddRange(_configuration.Extensions); var settings = new AppHostSettings { // Setting a custom path so if the parent app is also an AppHost app then with the default settings // those won't clash. AppDataFolderPath = "~/Hastlayer/App_Data", ImportedExtensions = importedExtensions, DefaultShellFeatureStates = new[] { new DefaultShellFeatureState { ShellName = ShellName, EnabledFeatures = importedExtensions.Select(extension => extension.ShortName()) } }, ModuleFolderPaths = moduleFolderPaths }; var registrations = new AppHostRegistrations { HostRegistrations = builder => builder .RegisterType <HardwareExecutionEventHandlerHolder>() .As <IHardwareExecutionEventHandlerHolder>() .SingleInstance() }; _host = await OrchardAppHostFactory.StartTransientHost(settings, registrations, null); await _host.Run <IHardwareExecutionEventHandlerHolder>(proxy => Task.Run(() => proxy.RegisterExecutedOnHardwareEventHandler(eventArgs => ExecutedOnHardware?.Invoke(this, eventArgs)))); // Enable all loaded features. This is needed so extensions just added to the solution, but not referenced // anywhere in the current app can contribute dependencies. await _host .Run <Orchard.Environment.Features.IFeatureManager>( (featureManager) => { featureManager.EnableFeatures(featureManager.GetAvailableFeatures().Select(feature => feature.Id), true); return(Task.CompletedTask); }, ShellName, false); }