public static TMetadataView GetMetadataView <TMetadataView>(IDictionary <string, object?> metadata)
        {
            if (metadata == null)
            {
                throw new ArgumentNullException(nameof(metadata));
            }

            Type metadataViewType = typeof(TMetadataView);

            // If the Metadata dictionary is cast compatible with the passed in type
            if (metadataViewType.IsAssignableFrom(typeof(IDictionary <string, object?>)))
            {
                return((TMetadataView)metadata);
            }
            // otherwise is it a metadata view
            else
            {
                Type?proxyType = null;
                MetadataViewGenerator.MetadataViewFactory?metadataViewFactory = null;
                if (metadataViewType.IsInterface)
                {
                    if (!metadataViewType.IsAttributeDefined <MetadataViewImplementationAttribute>())
                    {
                        try
                        {
                            metadataViewFactory = MetadataViewGenerator.GetMetadataViewFactory(metadataViewType);
                        }
                        catch (TypeLoadException ex)
                        {
                            throw new NotSupportedException(SR.Format(SR.NotSupportedInterfaceMetadataView, metadataViewType.FullName), ex);
                        }
                    }
                    else
                    {
                        var implementationAttribute = metadataViewType.GetFirstAttribute <MetadataViewImplementationAttribute>();
                        Debug.Assert(implementationAttribute != null);
                        proxyType = implementationAttribute.ImplementationType;
                        if (proxyType == null)
                        {
                            throw new CompositionContractMismatchException(SR.Format(
                                                                               SR.ContractMismatch_MetadataViewImplementationCanNotBeNull,
                                                                               metadataViewType.FullName));
                        }
                        else
                        {
                            if (!metadataViewType.IsAssignableFrom(proxyType))
                            {
                                throw new CompositionContractMismatchException(SR.Format(
                                                                                   SR.ContractMismatch_MetadataViewImplementationDoesNotImplementViewInterface,
                                                                                   metadataViewType.FullName,
                                                                                   proxyType.FullName));
                            }
                        }
                    }
                }
                else
                {
                    proxyType = metadataViewType;
                }

                // Now we have the type for the proxy create it
                try
                {
                    if (metadataViewFactory != null)
                    {
                        return(MetadataViewGenerator.CreateMetadataView <TMetadataView>(metadataViewFactory, metadata));
                    }
                    else
                    {
                        if (proxyType == null)
                        {
                            throw new Exception(SR.Diagnostic_InternalExceptionMessage);
                        }
                        return((TMetadataView)proxyType.SafeCreateInstance(metadata) !);
                    }
                }
                catch (MissingMethodException ex)
                {
                    // Unable to create an Instance of the Metadata view '{0}' because a constructor could not be selected.  Ensure that the type implements a constructor which takes an argument of type IDictionary<string, object>.
                    throw new CompositionContractMismatchException(SR.Format(
                                                                       SR.CompositionException_MetadataViewInvalidConstructor,
                                                                       proxyType !.AssemblyQualifiedName), ex);
                }
                catch (TargetInvocationException ex)
                {
                    //Unwrap known failures that we want to present as CompositionContractMismatchException
                    if (metadataViewType.IsInterface)
                    {
                        if (ex.InnerException !.GetType() == typeof(InvalidCastException))
                        {
                            // Unable to create an Instance of the Metadata view {0} because the exporter exported the metadata for the item {1} with the value {2} as type {3} but the view imports it as type {4}.
                            throw new CompositionContractMismatchException(SR.Format(
                                                                               SR.ContractMismatch_InvalidCastOnMetadataField,
                                                                               ex.InnerException.Data[MetadataViewGenerator.MetadataViewType],
                                                                               ex.InnerException.Data[MetadataViewGenerator.MetadataItemKey],
                                                                               ex.InnerException.Data[MetadataViewGenerator.MetadataItemValue],
                                                                               ex.InnerException.Data[MetadataViewGenerator.MetadataItemSourceType],
                                                                               ex.InnerException.Data[MetadataViewGenerator.MetadataItemTargetType]), ex);
                        }
                        else if (ex.InnerException.GetType() == typeof(NullReferenceException))
                        {
                            // Unable to create an Instance of the Metadata view {0} because the exporter exported the metadata for the item {1} with a null value and null is not a valid value for type {2}.
                            throw new CompositionContractMismatchException(SR.Format(
                                                                               SR.ContractMismatch_NullReferenceOnMetadataField,
                                                                               ex.InnerException.Data[MetadataViewGenerator.MetadataViewType],
                                                                               ex.InnerException.Data[MetadataViewGenerator.MetadataItemKey],
                                                                               ex.InnerException.Data[MetadataViewGenerator.MetadataItemTargetType]), ex);
                        }
                    }
                    throw;
                }
            }
Exemple #2
0
        public static TMetadataView GetMetadataView <TMetadataView>(IDictionary <string, object> metadata)
        {
            Type metadataViewType = typeof(TMetadataView);

            // If the Metadata dictionary is cast compatible with the passed in type
            if (metadataViewType.IsAssignableFrom(typeof(IDictionary <string, object>)))
            {
                return((TMetadataView)metadata);
            }
            // otherwise is it a metadata view
            else
            {
                Type proxyType;
                if (metadataViewType.IsInterface)
                {
                    try
                    {
                        proxyType = MetadataViewGenerator.GenerateView(metadataViewType);
                    }
                    catch (TypeLoadException ex)
                    {
                        throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Strings.NotSupportedInterfaceMetadataView, metadataViewType.FullName), ex);
                    }
                }
                else
                {
                    proxyType = metadataViewType;
                }

                // Now we have the type for the proxy create it
                try
                {
                    return((TMetadataView)proxyType.SafeCreateInstance(metadata));
                }
                catch (MissingMethodException ex)
                {
                    // Unable to create an Instance of the Metadata view '{0}' because a constructor could not be selected.  Ensure that the type implements a constructor which takes an argument of type IDictionary<string, object>.
                    throw new CompositionContractMismatchException(string.Format(CultureInfo.CurrentCulture,
                                                                                 Strings.CompositionException_MetadataViewInvalidConstructor,
                                                                                 proxyType.AssemblyQualifiedName), ex);
                }
                catch (TargetInvocationException ex)
                {
                    //Unwrap known failures that we want to present as CompositionContractMismatchException
                    if (metadataViewType.IsInterface)
                    {
                        if (ex.InnerException.GetType() == typeof(InvalidCastException))
                        {
                            // Unable to create an Instance of the Metadata view {0} because the exporter exported the metadata for the item {1} with the value {2} as type {3} but the view imports it as type {4}.
                            throw new CompositionContractMismatchException(string.Format(CultureInfo.CurrentCulture,
                                                                                         Strings.ContractMismatch_InvalidCastOnMetadataField,
                                                                                         ex.InnerException.Data[MetadataViewGenerator.MetadataViewType],
                                                                                         ex.InnerException.Data[MetadataViewGenerator.MetadataItemKey],
                                                                                         ex.InnerException.Data[MetadataViewGenerator.MetadataItemValue],
                                                                                         ex.InnerException.Data[MetadataViewGenerator.MetadataItemSourceType],
                                                                                         ex.InnerException.Data[MetadataViewGenerator.MetadataItemTargetType]), ex);
                        }
                        else if (ex.InnerException.GetType() == typeof(NullReferenceException))
                        {
                            // Unable to create an Instance of the Metadata view {0} because the exporter exported the metadata for the item {1} with a null value and null is not a valid value for type {2}.
                            throw new CompositionContractMismatchException(string.Format(CultureInfo.CurrentCulture,
                                                                                         Strings.ContractMismatch_NullReferenceOnMetadataField,
                                                                                         ex.InnerException.Data[MetadataViewGenerator.MetadataViewType],
                                                                                         ex.InnerException.Data[MetadataViewGenerator.MetadataItemKey],
                                                                                         ex.InnerException.Data[MetadataViewGenerator.MetadataItemTargetType]), ex);
                        }
                    }
                    throw;
                }
            }
        }