in src/Microsoft.VisualStudio.Composition/RuntimeExportProviderFactory+RuntimeExportProvider.cs [117:214]
private ValueForImportSite GetValueForImportSite(RuntimePartLifecycleTracker importingPartTracker, RuntimeComposition.RuntimeImport import)
{
Requires.NotNull(import, nameof(import));
Func<Func<object?>, object, object>? lazyFactory = import.LazyFactory;
var exports = import.SatisfyingExports;
if (import.Cardinality == ImportCardinality.ZeroOrMore)
{
if (import.ImportingSiteType.IsArray || (import.ImportingSiteType.GetTypeInfo().IsGenericType && import.ImportingSiteType.GetGenericTypeDefinition().IsEquivalentTo(typeof(IEnumerable<>))))
{
Array array = Array.CreateInstance(import.ImportingSiteTypeWithoutCollection, exports.Count);
using (var intArray = ArrayRental<int>.Get(1))
{
int i = 0;
foreach (var export in exports)
{
intArray.Value[0] = i++;
var exportedValue = this.GetValueForImportElement(importingPartTracker, import, export, lazyFactory);
this.ThrowIfExportedValueIsNotAssignableToImport(import, export, exportedValue);
array.SetValue(exportedValue, intArray.Value);
}
}
return new ValueForImportSite(array);
}
else
{
object? collectionObject = null;
MemberInfo? importingMember = import.ImportingMember;
if (importingMember != null)
{
Assumes.NotNull(importingPartTracker.Value);
collectionObject = GetImportingMember(importingPartTracker.Value, importingMember);
}
bool preexistingInstance = collectionObject != null;
if (!preexistingInstance)
{
if (PartDiscovery.IsImportManyCollectionTypeCreateable(import.ImportingSiteType, import.ImportingSiteTypeWithoutCollection))
{
using (var typeArgs = ArrayRental<Type>.Get(1))
{
typeArgs.Value[0] = import.ImportingSiteTypeWithoutCollection;
Type listType = typeof(List<>).MakeGenericType(typeArgs.Value);
if (import.ImportingSiteType.GetTypeInfo().IsAssignableFrom(listType.GetTypeInfo()))
{
collectionObject = Activator.CreateInstance(listType)!;
}
else
{
collectionObject = Activator.CreateInstance(import.ImportingSiteType)!;
}
}
Assumes.NotNull(importingPartTracker.Value);
Assumes.NotNull(importingMember);
SetImportingMember(importingPartTracker.Value, importingMember, collectionObject);
}
else
{
throw new CompositionFailedException(
string.Format(
CultureInfo.CurrentCulture,
Strings.UnableToInstantiateCustomImportCollectionType,
import.ImportingSiteType.FullName,
$"{import.DeclaringTypeRef.FullName}.{import.ImportingMemberRef?.Name}"));
}
}
var collectionAccessor = CollectionServices.GetCollectionWrapper(import.ImportingSiteTypeWithoutCollection, collectionObject!);
if (preexistingInstance)
{
collectionAccessor.Clear();
}
foreach (var export in exports)
{
var exportedValue = this.GetValueForImportElement(importingPartTracker, import, export, lazyFactory);
this.ThrowIfExportedValueIsNotAssignableToImport(import, export, exportedValue);
collectionAccessor.Add(exportedValue);
}
return default(ValueForImportSite); // signal caller should not set value again.
}
}
else
{
var export = exports.FirstOrDefault();
if (export == null)
{
return new ValueForImportSite(null);
}
var exportedValue = this.GetValueForImportElement(importingPartTracker, import, export, lazyFactory);
this.ThrowIfExportedValueIsNotAssignableToImport(import, export, exportedValue);
return new ValueForImportSite(exportedValue);
}
}