using System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Windows.Forms; namespace Netron.Diagramming.Core { // ---------------------------------------------------------------------- /// /// Contains a collection of shapes and handles loading shapes from /// assemblies. This can also be serialized for later use. /// // ---------------------------------------------------------------------- public class Library { // ------------------------------------------------------------------ /// /// The collection of shapes for this library. /// // ------------------------------------------------------------------ CollectionBase myShapes; // ------------------------------------------------------------------ /// /// The name of this library. /// // ------------------------------------------------------------------ string myName = "Library"; // ------------------------------------------------------------------ /// /// The complete path to the assembly to load. /// // ------------------------------------------------------------------ string myPath = String.Empty; // ------------------------------------------------------------------ /// /// Our assembly. /// // ------------------------------------------------------------------ Assembly assembly; // ------------------------------------------------------------------ /// /// Gets or sets the name of this library. /// // ------------------------------------------------------------------ public string Name { get { return myName; } set { myName = value; } } // ------------------------------------------------------------------ /// /// Gets the shapes in the library. /// // ------------------------------------------------------------------ public CollectionBase Shapes { get { return myShapes; } } // ------------------------------------------------------------------ /// /// Constructor. /// // ------------------------------------------------------------------ public Library() { this.myShapes = new CollectionBase(); } // ------------------------------------------------------------------ /// /// Returns if this library contains a shape with the GUID specified. /// /// /// // ------------------------------------------------------------------ public bool ContainsShape(string guid) { foreach (IShape shape in myShapes) { if (shape.Uid.ToString() == guid) { return true; } } return false; } // ------------------------------------------------------------------ /// /// Creates a new instance of the shape with the GUID specified. /// /// string /// IShape // ------------------------------------------------------------------ public IShape CreateNewInstance(string guid) { if ((assembly == null) || (guid == "") || (guid == String.Empty)) { return null; } string typeName = ""; foreach (IShape shape in myShapes) { if (shape.Uid.ToString() == guid) { typeName = shape.GetType().FullName; IShape newInstance = (IShape)assembly.CreateInstance(typeName); return newInstance; } } return null; } // ------------------------------------------------------------------ /// /// Imports all shapes that have the "ShapeAttribute" attribute /// from the assembly (i.e. "dll") specified. /// /// string: The complete path to the assembly to /// load. // ------------------------------------------------------------------ public void Load(string path) { try { myPath = path; Directory.SetCurrentDirectory( Path.GetDirectoryName(Application.ExecutablePath)); // Use the "LoadFile" option so the assembly is also loaded // into the current domain. This is important!!! assembly = Assembly.LoadFile(path); if (assembly == null) { return; } // The assembly types. Type[] types = assembly.GetTypes(); if (types == null) { return; } IShape shapeInstance = null; object[] objs; // Loop over all modules in the assembly and get all shapes // that are marked with the attribute that indicates they're // to be loaded into the library. for (int k = 0; k < types.Length; k++) { // It has to be a class to be a shape! if (!types[k].IsClass) { continue; } objs = types[k].GetCustomAttributes( typeof(ShapeAttribute), false); if (objs.Length < 1) { // This module isn't a shape so go to the next one. continue; } // Now, we are sure to have a shape object. try { // Normally you'd need the constructor passing the // Model, but this instance will not actually live // on the canvas and hence cause no problem. // However, you do need a ctor with no parameters! shapeInstance = (IShape)assembly.CreateInstance( types[k].FullName); ShapeAttribute shapeAtts = objs[0] as ShapeAttribute; this.myShapes.Add(shapeInstance); //summary = new ShapeSummary(path, shapeAtts.Key,shapeAtts.Name, shapeAtts.ShapeCategory, shapeAtts.ReflectionName, shapeAtts.Description); //library.ShapeSummaries.Add(summary); } catch (Exception exc) { Trace.WriteLine(exc.Message, "An error occurred " + "while creating a shape from type " + types[k].FullName); continue; } } // Now, set the name of this library to the assembly title. foreach (Attribute attr in Attribute.GetCustomAttributes(assembly)) { // Check for the AssemblyTitle attribute. if (attr.GetType() == typeof(AssemblyTitleAttribute)) { this.myName = ((AssemblyTitleAttribute)attr).Title; break; } } } catch (Exception e) { Trace.WriteLine(e.Message, "An error occurred while " + "loading library from:\n" + path); return; } } } }