/// <summary>Adds a new cache item, and returns the item that is put in the cache.</summary> /// <param name="serviceType">Type of service with metadata being cached.</param> /// <param name="dataContextInstance"> /// Data context instance being cached, possibly segmenting the cache /// space for <paramref name="serviceType"/>. /// </param> /// <param name="item">Item being added.</param> /// <returns>The item being put in the cache (possibly an existing one).</returns> /// <remarks>This method is thread-safe but not re-entrant.</remarks> internal static MetadataCacheItem AddCacheItem(Type serviceType, object dataContextInstance, MetadataCacheItem item) { Debug.Assert(serviceType != null, "serviceType != null"); Debug.Assert(dataContextInstance != null, "dataContextInstance != null"); Debug.Assert(item != null, "item != null"); MetadataCacheKey key = new MetadataCacheKey(serviceType, dataContextInstance as ObjectContext); MetadataCacheItem result; cacheLock.EnterWriteLock(); try { // If another thread beat the current thread, we return the // previously created item, which has a higher chance of // having survived a garbage collection already. if (!cache.TryGetValue(key, out result)) { cache.Add(key, item); result = item; } } finally { cacheLock.ExitWriteLock(); } Debug.Assert(result != null, "result != null -- a null item is never returned."); Debug.Assert( result == TryLookup(serviceType, dataContextInstance), "result == TryLookup(serviceType, dataContextInstance) -- instance from cache is being returned."); return(result); }
public static MetadataWorkspace GetWorkspace(MetadataCacheKey key) { if (_workspaces.ContainsKey(key)) { return(_workspaces[key]); } _workspaces[key] = new MetadataWorkspace(key.Paths, key.Assemblies); return(_workspaces[key]); }
/// <summary> /// Another method, can pass in the MetadataCacheKey /// </summary> public static T CreateObjectContext <T>(this DbConnection connection, MetadataCacheKey cacheKey) where T : System.Data.Objects.ObjectContext { var workspace = MetadataCache.GetWorkspace(cacheKey); var factory = DbProviderServices.GetProviderFactory(connection); var itemCollection = workspace.GetItemCollection(System.Data.Metadata.Edm.DataSpace.SSpace); itemCollection.GetType().GetField("_providerFactory", // <==== big fat ugly hack BindingFlags.NonPublic | BindingFlags.Instance).SetValue(itemCollection, factory); var ec = new System.Data.EntityClient.EntityConnection(workspace, connection); return(CtorCache <T, System.Data.EntityClient.EntityConnection> .Ctor(ec)); }
internal static T TryLookup(Type serviceType, object dataContextInstance) { T local; MetadataCacheKey key = new MetadataCacheKey(serviceType, DbContextHelper.GetObjectContext(dataContextInstance)); MetadataCache <T> .cacheLock.EnterReadLock(); try { MetadataCache <T> .cache.TryGetValue(key, out local); } finally { MetadataCache <T> .cacheLock.ExitReadLock(); } return(local); }
public Task <ModelInformation> GetModelMetadataInformation(string key) { var cacheKey = new MetadataCacheKey(key); return(_memoryCache.GetOrCreateAsync(cacheKey, entry => { if (!_options.AllowedTypes.TryGetValue(key, out var type)) { return null; } var cacheOptions = _options.MemoryCacheEntryOptions; if (cacheOptions != null) { entry.SetOptions(cacheOptions); } return GetModelMetadataInformation(type); })); }
/// <summary>Tries to look up metadata for the specifed service type and context instance.</summary> /// <param name="serviceType">Type of service with metadata being cached.</param> /// <param name="dataContextInstance"> /// Data context instance being cached, possibly segmenting the cache /// space for <paramref name="serviceType"/>. /// </param> /// <returns>The cached metadata item, if one exists.</returns> /// <remarks>This method is thread-safe but not re-entrant.</remarks> internal static MetadataCacheItem TryLookup(Type serviceType, object dataContextInstance) { Debug.Assert(serviceType != null, "serviceType != null"); Debug.Assert(dataContextInstance != null, "dataContextInstance != null"); MetadataCacheKey key = new MetadataCacheKey(serviceType, dataContextInstance as ObjectContext); MetadataCacheItem result; cacheLock.EnterReadLock(); try { cache.TryGetValue(key, out result); } finally { cacheLock.ExitReadLock(); } return(result); }
/// <summary> /// Add an MetadataCacheItem object to the cache for a given service. /// </summary> /// <param name="serviceType">Type of the service class</param> /// <param name="item">Item to be added to the cache</param> /// <returns>Item that was added to the cache</returns> internal static MetadataCacheItem AddCacheItem(Type serviceType, MetadataCacheItem item) { MetadataCacheItem item2; var key = new MetadataCacheKey(serviceType); // Use a double check lock for concurrency. if (!_cache.TryGetValue(key, out item2)) { lock (_lockObject) { if (!_cache.TryGetValue(key, out item2)) { _cache.Add(key, item); item2 = item; } } } return item2; }
internal static T AddCacheItem(Type serviceType, object dataContextInstance, T item) { T local; MetadataCacheKey key = new MetadataCacheKey(serviceType, DbContextHelper.GetObjectContext(dataContextInstance)); MetadataCache <T> .cacheLock.EnterWriteLock(); try { if (!MetadataCache <T> .cache.TryGetValue(key, out local)) { MetadataCache <T> .cache.Add(key, item); local = item; } } finally { MetadataCache <T> .cacheLock.ExitWriteLock(); } return(local); }
/// <summary> /// Lookup an item from the metadata cache for a given service type. /// </summary> /// <param name="serviceType">Service type for which we want to lookup metadata.</param> /// <returns>MetadataCacheItem for the service type. Null if there is no item in the cache for the given service type.</returns> internal static MetadataCacheItem TryLookup(Type serviceType) { MetadataCacheItem item; var key = new MetadataCacheKey(serviceType); _cache.TryGetValue(key, out item); return item; }
private static MetadataWorkspace CreateWorkspace(MetadataCacheKey key) { return(new MetadataWorkspace(key.Paths, key.Assemblies)); }
/// <summary> /// get the workspace. /// </summary> /// <param name="key">The key.</param> /// <returns>the meta data workspace.</returns> public static MetadataWorkspace GetWorkspace(MetadataCacheKey key) { return(Workspaces.GetOrAdd(key, CreateWorkspace)); }