Class ResourceProvider<TKey, TValue, TResource>
- Namespace
- Acuit.Pinpoint.ResourceManagement
- Assembly
- Acuit.Pinpoint.ResourceManagement.Abstractions.dll
A base class for implementing resource providers.
public abstract class ResourceProvider<TKey, TValue, TResource> : IDisposable where TKey : notnull where TResource : IReferencedResource<TKey, TValue>
Type Parameters
TKeyThe type of the key used to identify different resources, which must be a non-nullable type.
TValueThe resource value type.
TResourceThe referenced resource class type, which must implement IReferencedResource<TKey, TValue>.
- Inheritance
-
ResourceProvider<TKey, TValue, TResource>
- Implements
- Derived
- Inherited Members
Examples
The following example demonstrates a resource provider for resources that require multiple parameters to select a specific resource and that requires an injected service to retrieve resource values:
public interface IWidgetProvider
{
IResourceReference<Widget> CreateWidgetReference(string widgetGroupName, string widgetItemName);
}
// Using a record is a convenient approach for resource keys that combine multiple values; this is immutable and implements value equality:
internal sealed record WidgetId(string WidgetGroupName, string WidgetItemName);
internal sealed class WidgetProvider(IWidgetRetrievalService widgetRetrievalService) : ResourceProvider<WidgetId, Widget, ReferencedWidget>, IWidgetProvider
{
public IResourceReference<Widget> CreateWidgetReference(string widgetGroupName, string widgetItemName) =>
CreateResourceReference(new WidgetId(widgetGroupName, widgetItemName));
protected override ReferencedWidget CreateReferencedResource(WidgetId key) => new(key, widgetRetrievalService);
}
internal sealed class ReferencedWidget(WidgetId key, IWidgetRetrievalService widgetRetrievalService) : ReferencedResource<WidgetId, Widget>(key)
{
protected override async Task<Widget> GetValueAsync(CancellationToken cancellationToken) =>
await widgetRetrievalService.RetrieveWidgetAsync(Key.WidgetGroupName, Key.WidgetItemName, cancellationToken).ConfigureAwait(false);
protected override IChangeToken GetChangeToken() => throw new NotImplementedException(); // TODO: Implement as appropriate
}
Remarks
This base class provides the common logic to track resource references.
Implementations deriving from this class must do the following:
- Provide a class that implements IReferencedResource<TKey, TValue> that will perform the logic to retrieve instances of the resources
provided by this provider. ReferencedResource<TKey, TValue> or one of the more specialized derived classes can be used as a base class to
simplify implementing this class. This will be the
TResourcetype parameter. - Provide an implementation for CreateReferencedResource(TKey) that creates instances of that class. If a provided key is not valid, this implementation method should throw an appropriate ArgumentException rather than return an object that can never produce any values. However, if the key is a valid key but the corresponding resource does not exist or is otherwise unavailable, the implementation should return an object that will produce references that throw an appropriate exception when GetValueAsync(CancellationToken) is called. Presumably, the resource could become available in the future.
- Expose one or more public methods that call CreateResourceReference(TKey) to create references to the resources. Typically, a resource provider will implement an interface specific to the resource type that can be used via dependency injection.
Constructors
ResourceProvider()
Initializes a new instance of the ResourceProvider<TKey, TValue, TResource> class that uses the default equality comparer for
TKey when comparing keys.
protected ResourceProvider()
ResourceProvider(IEqualityComparer<TKey>)
Initializes a new instance of the ResourceProvider<TKey, TValue, TResource> class with a specified equality comparer to use when comparing keys.
protected ResourceProvider(IEqualityComparer<TKey> keyComparer)
Parameters
keyComparerIEqualityComparer<TKey>The IEqualityComparer<T> implementation to use when comparing keys.
Methods
CreateReferencedResource(TKey)
Creates a new referenced resource for a specified key.
protected abstract TResource CreateReferencedResource(TKey key)
Parameters
keyTKeyThe resource key.
Returns
- TResource
A new instance of type
TResourcethat represents the resource.
Exceptions
- ArgumentNullException
keyis null.
CreateResourceReference(TKey)
Creates a reference to a resource.
protected IResourceReference<TValue> CreateResourceReference(TKey key)
Parameters
keyTKeyThe resource key.
Returns
- IResourceReference<TValue>
A IResourceReference<TValue> that can be used to access the resource and that should be disposed when the resource reference is no longer needed.
Remarks
The implementation should expose its own public method(s) that call this method to create a reference to a resource.
Exceptions
- ArgumentNullException
keyis null.
Dispose()
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
public void Dispose()
Remarks
This will cause all active referenced resources (previously created by CreateReferencedResource(TKey)) to be disposed. This should invalidate all active references to those resources. Any attempt to use the reference should produce an ObjectDisposedException.
Dispose(bool)
Closes and releases all resources used by the ResourceProvider<TKey, TValue, TResource>.
protected virtual void Dispose(bool disposing)
Parameters
Remarks
Derived classes should override this when they have any resources that should be disposed.
OnLastReferenceRemoved(TResource)
Called when the last reference to a resource is removed.
protected virtual void OnLastReferenceRemoved(TResource resource)
Parameters
resourceTResourceThe referenced resource for which the last resource was removed.
Remarks
Any override must be sure to call the base implementation, which will remove it from its list of active referenced resources, and then dispose the resource.
UseLockedReferencedResources(Action<IReadOnlyCollection<TResource>>)
Allows derived classes to reference the list of active referenced resources.
protected void UseLockedReferencedResources(Action<IReadOnlyCollection<TResource>> action)
Parameters
actionAction<IReadOnlyCollection<TResource>>A delegate to a method that will be called, with the read-only collection of active referenced resources as its one argument. Adding or removing referenced resources from other threads will block until this action completes.
Exceptions
- ArgumentNullException
actionis null.
UseLockedReferencedResources<TResult>(Func<IReadOnlyCollection<TResource>, TResult>)
Allows derived classes to reference the list of active referenced resources.
protected TResult UseLockedReferencedResources<TResult>(Func<IReadOnlyCollection<TResource>, TResult> action)
Parameters
actionFunc<IReadOnlyCollection<TResource>, TResult>A delegate to a method that will be called, with the read-only collection of active referenced resources as its one argument; the value returned will be returned by this method. Adding or removing referenced resources from other threads will block until this action completes.
Returns
- TResult
Type Parameters
TResultThe return value type.
Exceptions
- ArgumentNullException
actionis null.