// ensure that the factory is running with the lastest generation of models internal Infos EnsureModels() { if (_debugLevel > 0) { _logger.LogDebug("Ensuring models."); } // don't use an upgradeable lock here because only 1 thread at a time could enter it try { _locker.EnterReadLock(); if (_hasModels) { return(_infos); } } finally { if (_locker.IsReadLockHeld) { _locker.ExitReadLock(); } } try { _locker.EnterUpgradeableReadLock(); if (_hasModels) { return(_infos); } _locker.EnterWriteLock(); // we don't have models, // either they haven't been loaded from the cache yet // or they have been reseted and are pending a rebuild using (_profilingLogger.DebugDuration <InMemoryModelFactory>("Get models.", "Got models.")) { try { Assembly assembly = GetModelsAssembly(_pendingRebuild); CurrentModelsAssembly = assembly; // Raise the model changing event. // NOTE: That on first load, if there is content, this will execute before the razor view engine // has loaded which means it hasn't yet bound to this event so there's no need to worry about if // it will be eagerly re-generated unecessarily on first render. BUT we should be aware that if we // change this to use the event aggregator that will no longer be the case. ModelsChanged?.Invoke(this, new EventArgs()); IEnumerable <Type> types = assembly.ExportedTypes.Where(x => x.Inherits <PublishedContentModel>() || x.Inherits <PublishedElementModel>()); _infos = RegisterModels(types); _errors.Clear(); } catch (Exception e) { try { _logger.LogError(e, "Failed to build models."); _logger.LogWarning("Running without models."); // be explicit _errors.Report("Failed to build InMemory models.", e); } finally { CurrentModelsAssembly = null; _infos = new Infos { ModelInfos = null, ModelTypeMap = new Dictionary <string, Type>() }; } } // don't even try again _hasModels = true; } return(_infos); } finally { if (_locker.IsWriteLockHeld) { _locker.ExitWriteLock(); } if (_locker.IsUpgradeableReadLockHeld) { _locker.ExitUpgradeableReadLock(); } } }
private void OnModelsChanged() { ModelsChanged?.Invoke(this, EventArgs.Empty); }