public Type GetByType(Type type, SoftwareVersion version) { Type returnType = null; // Type type = typeof(T); VersionLookup versionLookup; try { if (!_TypeLookup.TryGetValue(type, out versionLookup)) { _typeLock.Lock(); versionLookup = new VersionLookup(); _TypeLookup.Add(type, versionLookup); List <Type> types = new List <Type>(type.Assembly.GetTypes().Where(asmType => asmType.IsClass && !asmType.IsAbstract && (asmType.IsSubclassOf(type) || asmType == type))); // Find all descendants // TODO: Add functionality to add additional assemblies where datasources may be found, // outside of the assembly containing the base, which is where all searches are currently conducted foreach (Type subType in types) { DatabaseVersionAttribute[] attribs = (DatabaseVersionAttribute[])subType.GetCustomAttributes(typeof(DatabaseVersionAttribute), false); if (attribs.Length > 0) { foreach (DatabaseVersionAttribute attr in attribs) { foreach (SoftwareVersion attributeVersion in attr.Versions) { if (versionLookup.ContainsKey(attributeVersion)) { versionLookup[attributeVersion] = subType; } else { versionLookup.Add(attributeVersion, subType); } } } } } } } finally { _typeLock.Unlock(); } // At this point, all versioned types realted to the requested type are indexed by version number in the lookup for this type if (!versionLookup.TryGetValue(version, out returnType)) { // Couldn't find an exact match of the datasource requested. Look for the most recent one prior to this database version SoftwareVersion lastVersion = null; List <SoftwareVersion> keys = new List <SoftwareVersion>(versionLookup.Keys); keys.Sort(); keys.Reverse(); foreach (SoftwareVersion key in keys) { if (key > version) { continue; } lastVersion = key; break; } if (lastVersion != null) { returnType = versionLookup[lastVersion]; versionLookup.Add(version, returnType); // Warn if our datasource is not marked for the current version? } } return(returnType); }
public static void Parse(Token token, ref VCard vcard) { string version = token.Values[0]; vcard.Version = VersionLookup.Parse(version); }