public static Delegate GetReadValueDelegate(Type valueType) { // We want to generate the delegate only once even if we cannot insert it // to s_readerDelegates from the first attempt. var generatedDelegate = new Lazy <Delegate>( () => JSValueReaderGenerator.GenerateReadValueDelegate(valueType)); // We try to add the generated ReadValue delegate in a loop // in a lock-free thread-safe way. We do not change existing s_readerDelegates. // Instead we clone it, update the clone, then replace the s_readerDelegates with the updated clone. while (true) { var readerDelegates = s_readerDelegates; // Get the local pointer first. if (readerDelegates.TryGetValue(valueType, out Delegate readDelegate)) { return(readDelegate); } // The ReadValue delegate is not found. Generate it add try to add to the dictionary atomically. var newDelegate = generatedDelegate.Value; // Generates delegate when we are here a first time. // This is a quick shortcut in case if s_readerDelegates changed while we generated the value. // It helps to avoid cloning dictionary in a number of cases. if (readerDelegates != s_readerDelegates) { continue; } // Clone the dictionary, update the clone, and try to replace the s_readerDelegates. var updatedReaderDelegates = new Dictionary <Type, Delegate>(readerDelegates as IDictionary <Type, Delegate>); updatedReaderDelegates.Add(valueType, newDelegate); Interlocked.CompareExchange(ref s_readerDelegates, updatedReaderDelegates, readerDelegates); } }
/// <summary> /// Helper extension method to register a reflection /// </summary> /// <typeparam name="T">This must be thea type defined in the assembly where the items for the react package should be extracted.</typeparam> /// <remarks> /// The common use case of this type is when you have a react library. Then you would call this from the <see cref="IReactPackageBuilder.CreatePackage"/> function in ReactPackageProvider class that implements <see cref="IReactPackageProvider"/> like: <c> /// public sealed class ReactPackageProvider : IReactPackageProvider /// { /// public void CreatePackage(IReactPackageBuilder packageBuilder) /// { /// packageBuilder.AddReflectionReactPackageProvider<ReactPackageProvider>(); /// } /// } /// </c>. /// </remarks> public static void AddReflectionReactPackageProvider <T>(this IReactPackageBuilder packageBuilder) { var assembly = typeof(T).Assembly; packageBuilder.AddAttributedModules(assembly); packageBuilder.AddViewManagers(assembly); JSValueReaderGenerator.RegisterAssembly(assembly); JSValueWriterGenerator.RegisterAssembly(assembly); }