コード例 #1
0
        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);
            }
        }
コード例 #2
0
        /// <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);
        }