Click here to Skip to main content
15,896,726 members
Articles / DevOps / Testing

Composite Application Reloaded

Rate me:
Please Sign up or sign in to vote.
4.88/5 (38 votes)
11 May 2011CPOL12 min read 118.5K   1.5K   95  
A much simpler composite application library.
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.ComponentModel.Composition.Primitives;
using Microsoft.Internal;
using Microsoft.Internal.Collections;
using System.Reflection;

namespace System.ComponentModel.Composition.ReflectionModel
{
    // Describes the import type of a Reflection-based import definition
    internal class ImportType
    {
        private static readonly Type LazyOfTType = typeof(Lazy<>);
        private static readonly Type LazyOfTMType = typeof(Lazy<,>);
        private static readonly Type ExportFactoryOfTType = typeof(ExportFactory<>);
        private static readonly Type ExportFactoryOfTMType = typeof(ExportFactory<,>);

        private readonly Type _type;
        private readonly bool _isAssignableCollectionType;
        private readonly Type _contractType;
        private Func<Export, object> _castSingleValue;

        public ImportType(Type type, ImportCardinality cardinality)
        {
            Assumes.NotNull(type);

            this._type = type;
            this._contractType = type;

            if (cardinality == ImportCardinality.ZeroOrMore)
            {
                this._isAssignableCollectionType = IsTypeAssignableCollectionType(type);
                this._contractType = CheckForCollection(type);
            }

            this._contractType = CheckForLazyAndPartCreator(this._contractType);
        }

        public bool IsAssignableCollectionType
        {
            get { return this._isAssignableCollectionType; }
        }

        public Type ElementType { get; private set; }

        public Type ActualType
        {
            get { return this._type; }
        }

        public bool IsPartCreator { get; private set; }

        public Type ContractType { get { return this._contractType; } }

        public Func<Export, object> CastExport { get { return this._castSingleValue; } }

        public Type MetadataViewType { get; private set; }

        private Type CheckForCollection(Type type)
        {
            this.ElementType = CollectionServices.GetEnumerableElementType(type);
            if (this.ElementType != null)
            {
                return this.ElementType;
            }
            return type;
        }

        private Type CheckForLazyAndPartCreator(Type type)
        {
            if (type.IsGenericType)
            {
                Type genericType = type.GetGenericTypeDefinition();
                Type[] arguments = type.GetGenericArguments();

                if (genericType == LazyOfTType)
                {
                    this._castSingleValue = ExportServices.CreateStronglyTypedLazyFactory(arguments[0], null);
                    return arguments[0];
                }

                if (genericType == LazyOfTMType)
                {
                    this.MetadataViewType = arguments[1];
                    this._castSingleValue = ExportServices.CreateStronglyTypedLazyFactory(arguments[0], arguments[1]);
                    return arguments[0];
                }

                if(genericType == ExportFactoryOfTType || genericType == ExportFactoryOfTMType)
                {
                    this.IsPartCreator = true;
                    if (arguments.Length == 1)
                    {
                        this._castSingleValue = ExportServices.CreateStronglyTypedExportFactoryFactory(arguments[0], null);
                    }
                    else
                    {
                        Assumes.IsTrue(arguments.Length == 2);
                        this._castSingleValue = ExportServices.CreateStronglyTypedExportFactoryFactory(arguments[0], arguments[1]);
                        this.MetadataViewType = arguments[1];
                    }

                    return arguments[0];
                }
            }

            return type;
        }

        private static bool IsTypeAssignableCollectionType(Type type)
        {
            if (type.IsArray || CollectionServices.IsEnumerableOfT(type))
            {
                return true;
            }

            return false;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) http://www.ansibleww.com.au
Australia Australia
The Australia born French man who went back to Australia later in life...
Finally got over life long (and mostly hopeless usually, yay!) chronic sicknesses.
Worked in Sydney, Brisbane, Darwin, Billinudgel, Darwin and Melbourne.

Comments and Discussions