public static Delegate GetWriteValueDelegate(Type valueType) { // We want to generate the delegate only once even if we cannot insert it // to s_writerDelegates from the first attempt. var generatedDelegate = new Lazy <Delegate>( () => JSValueWriterGenerator.GenerateWriteValueDelegate(valueType)); // We try to add the generated WriteValue delegate in a loop // in a lock-free thread-safe way. We do not change existing s_writerDelegates. // Instead we clone it, update the clone, then replace the s_writerDelegates with the updated clone. while (true) { var writerDelegates = s_writerDelegates; // Get the local pointer first. if (writerDelegates.TryGetValue(valueType, out Delegate writeDelegate)) { return(writeDelegate); } // The WriteValue 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_writerDelegates changed while we generated the value. // It helps to avoid cloning dictionary in a number of cases. if (writerDelegates != s_writerDelegates) { continue; } // Clone the dictionary, update the clone, and try to replace the s_writerDelegates. var updatedWriterDelegates = new Dictionary <Type, Delegate>(writerDelegates as IDictionary <Type, Delegate>); updatedWriterDelegates.Add(valueType, newDelegate); Interlocked.CompareExchange(ref s_writerDelegates, updatedWriterDelegates, writerDelegates); } }
/// <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); }