namespace BCG { using Bts.DataStream; using bts; using mbts.config; using System; using System.Collections; using System.Reflection; using System.IO; public class PrimitiveManager { private IDictionary myTypeLookupTable = new Hashtable(); private static PrimitiveManager mySelf; private ArrayList myAssemblyNames = new ArrayList(); private PrimitiveManager() { myLoadAllTypes(); } private void myLoadAllTypes() { AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.AssemblyResolve += new ResolveEventHandler(myAssemblyResolver); loadAssembly(this.GetType().Assembly.FullName); var assemblies = new string[] { "DataStream.dll", "SharedStreams.dll" }; var config_assemblies = Configuration.get().Assemblies; bts.Log.Gen.info($"PrimitiveManager.myLoadAllTypes config_assemblies: {config_assemblies}"); foreach (string assemblyName in assemblies/*config_assemblies*/) { bts.Log.Gen.info($"PrimitiveManager.myLoadAllTypes assemblyName: {assemblyName}"); string resolvedAssemblyPath = assemblyName; if (!System.IO.Path.IsPathRooted(assemblyName)) { resolvedAssemblyPath = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assemblyName)); } loadAssembly(resolvedAssemblyPath); } } private static Assembly myAssemblyResolver(object sender, ResolveEventArgs args) { foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) if (args.Name.Equals(a.FullName)) return a; return null; } /// /// Loads all the Stream types associated with the assembly /// /// public void loadAssembly(string assemblyName) { Func is_silverpine_only = (t) => { if (!assemblyName.Contains("SharedStreams.dll")) return true; return t.Namespace == "bts.SilverPine"; }; bts.Log.Gen.info($"PrimitiveManager.loadAssembly assemblyName: {assemblyName}"); if (myAssemblyNames.Contains(assemblyName)) return; myAssemblyNames.Add(assemblyName); Assembly loadedAssembly = GetType().Assembly.FullName.Equals(assemblyName) ? GetType().Assembly : Assembly.LoadFrom(assemblyName); foreach (Type type in loadedAssembly.GetTypes()) if (!type.IsInterface && is_silverpine_only(type) && !type.IsAbstract && type.IsSubclassOf(typeof(ViewStream)) && type.IsPublic) { bool isVisible = true; string userRep = createDefaultName(type.Name); foreach (Attribute att in type.GetCustomAttributes(false)) if (att is DataStreamUserRespresentation) { DataStreamUserRespresentation dsatt = att as DataStreamUserRespresentation; isVisible = dsatt.isVisible; userRep = isVisible ? dsatt.friendlyName == null ? userRep : dsatt.friendlyName : null; break; } if (isVisible) { Log.assert_d(myTypeLookupTable[userRep] == null, type.FullName); myTypeLookupTable[userRep] = type; } } } public static string createDefaultName(string typeName) { if (!typeName.EndsWith("Stream")) return typeName; string retVal = typeName.Remove(typeName.Length - "Stream".Length, "Stream".Length); string startString = new String(new char[] { retVal[0] }).ToLower(); retVal = retVal.Remove(0, 1); retVal = retVal.Insert(0, startString); return retVal; } public static PrimitiveManager instance { get { return mySelf = mySelf == null ? new PrimitiveManager() : mySelf; } } /// /// Returns the Type name corresponding to the primitive name /// /// /// public string find(string friendlyName) { if (myTypeLookupTable[friendlyName] == null) throw new ApplicationException(friendlyName + " is not the friendly name of any of the loaded types"); return (myTypeLookupTable[friendlyName] as Type).Name; } /// /// Constructs and returns a ViewStream of type corresponding to the friendly name /// /// friendly primitive name /// args can be null or an empty ICollection if the paramterless constructor /// is the desired one /// public ViewStream build(string friendlyName, ICollection args) { object[] constructorArgs = null; if (args != null && args.Count > 0) { constructorArgs = new object[args.Count]; args.CopyTo(constructorArgs, 0); } if (myTypeLookupTable[friendlyName] == null) throw new ApplicationException(friendlyName + " is not the friendly name of any of the loaded types"); return constructorArgs == null ? Activator.CreateInstance(myTypeLookupTable[friendlyName] as Type) as ViewStream : Activator.CreateInstance(myTypeLookupTable[friendlyName] as Type, constructorArgs) as ViewStream; } /// /// Returns the name of all the primitives /// /// public string[] getPrimitiveNames() { string[] retVal = new string[myTypeLookupTable.Count]; myTypeLookupTable.Keys.CopyTo(retVal, 0); return retVal; } /// /// Return the types of all the streams /// /// public Type[] getStreamTypes() { Type[] retVal = new Type[myTypeLookupTable.Count]; myTypeLookupTable.Values.CopyTo(retVal, 0); return retVal; } public ICollection getConstructorSigns(string primitiveName) { ArrayList retVal = new ArrayList(); Log.assert(myTypeLookupTable[primitiveName] != null); Type t = myTypeLookupTable[primitiveName] as Type; foreach (ConstructorInfo ci in t.GetConstructors()) { string sign = ""; sign = t.Name + " ("; foreach (ParameterInfo pi in ci.GetParameters()) sign += pi.ParameterType.Name + " " + pi.Name + ", "; sign = sign.Length == (t.Name + " (").Length ? sign + ")" : sign.Remove(sign.Length - 2, 2) + ")"; retVal.Add(sign); } return retVal; } public string getAssemblyName(string primitiveName) { Log.assert(myTypeLookupTable[primitiveName] != null); return (myTypeLookupTable[primitiveName] as Type).Assembly.GetName().Name; } } }