/// <summary> /// Registers the asset assembly. This assembly should provide <see cref="Asset"/> objects, associated with /// <see cref="IAssetCompiler"/> and optionaly a <see cref="IAssetImporter"/>. /// </summary> /// <param name="assembly">The assembly.</param> /// <exception cref="System.ArgumentNullException">assembly</exception> /// <exception cref="AssetException"> /// Invalid compiler type [{0}], must inherit from IAssetImporter.ToFormat(assetCompiler.TypeName) /// or /// Unable to instantiate compiler [{0}].ToFormat(assetCompiler.TypeName) /// or /// Invalid importer type [{0}], must inherit from IAssetImporter.ToFormat(assetImporter.ImpoterTypeName) /// or /// Unable to instantiate importer [{0}].ToFormat(assetImporter.ImpoterTypeName) /// </exception> public static void RegisterAssembly(Assembly assembly) { if (assembly == null) { throw new ArgumentNullException("assembly"); } lock (RegisteredAssemblies) { if (RegisteredAssemblies.Contains(assembly)) { return; } RegisteredAssemblies.Add(assembly); } // Process Asset types. foreach (var type in assembly.GetTypes()) { // Register serializer factories if (type.GetCustomAttribute <YamlSerializerFactoryAttribute>() != null) { if (typeof(IYamlSerializableFactory).IsAssignableFrom(type)) { try { var yamlFactory = (IYamlSerializableFactory)Activator.CreateInstance(type); lock (RegisteredSerializerFactories) { RegisteredSerializerFactories.Add(yamlFactory); } // TODO: Handle IDataCustomVisitor on its own instead of relying on the coupling with IYamlSerializableFactory var dataCustomVisitor = yamlFactory as IDataCustomVisitor; if (dataCustomVisitor != null) { lock (RegisteredDataVisitNodes) { RegisteredDataVisitNodes.Add(dataCustomVisitor); } } } catch (Exception ex) { Log.Error("Unable to instantiate serializer factory [{0}]", ex, type); } } } if (type.GetCustomAttribute <DiffNodeBuilderAttribute>() != null) { if (typeof(IDataCustomVisitor).IsAssignableFrom(type)) { try { var dataCustomVisitor = (IDataCustomVisitor)Activator.CreateInstance(type); lock (RegisteredDataVisitNodeBuilders) { RegisteredDataVisitNodeBuilders.Add(dataCustomVisitor); } } catch (Exception ex) { Log.Error("Unable to instantiate diff converter [{0}]", ex, type); } } } // Asset importer if (typeof(IAssetImporter).IsAssignableFrom(type) && type.GetConstructor(new Type[0]) != null) { try { var importerInstance = Activator.CreateInstance(type) as IAssetImporter; // Register the importer instance RegisterImporter(importerInstance); } catch (Exception ex) { Log.Error("Unable to instantiate importer [{0}]", ex, type.Name); } } if (typeof(PackageSessionAnalysisBase).IsAssignableFrom(type) && type.GetConstructor(new Type[0]) != null) { RegisteredPackageSessionAnalysisTypes.Add(type); } { var packageUpgraderAttribute = type.GetCustomAttribute <PackageUpgraderAttribute>(); if (packageUpgraderAttribute != null) { try { var packageUpgrader = (PackageUpgrader)Activator.CreateInstance(type); packageUpgrader.Attribute = packageUpgraderAttribute; RegisteredPackageUpgraders[packageUpgraderAttribute.PackageName] = packageUpgrader; } catch (Exception ex) { Log.Error("Unable to instantiate package upgrader [{0}]", ex, type.Name); } } } // Only process Asset types var assetType = type; if (!typeof(Asset).IsAssignableFrom(assetType) || !assetType.IsClass) { continue; } // Store in a list all asset types loaded if (assetType.IsPublic && !assetType.IsAbstract) { AssetTypes.Add(assetType); } var isSourceCodeAsset = typeof(SourceCodeAsset).IsAssignableFrom(assetType); // Asset FileExtensions var assetDescriptionAttribute = assetType.GetCustomAttribute <AssetDescriptionAttribute>(); if (assetDescriptionAttribute != null) { if (assetDescriptionAttribute.FileExtensions != null) { var extensions = FileUtility.GetFileExtensions(assetDescriptionAttribute.FileExtensions); RegisteredDefaultAssetExtension[assetType] = extensions.FirstOrDefault(); foreach (var extension in extensions) { RegisteredAssetFileExtensions.Add(extension); // If the asset is a pure sourcecode asset, then register the serializer if (isSourceCodeAsset) { SourceCodeAssetSerializer.RegisterExtension(assetType, extension); } } } if (!assetDescriptionAttribute.AllowUserCreation) { RegisteredInternalAssetTypes.Add(assetType); } } // Asset format version var assetFormatVersion = assetType.GetCustomAttribute <AssetFormatVersionAttribute>(); int formatVersion = assetFormatVersion != null ? assetFormatVersion.Version : 0; int minVersion = assetFormatVersion != null ? assetFormatVersion.MinUpgradableVersion : 0; RegisteredFormatVersions.Add(assetType, Tuple.Create(minVersion, formatVersion)); // Asset upgraders var assetUpgraders = assetType.GetCustomAttributes <AssetUpgraderAttribute>(); AssetUpgraderCollection upgraderCollection = null; foreach (var upgrader in assetUpgraders) { if (upgraderCollection == null) { upgraderCollection = new AssetUpgraderCollection(assetType, formatVersion); } upgraderCollection.RegisterUpgrader(upgrader.AssetUpgraderType, upgrader.StartMinVersion, upgrader.StartMaxVersion, upgrader.TargetVersion); } if (upgraderCollection != null) { upgraderCollection.Validate(minVersion); RegisteredAssetUpgraders.Add(assetType, upgraderCollection); } // Asset factory var assetFactory = assetType.GetCustomAttribute <ObjectFactoryAttribute>(); if (assetFactory != null) { try { ObjectFactory.RegisterFactory(assetType); } catch (Exception ex) { Log.Error("Unable to instantiate factory [{0}] for asset [{1}]", ex, assetFactory.FactoryTypeName, assetType); } } else { var assetConstructor = assetType.GetConstructor(Type.EmptyTypes); if (assetConstructor != null) { // Register the asset even if it has no factory (default using empty constructor) ObjectFactory.RegisterFactory(assetType, null); } } // Asset description var thumbnailCompilerAttribute = assetType.GetCustomAttribute <ThumbnailCompilerAttribute>(); if (thumbnailCompilerAttribute != null) { RegisterDynamicThumbnail(assetType, thumbnailCompilerAttribute.DynamicThumbnails); } } }
/// <summary> /// Registers the asset assembly. This assembly should provide <see cref="Asset"/> objects, associated with /// <see cref="ICompiler"/> and optionaly a <see cref="IAssetImporter"/>. /// </summary> /// <param name="assembly">The assembly.</param> /// <exception cref="System.ArgumentNullException">assembly</exception> /// <exception cref="AssetException"> /// Invalid compiler type [{0}], must inherit from IAssetImporter.ToFormat(assetCompiler.CompilerTypeName) /// or /// Unable to instantiate compiler [{0}].ToFormat(assetCompiler.CompilerTypeName) /// or /// Invalid importer type [{0}], must inherit from IAssetImporter.ToFormat(assetImporter.ImpoterTypeName) /// or /// Unable to instantiate importer [{0}].ToFormat(assetImporter.ImpoterTypeName) /// </exception> public static void RegisterAssembly(Assembly assembly) { if (assembly == null) { throw new ArgumentNullException("assembly"); } if (RegisteredAssemblies.Contains(assembly)) { return; } RegisteredAssemblies.Add(assembly); // Process Asset types. foreach (var type in assembly.GetTypes()) { // Register serializer factories if (type.GetCustomAttribute <YamlSerializerFactoryAttribute>() != null) { if (typeof(IYamlSerializableFactory).IsAssignableFrom(type)) { try { var yamlFactory = (IYamlSerializableFactory)Activator.CreateInstance(type); RegisteredSerializerFactories.Add(yamlFactory); // TODO: Handle IDataCustomVisitor on its own instead of relying on the coupling with IYamlSerializableFactory var dataCustomVisitor = yamlFactory as IDataCustomVisitor; if (dataCustomVisitor != null) { RegisteredDataVisitNodes.Add(dataCustomVisitor); } } catch (Exception ex) { log.Error("Unable to instantiate serializer factory [{0}]", ex, type); } } } // Asset importer if (typeof(IAssetImporter).IsAssignableFrom(type) && type.GetConstructor(new Type[0]) != null) { try { var importerInstance = Activator.CreateInstance(type) as IAssetImporter; // Register the importer instance RegisterImporter(importerInstance); } catch (Exception ex) { log.Error("Unable to instantiate importer [{0}]", ex, type.Name); } } // Only process Asset types var assetType = type; if (!typeof(Asset).IsAssignableFrom(assetType) || !assetType.IsClass) { continue; } var isSourceCodeAsset = typeof(SourceCodeAsset).IsAssignableFrom(assetType); // Asset FileExtensions var assetFileExtensionAttribute = assetType.GetCustomAttribute <AssetFileExtensionAttribute>(); if (assetFileExtensionAttribute != null && assetFileExtensionAttribute.FileExtensions != null) { var extensions = FileUtility.GetFileExtensions(assetFileExtensionAttribute.FileExtensions); RegisteredDefaultAssetExtension[assetType] = extensions.FirstOrDefault(); foreach (var extension in extensions) { RegisteredAssetFileExtensions.Add(extension); // If the asset is a pure sourcecode asset, then register the serializer if (isSourceCodeAsset) { SourceCodeAssetSerializer.RegisterExtension(assetType, extension); } } } var assetFormatVersion = assetType.GetCustomAttribute <AssetFormatVersionAttribute>(); if (assetFormatVersion != null) { RegisteredFormatVersions.Add(assetType, assetFormatVersion.Version); RegisteredFormatVersionUpdaterTypes.Add(assetType, assetFormatVersion.AssetUpdaterTypes); } // Asset factory var assetFactory = assetType.GetCustomAttribute <AssetFactoryAttribute>(); if (assetFactory != null) { // A null factory name means that the type is not instantiable if (assetFactory.FactoryTypeName != null) { try { var factoryType = Type.GetType(assetFactory.FactoryTypeName); if (factoryType == null) { log.Error("Unable to find factory [{0}] for asset [{1}]", assetFactory.FactoryTypeName, assetType); goto labelAssetDescription; } var factoryInstance = Activator.CreateInstance(factoryType) as IAssetFactory; if (factoryInstance == null) { log.Error("Invalid factory type [{0}], must inherit from IAssetImporter", assetFactory.FactoryTypeName); goto labelAssetDescription; } RegisterFactory(assetType, factoryInstance); } catch (Exception ex) { if (ex is AssetException) { throw; } throw new AssetException("Unable to instantiate factory [{0}]".ToFormat(assetFactory.FactoryTypeName), ex); } } } else { var assetConstructor = assetType.GetConstructor(Type.EmptyTypes); if (assetConstructor != null) { RegisterFactory(assetType, null); } } labelAssetDescription: // Asset description var assetDescription = assetType.GetCustomAttribute <AssetDescriptionAttribute>(); if (assetDescription != null) { RegisterDescription(assetType, assetDescription.GetDescription()); } } }