/// <summary> /// As we rely on search when generating markdown files and matching them with content from the DynamoDictionary /// we need to add all NodeModel nodes to the SearchModel. /// </summary> /// <param name="asm"></param> /// <param name="nodeModelType"></param> /// <param name="searchModel"></param> private static void AddNodeModelsToSearchModel(Assembly asm, NodeSearchModel searchModel) { System.Type[] typesInAsm = null; try { typesInAsm = asm.GetTypes(); } // see https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.gettypes?view=netframework-4.8#remarks catch (ReflectionTypeLoadException ex) { Program.VerboseControlLog(ex.Message); typesInAsm = ex.Types; } var nodeTypes = typesInAsm .Where(x => NodeModelAssemblyLoader.IsNodeSubType(x)) .Select(t => new TypeLoadData(t)) .Where(type => type != null && !type.IsDeprecated && !type.IsHidden) .ToList(); foreach (var type in nodeTypes) { Program.VerboseControlLog($"adding nodeModelSearchElement for {type.Category} {type.Name}"); searchModel.Add(new NodeModelSearchElement(type)); } }
public void INodeViewCustomizationCheckUsingReflectionIsCorrect() { var dyncorewpfAssem = AppDomain.CurrentDomain.GetAssemblies().Where(x => x.GetName().Name == "DynamoCoreWpf").FirstOrDefault(); var dyncoreAssem = AppDomain.CurrentDomain.GetAssemblies().Where(x => x.GetName().Name == "DynamoCore").FirstOrDefault(); Assert.IsNotNull(dyncorewpfAssem); Assert.IsNotNull(dyncoreAssem); //this assembly contains some builtin nodeviewcustomizations and this methd should return true. Assert.IsTrue(NodeModelAssemblyLoader.ContainsNodeViewCustomizationType(dyncorewpfAssem)); //this assembly contains some builtin nodeviewcustomizations and this methd should return true. Assert.IsFalse(NodeModelAssemblyLoader.ContainsNodeViewCustomizationType(dyncoreAssem)); }
/// <summary> /// Default constructor for DynamoModel /// </summary> /// <param name="config">Start configuration</param> protected DynamoModel(IStartConfiguration config) { ClipBoard = new ObservableCollection<ModelBase>(); pathManager = new PathManager(new PathManagerParams { CorePath = config.DynamoCorePath, HostPath = config.DynamoHostPath, PathResolver = config.PathResolver }); // Ensure we have all directories in place. var exceptions = new List<Exception>(); pathManager.EnsureDirectoryExistence(exceptions); Context = config.Context; IsTestMode = config.StartInTestMode; var config2 = config as IStartConfiguration2; IsHeadless = (config2 != null) ? config2.IsHeadless : false; DebugSettings = new DebugSettings(); Logger = new DynamoLogger(DebugSettings, pathManager.LogDirectory); foreach (var exception in exceptions) { Logger.Log(exception); // Log all exceptions. } MigrationManager = new MigrationManager(DisplayFutureFileMessage, DisplayObsoleteFileMessage); MigrationManager.MessageLogged += LogMessage; MigrationManager.MigrationTargets.Add(typeof(WorkspaceMigrations)); var thread = config.SchedulerThread ?? new DynamoSchedulerThread(); Scheduler = new DynamoScheduler(thread, config.ProcessMode); Scheduler.TaskStateChanged += OnAsyncTaskStateChanged; geometryFactoryPath = config.GeometryFactoryPath; IPreferences preferences = CreateOrLoadPreferences(config.Preferences); var settings = preferences as PreferenceSettings; if (settings != null) { PreferenceSettings = settings; PreferenceSettings.PropertyChanged += PreferenceSettings_PropertyChanged; } InitializeInstrumentationLogger(); if (!IsTestMode && PreferenceSettings.IsFirstRun) { DynamoMigratorBase migrator = null; try { var dynamoLookup = config.UpdateManager != null && config.UpdateManager.Configuration != null ? config.UpdateManager.Configuration.DynamoLookUp : null; migrator = DynamoMigratorBase.MigrateBetweenDynamoVersions(pathManager, dynamoLookup); } catch (Exception e) { Logger.Log(e.Message); } if (migrator != null) { var isFirstRun = PreferenceSettings.IsFirstRun; PreferenceSettings = migrator.PreferenceSettings; // Preserve the preference settings for IsFirstRun as this needs to be set // only by UsageReportingManager PreferenceSettings.IsFirstRun = isFirstRun; } } InitializePreferences(PreferenceSettings); // At this point, pathManager.PackageDirectories only has 1 element which is the directory // in AppData. If list of PackageFolders is empty, add the folder in AppData to the list since there // is no additional location specified. Otherwise, update pathManager.PackageDirectories to include // PackageFolders if (PreferenceSettings.CustomPackageFolders.Count == 0) PreferenceSettings.CustomPackageFolders = new List<string> {pathManager.UserDataDirectory}; //Make sure that the default package folder is added in the list if custom packages folder. var userDataFolder = pathManager.GetUserDataFolder(); //Get the default user data path if (Directory.Exists(userDataFolder) && !PreferenceSettings.CustomPackageFolders.Contains(userDataFolder)) { PreferenceSettings.CustomPackageFolders.Add(userDataFolder); } pathManager.Preferences = PreferenceSettings; SearchModel = new NodeSearchModel(); SearchModel.ItemProduced += node => ExecuteCommand(new CreateNodeCommand(node, 0, 0, true, true)); NodeFactory = new NodeFactory(); NodeFactory.MessageLogged += LogMessage; CustomNodeManager = new CustomNodeManager(NodeFactory, MigrationManager); InitializeCustomNodeManager(); extensionManager = new ExtensionManager(); extensionManager.MessageLogged += LogMessage; var extensions = config.Extensions ?? LoadExtensions(); Loader = new NodeModelAssemblyLoader(); Loader.MessageLogged += LogMessage; // Create a core which is used for parsing code and loading libraries var libraryCore = new ProtoCore.Core(new Options()); libraryCore.Compilers.Add(Language.Associative, new Compiler(libraryCore)); libraryCore.Compilers.Add(Language.Imperative, new ProtoImperative.Compiler(libraryCore)); libraryCore.ParsingMode = ParseMode.AllowNonAssignment; LibraryServices = new LibraryServices(libraryCore, pathManager, PreferenceSettings); LibraryServices.MessageLogged += LogMessage; LibraryServices.LibraryLoaded += LibraryLoaded; ResetEngineInternal(); AddHomeWorkspace(); AuthenticationManager = new AuthenticationManager(config.AuthProvider); UpdateManager = config.UpdateManager ?? new DefaultUpdateManager(null); // config.UpdateManager has to be cast to IHostUpdateManager in order to extract the HostVersion and HostName // see IHostUpdateManager summary for more details var hostUpdateManager = config.UpdateManager as IHostUpdateManager; if (hostUpdateManager != null) { HostName = hostUpdateManager.HostName; HostVersion = hostUpdateManager.HostVersion == null ? null : hostUpdateManager.HostVersion.ToString(); } else { HostName = string.Empty; HostVersion = null; } UpdateManager.Log += UpdateManager_Log; if (!IsTestMode && !IsHeadless) { DefaultUpdateManager.CheckForProductUpdate(UpdateManager); } Logger.Log(string.Format("Dynamo -- Build {0}", Assembly.GetExecutingAssembly().GetName().Version)); InitializeNodeLibrary(PreferenceSettings); if (extensions.Any()) { var startupParams = new StartupParams(config.AuthProvider, pathManager, new ExtensionLibraryLoader(this), CustomNodeManager, GetType().Assembly.GetName().Version, PreferenceSettings); foreach (var ext in extensions) { var logSource = ext as ILogSource; if (logSource != null) logSource.MessageLogged += LogMessage; try { ext.Startup(startupParams); } catch (Exception ex) { Logger.Log(ex.Message); } ExtensionManager.Add(ext); } } LogWarningMessageEvents.LogWarningMessage += LogWarningMessage; StartBackupFilesTimer(); TraceReconciliationProcessor = this; foreach (var ext in ExtensionManager.Extensions) { try { ext.Ready(new ReadyParams(this)); } catch (Exception ex) { Logger.Log(ex.Message); } } }
private void LoaderOnAssemblyLoaded(NodeModelAssemblyLoader.AssemblyLoadedEventArgs args) { nodeViewCustomizationLibrary.Add(new AssemblyNodeViewCustomizations(args.Assembly)); }
protected DynamoModel(IStartConfiguration config) { ClipBoard = new ObservableCollection<ModelBase>(); pathManager = new PathManager(new PathManagerParams { CorePath = config.DynamoCorePath, PathResolver = config.PathResolver }); // Ensure we have all directories in place. pathManager.EnsureDirectoryExistence(); Context = config.Context; IsTestMode = config.StartInTestMode; DebugSettings = new DebugSettings(); Logger = new DynamoLogger(DebugSettings, pathManager.LogDirectory); MigrationManager = new MigrationManager(DisplayFutureFileMessage, DisplayObsoleteFileMessage); MigrationManager.MessageLogged += LogMessage; MigrationManager.MigrationTargets.Add(typeof(WorkspaceMigrations)); var thread = config.SchedulerThread ?? new DynamoSchedulerThread(); Scheduler = new DynamoScheduler(thread, IsTestMode); Scheduler.TaskStateChanged += OnAsyncTaskStateChanged; geometryFactoryPath = config.GeometryFactoryPath; IPreferences preferences = CreateOrLoadPreferences(config.Preferences); var settings = preferences as PreferenceSettings; if (settings != null) { PreferenceSettings = settings; PreferenceSettings.PropertyChanged += PreferenceSettings_PropertyChanged; } InitializePreferences(preferences); InitializeInstrumentationLogger(); if (!isTestMode && this.PreferenceSettings.IsFirstRun) { DynamoMigratorBase migrator = null; try { migrator = DynamoMigratorBase.MigrateBetweenDynamoVersions(pathManager, config.PathResolver); } catch (Exception e) { Logger.Log(e.Message); } if (migrator != null) { var isFirstRun = this.PreferenceSettings.IsFirstRun; this.PreferenceSettings = migrator.PreferenceSettings; // Preserve the preference settings for IsFirstRun as this needs to be set // only by UsageReportingManager this.PreferenceSettings.IsFirstRun = isFirstRun; } } SearchModel = new NodeSearchModel(); SearchModel.ItemProduced += node => ExecuteCommand(new CreateNodeCommand(node, 0, 0, true, true)); NodeFactory = new NodeFactory(); NodeFactory.MessageLogged += LogMessage; CustomNodeManager = new CustomNodeManager(NodeFactory, MigrationManager); InitializeCustomNodeManager(); extensionManager = new ExtensionManager(); extensionManager.MessageLogged += LogMessage; var extensions = config.Extensions ?? ExtensionManager.ExtensionLoader.LoadDirectory(pathManager.ExtensionsDirectory); if (extensions.Any()) { var startupParams = new StartupParams(config.AuthProvider, pathManager, CustomNodeManager); foreach (var ext in extensions) { ext.Startup(startupParams); ext.Load(preferences, pathManager); ext.RequestLoadNodeLibrary += LoadNodeLibrary; ExtensionManager.Add(ext); } } Loader = new NodeModelAssemblyLoader(); Loader.MessageLogged += LogMessage; DisposeLogic.IsShuttingDown = false; // Create a core which is used for parsing code and loading libraries var libraryCore = new ProtoCore.Core(new Options { RootCustomPropertyFilterPathName = string.Empty }); libraryCore.Compilers.Add(Language.kAssociative, new Compiler(libraryCore)); libraryCore.Compilers.Add(Language.kImperative, new ProtoImperative.Compiler(libraryCore)); libraryCore.ParsingMode = ParseMode.AllowNonAssignment; LibraryServices = new LibraryServices(libraryCore, pathManager); LibraryServices.MessageLogged += LogMessage; LibraryServices.LibraryLoaded += LibraryLoaded; ResetEngineInternal(); AddHomeWorkspace(); AuthenticationManager = new AuthenticationManager(config.AuthProvider); UpdateManager = config.UpdateManager ?? new DefaultUpdateManager(null); UpdateManager.Log += UpdateManager_Log; if (!IsTestMode) { DefaultUpdateManager.CheckForProductUpdate(UpdateManager); } Logger.Log(string.Format("Dynamo -- Build {0}", Assembly.GetExecutingAssembly().GetName().Version)); InitializeNodeLibrary(preferences); LogWarningMessageEvents.LogWarningMessage += LogWarningMessage; StartBackupFilesTimer(); TraceReconciliationProcessor = this; foreach (var ext in ExtensionManager.Extensions) { try { ext.Ready(new ReadyParams()); } catch (Exception ex) { Logger.Log(ex.Message); } } }
private List <Type> LoadNodesFromAssembly(Assembly assembly) { if (assembly == null) { throw new ArgumentNullException("assembly"); } var searchViewModel = DynamoViewModel.Model.SearchModel; var types = new List <Type>(); try { var loadedTypes = assembly.GetTypes(); foreach (var t in loadedTypes) { //only load types that are in the right namespace, are not abstract //and have the elementname attribute var attribs = t.GetCustomAttributes(typeof(NodeNameAttribute), false); var isDeprecated = t.GetCustomAttributes(typeof(NodeDeprecatedAttribute), true).Any(); var isMetaNode = t.GetCustomAttributes(typeof(IsMetaNodeAttribute), false).Any(); var isDSCompatible = t.GetCustomAttributes(typeof(IsDesignScriptCompatibleAttribute), true).Any(); bool isHidden = false; var attrs = t.GetCustomAttributes(typeof(IsVisibleInDynamoLibraryAttribute), true); if (null != attrs && attrs.Any()) { var isVisibleAttr = attrs[0] as IsVisibleInDynamoLibraryAttribute; if (null != isVisibleAttr && isVisibleAttr.Visible == false) { isHidden = true; } } if (!NodeModelAssemblyLoader.IsNodeSubType(t) && t.Namespace != "Dynamo.Graph.Nodes") /*&& attribs.Length > 0*/ { continue; } //if we are running in revit (or any context other than NONE) //use the DoNotLoadOnPlatforms attribute, //if available, to discern whether we should load this type if (!DynamoViewModel.Model.Context.Equals(Context.NONE)) { object[] platformExclusionAttribs = t.GetCustomAttributes(typeof(DoNotLoadOnPlatformsAttribute), false); if (platformExclusionAttribs.Length > 0) { string[] exclusions = (platformExclusionAttribs[0] as DoNotLoadOnPlatformsAttribute).Values; //if the attribute's values contain the context stored on the controller //then skip loading this type. if (exclusions.Reverse().Any(e => e.Contains(DynamoViewModel.Model.Context))) { continue; } //utility was late for Vasari release, //but could be available with after-post RevitAPI.dll if (t.Name.Equals("dynSkinCurveLoops")) { MethodInfo[] specialTypeStaticMethods = t.GetMethods(BindingFlags.Static | BindingFlags.Public); const string nameOfMethodCreate = "noSkinSolidMethod"; bool exclude = true; foreach (MethodInfo m in specialTypeStaticMethods) { if (m.Name == nameOfMethodCreate) { var argsM = new object[0]; exclude = (bool)m.Invoke(null, argsM); break; } } if (exclude) { continue; } } } } string typeName; if (attribs.Length > 0 && !isDeprecated && !isMetaNode && isDSCompatible && !isHidden) { //searchViewModel.Add(t); typeName = (attribs[0] as NodeNameAttribute).Name; } else { typeName = t.Name; } types.Add(t); var data = new TypeLoadData(t); } } catch (Exception e) { DynamoViewModel.Model.Logger.Log("Could not load types."); DynamoViewModel.Model.Logger.Log(e); } return(types); }
private static List <MdFileInfo> Scan(IEnumerable <string> assemblyPaths) { var fileInfos = new List <MdFileInfo>(); var nodeSearchModel = new NodeSearchModel(); var pathManager = new PathManager(new PathManagerParams()); Console.WriteLine($"Starting scan of following assemblies: {string.Join(", ", assemblyPaths)}"); var functionGroups = new Dictionary <string, Dictionary <string, FunctionGroup> >(new LibraryPathComparer()); foreach (var path in assemblyPaths) { try { var functionDescriptors = new List <FunctionDescriptor>(); if (new FileInfo(path).Extension == ".ds") { var dsDescriptors = GetFunctionDescriptorsFromDsFile(pathManager, path); if (dsDescriptors != null) { functionDescriptors.AddRange(dsDescriptors); } } else { //load the assembly. Assembly asm = Assembly.LoadFrom(path); AssemblyName name = asm.GetName(); if (NodeModelAssemblyLoader.ContainsNodeModelSubType(asm)) { AddNodeModelsToSearchModel(asm, nodeSearchModel); continue; } var dllDescriptors = GetFunctionDescriptorsFromDll(pathManager, asm); if (dllDescriptors != null) { functionDescriptors.AddRange(dllDescriptors); } } foreach (var descriptor in functionDescriptors) { Dictionary <string, FunctionGroup> functionGroupDict; if (!functionGroups.TryGetValue(descriptor.Assembly, out functionGroupDict)) { functionGroupDict = new Dictionary <string, FunctionGroup>(); functionGroups[descriptor.Assembly] = functionGroupDict; } var qualifiedName = descriptor.QualifiedName; FunctionGroup functionGroup; if (!functionGroupDict.TryGetValue(qualifiedName, out functionGroup)) { functionGroup = new FunctionGroup(qualifiedName); functionGroupDict[qualifiedName] = functionGroup; } functionGroup.AddFunctionDescriptor(descriptor); } } catch (Exception e) { CommandHandler.LogExceptionToConsole(e); continue; } } if (functionGroups.Any()) { AddFunctionGroupsToSearch(functionGroups.Values.SelectMany(x => x.Values.Select(g => g)), nodeSearchModel); } fileInfos.AddRange(FileInfosFromSearchModel(nodeSearchModel)); Console.WriteLine($"{fileInfos.Count()} nodes found during scan"); return(fileInfos); }