// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.Composition.Hosting.Core; using System.Composition.Hosting.Providers.Metadata; using System.Composition.Hosting.Util; using System.Linq; using System.Reflection; namespace System.Composition.Hosting.Providers.Lazy { internal sealed class LazyWithMetadataExportDescriptorProvider : ExportDescriptorProvider { private static readonly MethodInfo s_getLazyDefinitionsMethod = typeof(LazyWithMetadataExportDescriptorProvider).GetTypeInfo().GetDeclaredMethod("GetLazyDefinitions"); public override IEnumerable<ExportDescriptorPromise> GetExportDescriptors(CompositionContract exportKey, DependencyAccessor definitionAccessor) { if (!exportKey.ContractType.IsConstructedGenericType || exportKey.ContractType.GetGenericTypeDefinition() != typeof(Lazy<,>)) return NoExportDescriptors; var ga = exportKey.ContractType.GenericTypeArguments; var gld = s_getLazyDefinitionsMethod.MakeGenericMethod(ga[0], ga[1]); var gldm = gld.CreateStaticDelegate<Func<CompositionContract, DependencyAccessor, object>>(); return (ExportDescriptorPromise[])gldm(exportKey, definitionAccessor); } private static ExportDescriptorPromise[] GetLazyDefinitions<TValue, TMetadata>(CompositionContract lazyContract, DependencyAccessor definitionAccessor) { var metadataProvider = MetadataViewProvider.GetMetadataViewProvider<TMetadata>(); return definitionAccessor.ResolveDependencies("value", lazyContract.ChangeType(typeof(TValue)), false) .Select(d => new ExportDescriptorPromise( lazyContract, Formatters.Format(typeof(Lazy<TValue, TMetadata>)), false, () => new[] { d }, _ => { var dsc = d.Target.GetDescriptor(); var da = dsc.Activator; return ExportDescriptor.Create((c, o) => { return new Lazy<TValue, TMetadata>(() => (TValue)CompositionOperation.Run(c, da), metadataProvider(dsc.Metadata)); }, dsc.Metadata); })) .ToArray(); } } } |