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)); }