|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection.Runtime.TypeInfos;
namespace System.Reflection.Runtime.Dispensers
{
//
// Creates the appropriate Dispenser for a scenario, based on the dispenser policy.
//
internal static class DispenserFactory
{
//
// Note: If your K is a valuetype, use CreateDispenserV() instead. Some algorithms will not be available for use.
//
public static Dispenser<K, V> CreateDispenser<K, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] V>(DispenserScenario scenario, Func<K, V> factory)
where K : class, IEquatable<K>
where V : class
{
DispenserAlgorithm algorithm = s_dispenserPolicy.GetAlgorithm(scenario);
if (algorithm == DispenserAlgorithm.ReuseAsLongAsKeyIsAlive)
return new DispenserThatReusesAsLongAsKeyIsAlive<K, V>(factory);
else
return CreateDispenserV<K, V>(scenario, factory);
throw new Exception();
}
//
// This is similar to CreateDispenser() except it doesn't constrain the key to be a reference type.
// As a result, some algorithms will not be available for use.
//
public static Dispenser<K, V> CreateDispenserV<K, V>(DispenserScenario scenario, Func<K, V> factory)
where K : IEquatable<K>
where V : class
{
DispenserAlgorithm algorithm = s_dispenserPolicy.GetAlgorithm(scenario);
Debug.Assert(algorithm != DispenserAlgorithm.ReuseAsLongAsKeyIsAlive,
"Use CreateDispenser() if you want to use this algorithm. The key must not be a valuetype.");
if (algorithm == DispenserAlgorithm.CreateAlways)
return new DispenserThatAlwaysCreates<K, V>(factory);
else if (algorithm == DispenserAlgorithm.ReuseAlways)
return new DispenserThatAlwaysReuses<K, V>(factory);
else if (algorithm == DispenserAlgorithm.ReuseAsLongAsValueIsAlive)
return new DispenserThatReusesAsLongAsValueIsAlive<K, V>(factory);
throw new Exception();
}
private static readonly DefaultDispenserPolicy s_dispenserPolicy = new DefaultDispenserPolicy();
}
}
|