protected override object WriteCacheCore(IEnumerable <ComposablePartDefinition> partDefinitions, IDictionary <string, object> catalogMetadata, ICachedComposablePartCatalogSite catalogSite)
        {
            this.ThrowIfDisposed();
            catalogSite = catalogSite ?? new EmptyCachedComposablePartCatalogSite();

            CachingResult          result = CachingResult.SucceededResult;
            int                    currentCatalogIdentifierCounter = this._currentCatalogIdentifierCouner++;
            string                 currentCatalogIdentifier        = string.Format(CultureInfo.InvariantCulture, "{0}", currentCatalogIdentifierCounter);
            AssemblyCacheGenerator generator = new AssemblyCacheGenerator(this._moduleBuilder, this._generationServices, catalogSite, currentCatalogIdentifier);

            generator.BeginGeneration();
            foreach (ComposablePartDefinition partDefinition in partDefinitions)
            {
                result = result.MergeErrors(generator.CachePartDefinition(partDefinition).Errors);
            }
            generator.CacheCatalogMetadata(catalogMetadata);
            CachingResult <Type> stubGenerationResult = generator.EndGeneration();

            result = result.MergeErrors(stubGenerationResult.Errors);
            result.ThrowOnErrors();

            return(currentCatalogIdentifier);
        }
        public CachingResult <MethodInfo> CachePartDefinition(ComposablePartDefinition partDefinition)
        {
            Assumes.NotNull(partDefinition);
            CachingResult result     = CachingResult.SucceededResult;
            string        methodName = string.Format(CultureInfo.InvariantCulture, "{0}", this._partsCounter);


            //Ftypeof
            // public static ComposablePartDefinition<>()
            // {
            //    // load dictionary
            //    return CachingStubX.CreatePartDefinition(<dictinary>, <importsFactory>, <exportsFactory>);
            // }

            // Generate the signature
            MethodBuilder partFactoryBuilder = this._partsDefinitionBuilder.DefineMethod(
                methodName,
                MethodAttributes.Static | MethodAttributes.Public,
                AssemblyCacheGenerator._composablePartDefinitionType,
                Type.EmptyTypes);
            ILGenerator ilGenerator = partFactoryBuilder.GetILGenerator();

            // Generate imports caching
            CachingResult <MethodInfo> importsFactoryResult = this.CachePartImportsOrExports <ImportDefinition>(
                partDefinition.ImportDefinitions,
                this._importsDefinitionBuilder,
                this._createImportDefinitionMethod,
                (import) => this._cachedCatalogSite.CacheImportDefinition(partDefinition, import),
                methodName);

            result = result.MergeErrors(importsFactoryResult.Errors);

            // Generate exports caching
            CachingResult <MethodInfo> exportsFactoryResult = this.CachePartImportsOrExports <ExportDefinition>(
                partDefinition.ExportDefinitions,
                this._exportsDefinitionBuilder,
                this._createExportDefinitionMethod,
                (export) => this._cachedCatalogSite.CacheExportDefinition(partDefinition, export),
                methodName);

            result = result.MergeErrors(exportsFactoryResult.Errors);


            // get the actual cache for the part definition
            IDictionary <string, object> cache = this._cachedCatalogSite.CachePartDefinition(partDefinition);

            //
            // now write the method
            //

            // load the cache dictionary on stack
            result = result.MergeResult(this._generationServices.LoadValue(ilGenerator, cache));

            // load the imports function pointer on stack
            MethodInfo importsFactory = importsFactoryResult.Value;

            if (importsFactory != null)
            {
                ilGenerator.Emit(OpCodes.Ldftn, importsFactory);
            }
            else
            {
                // load IntPtr.Zero
                ilGenerator.Emit(OpCodes.Ldsfld, AssemblyCacheGenerator._IntPtr_Zero);
            }

            // load the exports function pointer on stack
            MethodInfo exportsFactory = exportsFactoryResult.Value;

            if (exportsFactory != null)
            {
                ilGenerator.Emit(OpCodes.Ldftn, exportsFactory);
            }
            else
            {
                // load IntPtr.Zero
                ilGenerator.Emit(OpCodes.Ldsfld, AssemblyCacheGenerator._IntPtr_Zero);
            }

            // and then call into stub.CreatePartDefinition and return
            ilGenerator.EmitCall(OpCodes.Call, this._createPartDefinitionMethod, null);
            ilGenerator.Emit(OpCodes.Ret);
            this._partsCounter++;

            this.UpdateCatalogIndex(partDefinition, partFactoryBuilder);

            return(result.ToResult <MethodInfo>(partFactoryBuilder));
        }