/// <summary> /// Creates dictionaries that maps from types full names to /// a suitable collection name. The resulting name is usually /// simple the name of the type. When there is more than /// one type with the same name, FullName is progressively /// perpended to name until there is no ambiguity. /// Two dictionaries are generated, one with pluralized last name /// and one with singular one. /// </summary> /// <param name="pPersistables">Types to be translated.</param> /// <param name="pSchema">Schema to add names dictionaries.</param> private static void CreateNamesDictionary(Type[] pPersistables, ref SchemaInfo pSchema) { Dictionary<string, string> lPlural; SortedSet<string> lSingular = new SortedSet<string>(); // Initially maps FullName to Name. lPlural = pPersistables.ToDictionary(lPersistable => lPersistable.ToGenericTypeString(), lPersistable => lPersistable.Name + "s"); foreach (Type type in pPersistables) lSingular.Add(type.ToGenericTypeString()); // Solve name clashes. pPersistables .ToLookup(lPersistable => lPersistable.Name) .Where(lGroup => lGroup.Count() > 1) .Select(lGroup => SolveNameClash(lGroup)) .ToList() .ForEach(delegate(Dictionary<string, string[]> lSub) { foreach (KeyValuePair<string, string[]> lPair in lSub) { // Singular names just join names. // lSingular[lPair.Key] = String.Join("_", lPair.Value); // Last name gets pluralized for plural names. lPair.Value[lPair.Value.Count() - 1] = lPair.Value.Last() + "s"; lPlural[lPair.Key] = String.Join("_", lPair.Value); } }); pSchema.SingularNames = lSingular; pSchema.TypesNameToPluralName = lPlural; }
public VelocityDBBuilder(VelocityDBDynamicDriver pDriver, VelocityDBProperties pProperties) { schema = SchemaExtractor.Extract(pProperties.ClassesFilenamesArray, pProperties.DependencyFilesArray); sessionInfo = new SessionInfo() { DBFolder = pProperties.DBFolder, Host = pProperties.Host, PessimisticLocking = pProperties.PessimisticLocking, SessionType = pProperties.SessionType, WindowsAuth = pProperties.WindowsAuth }; }
/// <summary> /// Load assemblies and get exported persistable types /// from them. /// </summary> /// <param name="pClassesFilenames">Filenames of all assemblies to /// load.</param> /// <param name="pAssemblies">Loaded assemblies.</param> /// <param name="pTypes">Types found.</param> private static void GetAssembliesAndTypes(string[] pClassFilenames, string[] pDependencyFilenames,ref SchemaInfo pSchema) { // Creates a SchemaExtractor instance on a new domain. This is done // so that no assembly is loaded on process start, and at the end, // only needed assemblies are loaded. AppDomain lDomain = AppDomain .CreateDomain("User assemblies domain."); SchemaExtractor lExtractor; lExtractor = (SchemaExtractor)lDomain.CreateInstanceFromAndUnwrap( typeof(SchemaExtractor).Assembly.CodeBase, typeof(SchemaExtractor).FullName); // Load assemblies and types on the new domain. List<string> lTypeNames = null; List<string> lAssemblyNames = null; List<string> lActualDependencies = null; lExtractor.GetAssembliesAndTypesHelper( pClassFilenames, pDependencyFilenames, ref lAssemblyNames, ref lTypeNames, ref lActualDependencies); AppDomain.Unload(lDomain); // Load assemblies on this domain (to be able to access types). Assembly l; foreach (string lDep in lActualDependencies) { l = Assembly.LoadFrom(lDep); } // Obtain types from names and fill in schema. pSchema.PersistableTypes = lTypeNames .Select(lTypeName => Type.GetType(lTypeName, true)) .ToArray(); pSchema.LoadedAssemblies = lActualDependencies.ToArray(); pSchema.LoadedAssembliesNames = lAssemblyNames.ToArray(); }
/// <summary> /// Extract schema information from assemblies. /// </summary> /// <param name="pClassesFilenames">Assemblies containing /// desired persistable types.</param> /// <param name="pDependenciesFilenames">Assemblies required by /// pClassesFilenames Assemblies.</param> /// <returns></returns> public static SchemaInfo Extract(string[] pClassesFilenames, string[] pDependenciesFilenames) { // Create schema, get persistable types, loaded assemblies and // loaded assemblies names, and finally create names for each type. SchemaInfo lSchema = new SchemaInfo() { UserClassesFiles = pClassesFilenames, UserDependenciesFiles = pDependenciesFilenames }; // Already loaded assemblies sometimes get not found! register // resolver. AppDomain.CurrentDomain.AssemblyResolve += SchemaExtractor .AssemblyResolve; GetAssembliesAndTypes(pClassesFilenames, pDependenciesFilenames, ref lSchema); CreateNamesDictionary(lSchema.PersistableTypes, ref lSchema); AppDomain.CurrentDomain.AssemblyResolve -= SchemaExtractor .AssemblyResolve; return lSchema; }
/// <summary> /// Load assemblies and get exported persistable types /// from them. /// </summary> /// <param name="pClassesFilenames">Filenames of all assemblies to /// load.</param> /// <param name="pAssemblies">Loaded assemblies.</param> /// <param name="pTypes">Types found.</param> private static void GetAssembliesAndTypes(string[] pClassFilenames, string[] pDependencyFilenames, ref SchemaInfo pSchema) { // Creates a SchemaExtractor instance on a new domain. This is done // so that no assembly is loaded on process start, and at the end, // only needed assemblies are loaded. AppDomain lDomain = AppDomain.CreateDomain("User assemblies domain."); SchemaExtractor lExtractor = (SchemaExtractor)lDomain.CreateInstanceFromAndUnwrap( typeof(SchemaExtractor).Assembly.CodeBase, typeof(SchemaExtractor).FullName); // Load assemblies and types on the new domain. List <string> typeNames = null; List <string> assemblyNames = null; List <string> actualDependencies = null; lExtractor.GetAssembliesAndTypesHelper(pClassFilenames, pDependencyFilenames, ref assemblyNames, ref typeNames, ref actualDependencies); AppDomain.Unload(lDomain); // Load assemblies on this domain (to be able to access types). Assembly l; foreach (string lDep in actualDependencies) { l = Assembly.LoadFrom(lDep); } // Obtain types from names and fill in schema. pSchema.PersistableTypes = typeNames.Select(lTypeName => Type.GetType(lTypeName, true)).ToArray(); pSchema.LoadedAssemblies = actualDependencies.ToArray(); pSchema.LoadedAssembliesNames = assemblyNames.ToArray(); }
public VelocityDBAccessBuilder(SchemaInfo pSchema, SessionInfo pSessionInfo) { schema = pSchema; sessionInfo = pSessionInfo; }