private static bool GetCachedCanAssign(object input, Type source, Type target) { var key = new CompositeTypeTypeKey(source, target); if (AssignableTypeCache.TryGetValue(key, out bool canConvert)) { return(canConvert); } // "object is" is faster than "Type.IsAssignableFrom. // We can use it to very quickly determine whether true/false if (input is IConvertible && target.IsAssignableFrom(source)) { return(AssignableTypeCache[key] = true); } return(AssignableTypeCache[key] = false); }
private static TypeConverter GetCachedTargetTypeConverter(Type source, Type target) { var key = new CompositeTypeTypeKey(source, target); if (DestinationTypeConverterCache.TryGetValue(key, out TypeConverter typeConverter)) { return(typeConverter); } TypeConverter converter = TypeDescriptor.GetConverter(target); if (converter.CanConvertFrom(source)) { return(DestinationTypeConverterCache[key] = converter); } return(DestinationTypeConverterCache[key] = null); }
public bool GetCachedCanAssignNoFactory() { // This method is 10% faster var key = new CompositeTypeTypeKey(source, target); bool canConvert; if (AssignableTypeCache.TryGetValue(key, out canConvert)) { return(canConvert); } // "is" is faster than "IsAssignableFrom" if (input is IConvertible && target.IsAssignableFrom(source)) { return(AssignableTypeCache[key] = true); } return(AssignableTypeCache[key] = false); }
private IEnumerable <Type> GetTypesInternalLocked( Type baseType, Type attributeType, Func <IEnumerable <Type> > finder, string action, bool cache) { // check if the TypeList already exists, if so return it, if not we'll create it var tobject = typeof(object); // CompositeTypeTypeKey does not support null values var listKey = new CompositeTypeTypeKey(baseType ?? tobject, attributeType ?? tobject); TypeList typeList = null; if (cache) { _types.TryGetValue(listKey, out typeList); // else null } // if caching and found, return if (typeList != null) { // need to put some logging here to try to figure out why this is happening: http://issues.umbraco.org/issue/U4-3505 _logger.Debug <TypeLoader>("Getting {TypeName}: found a cached type list.", GetName(baseType, attributeType)); return(typeList.Types); } // else proceed, typeList = new TypeList(baseType, attributeType); var typesListFilePath = GetTypesListFilePath(); var scan = RequiresRescanning || File.Exists(typesListFilePath) == false; if (scan) { // either we have to rescan, or we could not find the cache file: // report (only once) and scan and update the cache file if (_reportedChange == false) { _logger.Debug <TypeLoader>("Assemblies changes detected, need to rescan everything."); _reportedChange = true; } } if (scan == false) { // if we don't have to scan, try the cache var cacheResult = TryGetCached(baseType, attributeType); // here we need to identify if the CachedTypeNotFoundInFile was the exception, if it was then we need to re-scan // in some cases the type will not have been scanned for on application startup, but the assemblies haven't changed // so in this instance there will never be a result. if (cacheResult.Exception is CachedTypeNotFoundInFileException || cacheResult.Success == false) { _logger.Debug <TypeLoader>("Getting {TypeName}: failed to load from cache file, must scan assemblies.", GetName(baseType, attributeType)); scan = true; } else { // successfully retrieved types from the file cache: load foreach (var type in cacheResult.Result) { var resolvedType = TypeFinder.GetTypeByName(type); if (resolvedType != null) { typeList.Add(resolvedType); } else { // in case of any exception, we have to exit, and revert to scanning _logger.Warn <TypeLoader>("Getting {TypeName}: failed to load cache file type {CacheType}, reverting to scanning assemblies.", GetName(baseType, attributeType), type); scan = true; break; } } if (scan == false) { _logger.Debug <TypeLoader>("Getting {TypeName}: loaded types from cache file.", GetName(baseType, attributeType)); } } } if (scan) { // either we had to scan, or we could not get the types from the cache file - scan now _logger.Debug <TypeLoader>("Getting {TypeName}: " + action + ".", GetName(baseType, attributeType)); foreach (var t in finder()) { typeList.Add(t); } } // if we are to cache the results, do so if (cache) { var added = _types.ContainsKey(listKey) == false; if (added) { _types[listKey] = typeList; //if we are scanning then update the cache file if (scan) { UpdateCache(); } } _logger.Debug <TypeLoader>("Got {TypeName}, caching ({CacheType}).", GetName(baseType, attributeType), added.ToString().ToLowerInvariant()); } else { _logger.Debug <TypeLoader>("Got {TypeName}.", GetName(baseType, attributeType)); } return(typeList.Types); }