AttributedPartCreationInfo.cs :  » 2.6.4-mono-.net-core » System.ComponentModel » System » ComponentModel » Composition » AttributedModel » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.ComponentModel 
System.ComponentModel » System » ComponentModel » Composition » AttributedModel » AttributedPartCreationInfo.cs
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Diagnostics;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.ComponentModel.Composition.ReflectionModel;
using System.Linq;
using System.Reflection;
using Microsoft.Internal;
using Microsoft.Internal.Collections;

namespace System.ComponentModel.Composition.AttributedModel{
    internal class AttributedPartCreationInfo : IReflectionPartCreationInfo
    {
        private readonly Type _type;
        private readonly bool _ignoreConstructorImports = false;
        private readonly ICompositionElement _origin;
        private PartCreationPolicyAttribute _partCreationPolicy = null;
        private ConstructorInfo _constructor;
        private IEnumerable<ExportDefinition> _exports;
        private IEnumerable<ImportDefinition> _imports;
        private HashSet<string> _contractNamesOnNonInterfaces;

        public AttributedPartCreationInfo(Type type, PartCreationPolicyAttribute partCreationPolicy, bool ignoreConstructorImports, ICompositionElement origin)
        {
            Assumes.NotNull(type);
            this._type = type;
            this._ignoreConstructorImports = ignoreConstructorImports;
            this._partCreationPolicy = partCreationPolicy;
            this._origin = origin;
        }

        public Type GetPartType()
        {
            return this._type;
        }

        public Lazy<Type> GetLazyPartType()
        {
            return new Lazy<Type>(this.GetPartType, false);
        }

        public ConstructorInfo GetConstructor()
        {
            if (this._constructor == null && !this._ignoreConstructorImports)
            {
                this._constructor = SelectPartConstructor(this._type);
            }
            return this._constructor;
        }

        public IDictionary<string, object> GetMetadata()
        {
            return this._type.GetPartMetadataForType(this.CreationPolicy);
        }

        public IEnumerable<ExportDefinition> GetExports()
        {
            DiscoverExportsAndImports();
            return this._exports;
        }

        public IEnumerable<ImportDefinition> GetImports()
        {
            DiscoverExportsAndImports();
            return this._imports;
        }

        public bool IsDisposalRequired
        {
            get
            {
                return typeof(IDisposable).IsAssignableFrom(this.GetPartType());
            }
        }

        public bool IsPartDiscoverable()
        {
            if (this._type.IsAttributeDefined<PartNotDiscoverableAttribute>())
            {
                CompositionTrace.DefinitionMarkedWithPartNotDiscoverableAttribute(this._type);
                return false;
            }

            if (this._type.ContainsGenericParameters)
            {
                CompositionTrace.DefinitionContainsGenericsParameters(this._type);
                return false;
            }

            if (!HasExports())
            {
                CompositionTrace.DefinitionContainsNoExports(this._type);
                return false;
            }

            return true;
        }

        private bool HasExports()
        {
            return GetExportMembers(this._type).Any() ||
                   GetInheritedExports(this._type).Any();
        }

        string ICompositionElement.DisplayName
        {
            get { return this.GetDisplayName(); }
        }

        ICompositionElement ICompositionElement.Origin
        {
            get { return this._origin; }
        }

        public override string ToString()
        {
            return GetDisplayName();
        }

        private string GetDisplayName()
        {
            return this.GetPartType().GetDisplayName();
        }

        private CreationPolicy CreationPolicy
        {
            get
            {
                if (this._partCreationPolicy == null)
                {
                    this._partCreationPolicy = this._type.GetFirstAttribute<PartCreationPolicyAttribute>() ?? PartCreationPolicyAttribute.Default;
                }
                return this._partCreationPolicy.CreationPolicy;
            }
        }

        private static ConstructorInfo SelectPartConstructor(Type type)
        {
            Assumes.NotNull(type);

            if (type.IsAbstract)
            {
                return null;
            }

            // Only deal with non-static constructors
            BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;

            ConstructorInfo[] constructors = type.GetConstructors(flags);

            // Should likely only happen for static or abstract types
            if (constructors.Length == 0)
            {
                return null;
            }

            // Optimize single default constructor.
            if (constructors.Length == 1 && constructors[0].GetParameters().Length == 0)
            {
                return constructors[0];
            }

            // Select the marked constructor if there is exactly one marked
            IEnumerable<ConstructorInfo> importingConstructors = constructors.Where(
                ctor => ctor.IsAttributeDefined<ImportingConstructorAttribute>());

            switch (importingConstructors.GetCardinality())
            {
                case EnumerableCardinality.One:
                    {
                        return importingConstructors.First();
                    }

                case EnumerableCardinality.TwoOrMore:
                    {
                        // Return null, the part will error on instantiation.
                        return null;
                    }
            }

            // If there are no marked constructors then select the default constructor
            IEnumerable<ConstructorInfo> defaultConstructors = constructors.Where(
                ctor => ctor.GetParameters().Length == 0);

            // There should only ever be zero or one default constructors  
            return defaultConstructors.SingleOrDefault();
        }

        private void DiscoverExportsAndImports()
        {
            if (this._exports != null)
            {
                return;
            }

            this._exports = GetExportDefinitions();
            this._imports = GetImportDefinitions();
        }

        private IEnumerable<ExportDefinition> GetExportDefinitions()
        {
            List<ExportDefinition> exports = new List<ExportDefinition>();

            this._contractNamesOnNonInterfaces = new HashSet<string>();

            // GetExportMembers should only contain the type itself along with the members declared on it, 
            // it should not contain any base types, members on base types or interfaces on the type.
            foreach (MemberInfo member in GetExportMembers(this._type))
            {
                foreach (ExportAttribute exportAttribute in member.GetAttributes<ExportAttribute>())
                {
                    var attributedExportDefinition = new AttributedExportDefinition(this, member, exportAttribute);

                    if (exportAttribute.GetType() == CompositionServices.InheritedExportAttributeType)
                    {
                        // Any InheritedExports on the type itself are contributed during this pass 
                        // and we need to do the book keeping for those.
                        if (!this._contractNamesOnNonInterfaces.Contains(attributedExportDefinition.ContractName))
                        {
                            exports.Add(new ReflectionMemberExportDefinition(member.ToLazyMember(), attributedExportDefinition, this));
                            this._contractNamesOnNonInterfaces.Add(attributedExportDefinition.ContractName);
                        }
                    }
                    else
                    {
                        exports.Add(new ReflectionMemberExportDefinition(member.ToLazyMember(), attributedExportDefinition, this));
                    }
                }
            }

            // GetInheritedExports should only contain InheritedExports on base types or interfaces.
            // The order of types returned here is important because it is used as a 
            // priority list of which InhertedExport to choose if multiple exists with 
            // the same contract name. Therefore ensure that we always return the types
            // in the hiearchy from most derived to the lowest base type, followed
            // by all the interfaces that this type implements.
            foreach (Type type in GetInheritedExports(this._type))
            {
                foreach (InheritedExportAttribute exportAttribute in type.GetAttributes<InheritedExportAttribute>())
                {
                    var attributedExportDefinition = new AttributedExportDefinition(this, type, exportAttribute);

                    if (!this._contractNamesOnNonInterfaces.Contains(attributedExportDefinition.ContractName))
                    {
                        exports.Add(new ReflectionMemberExportDefinition(type.ToLazyMember(), attributedExportDefinition, this));

                        if (!type.IsInterface)
                        {
                            this._contractNamesOnNonInterfaces.Add(attributedExportDefinition.ContractName);
                        }
                    }
                }
            }

            this._contractNamesOnNonInterfaces = null; // No need to hold this state around any longer

            return exports;
        }

        private IEnumerable<MemberInfo> GetExportMembers(Type type)
        {
            BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public |
                BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;

            // If the type is abstract only find local static exports
            if (type.IsAbstract)
            {
                flags &= ~BindingFlags.Instance;
            }
            else if (IsExport(type))
            {
                yield return type;
            }

            // Walk the fields 
            foreach (var member in type.GetFields(flags))
            {
                if (IsExport(member))
                {
                    yield return member;
                }
            }

            // Walk the properties 
            foreach (var member in type.GetProperties(flags))
            {
                if (IsExport(member))
                {
                    yield return member;
                }
            }

            // Walk the methods 
            foreach (var member in type.GetMethods(flags))
            {
                if (IsExport(member))
                {
                    yield return member;
                }
            }
        }

        private IEnumerable<Type> GetInheritedExports(Type type)
        {
            // If the type is abstract we aren't interested in type level exports
            if (type.IsAbstract)
            {
                yield break;
            }

            // The order of types returned here is important because it is used as a 
            // priority list of which InhertedExport to choose if multiple exists with 
            // the same contract name. Therefore ensure that we always return the types
            // in the hiearchy from most derived to the lowest base type, followed
            // by all the interfaces that this type implements.

            Type currentType = type.BaseType;

            if (currentType == null)
            {
                yield break;
            }

            // Stopping at object instead of null to help with performance. It is a noticable performance
            // gain (~5%) if we don't have to try and pull the attributes we know don't exist on object.
            while (currentType != CompositionServices.ObjectType)
            {
                if (IsInheritedExport(currentType))
                {
                    yield return currentType;
                }
                currentType = currentType.BaseType;
            }

            foreach (Type iface in type.GetInterfaces())
            {
                if (IsInheritedExport(iface))
                {
                    yield return iface;
                }
            }
        }

        private static bool IsExport(ICustomAttributeProvider attributeProvider)
        {
            return attributeProvider.IsAttributeDefined<ExportAttribute>(false);
        }

        private static bool IsInheritedExport(ICustomAttributeProvider attributedProvider)
        {
            return attributedProvider.IsAttributeDefined<InheritedExportAttribute>(false);
        }

        private IEnumerable<ImportDefinition> GetImportDefinitions()
        {
            List<ImportDefinition> imports = new List<ImportDefinition>();

            foreach (MemberInfo member in GetImportMembers(this._type))
            {
                ReflectionMemberImportDefinition importDefinition = AttributedModelDiscovery.CreateMemberImportDefinition(member, this);
                imports.Add(importDefinition);
            }

            var constructor = this.GetConstructor();

            if (constructor != null)
            {
                foreach (ParameterInfo parameter in constructor.GetParameters())
                {
                    ReflectionParameterImportDefinition importDefinition = AttributedModelDiscovery.CreateParameterImportDefinition(parameter, this);
                    imports.Add(importDefinition);
                }
            }

            return imports;
        }

        private IEnumerable<MemberInfo> GetImportMembers(Type type)
        {
            if (type.IsAbstract)
            {
                yield break;
            }

            foreach (MemberInfo member in GetDeclaredOnlyImportMembers(type))
            {
                yield return member;
            }

            // Walk up the type chain until you hit object.
            if (type.BaseType != null)
            {
                Type baseType = type.BaseType;

                // Stopping at object instead of null to help with performance. It is a noticable performance
                // gain (~5%) if we don't have to try and pull the attributes we know don't exist on object.
                while (baseType != CompositionServices.ObjectType)
                {
                    foreach (MemberInfo member in GetDeclaredOnlyImportMembers(baseType))
                    {
                        yield return member;
                    }
                    baseType = baseType.BaseType;
                }
            }
        }

        private IEnumerable<MemberInfo> GetDeclaredOnlyImportMembers(Type type)
        {
            BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;

            // Walk the fields 
            foreach (var member in type.GetFields(flags))
            {
                if (IsImport(member))
                {
                    yield return member;
                }
            }

            // Walk the properties 
            foreach (var member in type.GetProperties(flags))
            {
                if (IsImport(member))
                {
                    yield return member;
                }
            }
        }

        private static bool IsImport(ICustomAttributeProvider attributeProvider)
        {
            return attributeProvider.IsAttributeDefined<IAttributedImport>(false);
        }
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.