Imported Upstream version 5.0.0.42

Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-04-10 11:41:01 +00:00
parent 1190d13a04
commit 6bdd276d05
19939 changed files with 3099680 additions and 93811 deletions

View File

@@ -0,0 +1,8 @@
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\dir.props" />
<PropertyGroup>
<PackageVersion>1.1.0</PackageVersion>
<AssemblyVersion>1.0.32.0</AssemblyVersion>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<ItemGroup>
<Project Include="System.Composition.Runtime.pkgproj" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
</Project>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<ItemGroup>
<ProjectReference Include="..\src\System.Composition.Runtime.builds">
<SupportedFramework>net45;netcore45;netcoreapp1.0;wp8;wpa81;$(AllXamarinFrameworks)</SupportedFramework>
</ProjectReference>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildConfigurations>
netstandard1.0;
netstandard;
</BuildConfigurations>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,91 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17626
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace System.Composition.Properties {
using System;
using System.Reflection;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("System.Composition.Properties.Resources", typeof(Resources).GetTypeInfo().Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to No export was found for the contract &apos;{0}&apos;..
/// </summary>
internal static string CompositionContext_NoExportFoundForContract {
get {
return ResourceManager.GetString("CompositionContext_NoExportFoundForContract", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Composition failed..
/// </summary>
internal static string CompositionFailedDefaultExceptionMessage {
get {
return ResourceManager.GetString("CompositionFailedDefaultExceptionMessage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to , .
/// </summary>
internal static string Formatter_ListSeparatorWithSpace {
get {
return ResourceManager.GetString("Formatter_ListSeparatorWithSpace", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="CompositionContext_NoExportFoundForContract" xml:space="preserve">
<value>No export was found for the contract '{0}'.</value>
</data>
<data name="CompositionFailedDefaultExceptionMessage" xml:space="preserve">
<value>Composition failed.</value>
</data>
<data name="Formatter_ListSeparatorWithSpace" xml:space="preserve">
<value>, </value>
</data>
</root>

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<ProjectGuid>{2711DFD2-8541-4628-BC53-EB784A14CDCF}</ProjectGuid>
<RootNamespace>System.Composition</RootNamespace>
<AssemblyName>System.Composition.Runtime</AssemblyName>
<PackageTargetFramework Condition="'$(TargetGroup)' == 'netstandard1.0'">netstandard1.0;portable-net45+win8+wp8+wpa81</PackageTargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard1.0-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard1.0-Release|AnyCPU'" />
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="System\Composition\CompositionContext.cs" />
<Compile Include="System\Composition\ExportFactoryOfT.cs" />
<Compile Include="System\Composition\ExportFactoryOfTTMetadata.cs" />
<Compile Include="System\Composition\ExportOfT.cs" />
<Compile Include="System\Composition\Hosting\CompositionFailedException.cs" />
<Compile Include="System\Composition\Hosting\Core\CompositionContract.cs" />
<Compile Include="System\Composition\Runtime\Util\Formatters.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetGroup)' == 'netstandard1.0'">
<Reference Include="System.Collections" />
<Reference Include="System.Diagnostics.Debug" />
<Reference Include="System.Diagnostics.Tools" />
<Reference Include="System.Globalization" />
<Reference Include="System.Linq" />
<Reference Include="System.Reflection" />
<Reference Include="System.Resources.ResourceManager" />
<Reference Include="System.Runtime" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>

View File

@@ -0,0 +1,211 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Composition.Hosting.Core;
using System.Composition.Hosting;
namespace System.Composition
{
/// <summary>
/// Provides retrieval of exports from the composition.
/// </summary>
public abstract class CompositionContext
{
private const string ImportManyImportMetadataConstraintName = "IsImportMany";
/// <summary>
/// Retrieve the single <paramref name="contract"/> instance from the
/// <see cref="CompositionContext"/>.
/// </summary>
/// <param name="contract">The contract to retrieve.</param>
/// <returns>An instance of the export.</returns>
/// <param name="export">The export if available, otherwise, null.</param>
/// <exception cref="CompositionFailedException" />
public abstract bool TryGetExport(CompositionContract contract, out object export);
/// <summary>
/// Retrieve the single <typeparamref name="TExport"/> instance from the
/// <see cref="CompositionContext"/>.
/// </summary>
/// <typeparam name="TExport">The type of the export to retrieve.</typeparam>
/// <returns>An instance of the export.</returns>
/// <exception cref="CompositionFailedException" />
public TExport GetExport<TExport>()
{
return GetExport<TExport>((string)null);
}
/// <summary>
/// Retrieve the single <typeparamref name="TExport"/> instance from the
/// <see cref="CompositionContext"/>.
/// </summary>
/// <typeparam name="TExport">The type of the export to retrieve.</typeparam>
/// <param name="contractName">Optionally, a discriminator that constrains the selection of the export.</param>
/// <returns>An instance of the export.</returns>
/// <exception cref="CompositionFailedException" />
public TExport GetExport<TExport>(string contractName)
{
return (TExport)GetExport(typeof(TExport), contractName);
}
/// <summary>
/// Retrieve the single <paramref name="exportType"/> instance from the
/// <see cref="CompositionContext"/>.
/// </summary>
/// <param name="exportType">The type of the export to retrieve.</param>
/// <param name="contractName">Optionally, a discriminator that constrains the selection of the export.</param>
/// <returns>An instance of the export.</returns>
/// <param name="export">The export if available, otherwise, null.</param>
/// <exception cref="CompositionFailedException" />
public bool TryGetExport(Type exportType, string contractName, out object export)
{
return TryGetExport(new CompositionContract(exportType, contractName), out export);
}
/// <summary>
/// Retrieve the single <paramref name="exportType"/> instance from the
/// <see cref="CompositionContext"/>.
/// </summary>
/// <param name="exportType">The type of the export to retrieve.</param>
/// <returns>An instance of the export.</returns>
/// <param name="export">The export if available, otherwise, null.</param>
/// <exception cref="CompositionFailedException" />
public bool TryGetExport(Type exportType, out object export)
{
return TryGetExport(exportType, null, out export);
}
/// <summary>
/// Retrieve the single <typeparamref name="TExport"/> instance from the
/// <see cref="CompositionContext"/>.
/// </summary>
/// <typeparam name="TExport">The type of the export to retrieve.</typeparam>
/// <returns>An instance of the export.</returns>
/// <param name="export">The export if available, otherwise, null.</param>
/// <exception cref="CompositionFailedException" />
public bool TryGetExport<TExport>(out TExport export)
{
return TryGetExport<TExport>(null, out export);
}
/// <summary>
/// Retrieve the single <typeparamref name="TExport"/> instance from the
/// <see cref="CompositionContext"/>.
/// </summary>
/// <typeparam name="TExport">The type of the export to retrieve.</typeparam>
/// <param name="contractName">Optionally, a discriminator that constrains the selection of the export.</param>
/// <returns>An instance of the export.</returns>
/// <param name="export">The export if available, otherwise, null.</param>
/// <exception cref="CompositionFailedException" />
public bool TryGetExport<TExport>(string contractName, out TExport export)
{
object untypedExport;
if (!TryGetExport(typeof(TExport), contractName, out untypedExport))
{
export = default(TExport);
return false;
}
export = (TExport)untypedExport;
return true;
}
/// <summary>
/// Retrieve the single <paramref name="exportType"/> instance from the
/// <see cref="CompositionContext"/>.
/// </summary>
/// <param name="exportType">The type of the export to retrieve.</param>
/// <returns>An instance of the export.</returns>
/// <exception cref="CompositionFailedException" />
public object GetExport(Type exportType)
{
return GetExport(exportType, (string)null);
}
/// <summary>
/// Retrieve the single <paramref name="exportType"/> instance from the
/// <see cref="CompositionContext"/>.
/// </summary>
/// <param name="exportType">The type of the export to retrieve.</param>
/// <param name="contractName">Optionally, a discriminator that constrains the selection of the export.</param>
/// <returns>An instance of the export.</returns>
/// <exception cref="CompositionFailedException" />
public object GetExport(Type exportType, string contractName)
{
return GetExport(new CompositionContract(exportType, contractName));
}
/// <summary>
/// Retrieve the single <paramref name="contract"/> instance from the
/// <see cref="CompositionContext"/>.
/// </summary>
/// <param name="contract">The contract of the export to retrieve.</param>
/// <returns>An instance of the export.</returns>
/// <exception cref="CompositionFailedException" />
public object GetExport(CompositionContract contract)
{
object export;
if (!TryGetExport(contract, out export))
throw new CompositionFailedException(
string.Format(Properties.Resources.CompositionContext_NoExportFoundForContract, contract));
return export;
}
/// <summary>
/// Retrieve the single <paramref name="exportType"/> instance from the
/// <see cref="CompositionContext"/>.
/// </summary>
/// <param name="exportType">The type of the export to retrieve.</param>
/// <exception cref="CompositionFailedException" />
public IEnumerable<object> GetExports(Type exportType)
{
return GetExports(exportType, (string)null);
}
/// <summary>
/// Retrieve the single <paramref name="exportType"/> instance from the
/// <see cref="CompositionContext"/>.
/// </summary>
/// <param name="exportType">The type of the export to retrieve.</param>
/// <param name="contractName">The discriminator to apply when selecting the export.</param>
/// <returns>An instance of the export.</returns>
/// <exception cref="CompositionFailedException" />
public IEnumerable<object> GetExports(Type exportType, string contractName)
{
var manyContract = new CompositionContract(
exportType.MakeArrayType(),
contractName,
new Dictionary<string, object> { { ImportManyImportMetadataConstraintName, true } });
return (IEnumerable<object>)GetExport(manyContract);
}
/// <summary>
/// Retrieve the single <typeparamref name="TExport"/> instance from the
/// <see cref="CompositionContext"/>.
/// </summary>
/// <typeparam name="TExport">The export type to retrieve.</typeparam>
/// <returns>An instance of the export.</returns>
/// <exception cref="CompositionFailedException" />
public IEnumerable<TExport> GetExports<TExport>()
{
return GetExports<TExport>((string)null);
}
/// <summary>
/// Retrieve the single <typeparamref name="TExport"/> instance from the
/// <see cref="CompositionContext"/>.
/// </summary>
/// <typeparam name="TExport">The export type to retrieve.</typeparam>
/// <returns>An instance of the export.</returns>
/// <param name="contractName">The discriminator to apply when selecting the export.</param>
/// <exception cref="CompositionFailedException" />
public IEnumerable<TExport> GetExports<TExport>(string contractName)
{
return (IEnumerable<TExport>)GetExports(typeof(TExport), contractName);
}
}
}

View File

@@ -0,0 +1,39 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Composition
{
/// <summary>
/// Can be imported by parts that wish to dynamically create instances of other parts.
/// </summary>
/// <typeparam name="T">The contract type of the created parts.</typeparam>
public class ExportFactory<T>
{
private readonly Func<Tuple<T, Action>> _exportLifetimeContextCreator;
/// <summary>
/// Construct an ExportFactory.
/// </summary>
/// <param name="exportCreator">Action invoked upon calls to the Create() method.</param>
public ExportFactory(Func<Tuple<T, Action>> exportCreator)
{
if (exportCreator == null)
{
throw new ArgumentNullException(nameof(exportCreator));
}
_exportLifetimeContextCreator = exportCreator;
}
/// <summary>
/// Create an instance of the exported part.
/// </summary>
/// <returns>A handle allowing the created part to be accessed then released.</returns>
public Export<T> CreateExport()
{
Tuple<T, Action> untypedLifetimeContext = _exportLifetimeContextCreator.Invoke();
return new Export<T>(untypedLifetimeContext.Item1, untypedLifetimeContext.Item2);
}
}
}

View File

@@ -0,0 +1,36 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Composition
{
/// <summary>
/// An ExportFactory that provides metadata describing the created exports.
/// </summary>
/// <typeparam name="T">The contract type being created.</typeparam>
/// <typeparam name="TMetadata">The metadata required from the export.</typeparam>
public class ExportFactory<T, TMetadata> : ExportFactory<T>
{
private readonly TMetadata _metadata;
/// <summary>
/// Construct an ExportFactory.
/// </summary>
/// <param name="exportCreator">Action invoked upon calls to the Create() method.</param>
/// <param name="metadata">The metadata associated with the export.</param>
public ExportFactory(Func<Tuple<T, Action>> exportCreator, TMetadata metadata)
: base(exportCreator)
{
_metadata = metadata;
}
/// <summary>
/// The metadata associated with the export.
/// </summary>
public TMetadata Metadata
{
get { return _metadata; }
}
}
}

View File

@@ -0,0 +1,51 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Composition
{
/// <summary>
/// A handle allowing the graph of parts associated with an exported instance
/// to be released.
/// </summary>
/// <typeparam name="T"></typeparam>
public sealed class Export<T> : IDisposable
{
private readonly T _value;
private readonly Action _disposeAction;
/// <summary>
/// Construct an ExportLifetimContext.
/// </summary>
/// <param name="value">The value of the export.</param>
/// <param name="disposeAction">An action that releases resources associated with the export.</param>
public Export(T value, Action disposeAction)
{
_value = value;
_disposeAction = disposeAction;
}
/// <summary>
/// The exported value.
/// </summary>
public T Value
{
get
{
return _value;
}
}
/// <summary>
/// Release the parts associated with the exported value.
/// </summary>
public void Dispose()
{
if (_disposeAction != null)
{
_disposeAction.Invoke();
}
}
}
}

View File

@@ -0,0 +1,38 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Composition.Hosting
{
/// <summary>
/// The exception type thrown when composition problems occur.
/// Exception should be assumed to be fatal for the entire composition/container unless
/// otherwise documented - no production code should throw this exception.
/// </summary>
public class CompositionFailedException : Exception
{
/// <summary>
/// Construct a <see cref="CompositionFailedException"/> with the default message.
/// </summary>
public CompositionFailedException()
: base(Properties.Resources.CompositionFailedDefaultExceptionMessage)
{ }
/// <summary>
/// Construct a <see cref="CompositionFailedException"/>.
/// </summary>
/// <param name="message">The exception message.</param>
public CompositionFailedException(string message)
: base(message)
{ }
/// <summary>
/// Construct a <see cref="CompositionFailedException"/>.
/// </summary>
/// <param name="message">The exception message.</param>
/// <param name="innerException">The inner exception.</param>
public CompositionFailedException(string message, Exception innerException)
: base(message, innerException)
{ }
}
}

View File

@@ -0,0 +1,248 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections;
using System.Collections.Generic;
using System.Composition.Runtime.Util;
using System.Linq;
namespace System.Composition.Hosting.Core
{
/// <summary>
/// The link between exports and imports.
/// </summary>
public sealed class CompositionContract
{
private readonly Type _contractType;
private readonly string _contractName;
private readonly IDictionary<string, object> _metadataConstraints;
/// <summary>
/// Construct a <see cref="CompositionContract"/>.
/// </summary>
/// <param name="contractType">The type shared between the exporter and importer.</param>
public CompositionContract(Type contractType)
: this(contractType, null)
{
}
/// <summary>
/// Construct a <see cref="CompositionContract"/>.
/// </summary>
/// <param name="contractType">The type shared between the exporter and importer.</param>
/// <param name="contractName">Optionally, a name that discriminates this contract from others with the same type.</param>
public CompositionContract(Type contractType, string contractName)
: this(contractType, contractName, null)
{
}
/// <summary>
/// Construct a <see cref="CompositionContract"/>.
/// </summary>
/// <param name="contractType">The type shared between the exporter and importer.</param>
/// <param name="contractName">Optionally, a name that discriminates this contract from others with the same type.</param>
/// <param name="metadataConstraints">Optionally, a non-empty collection of named constraints that apply to the contract.</param>
public CompositionContract(Type contractType, string contractName, IDictionary<string, object> metadataConstraints)
{
if (contractType == null) throw new ArgumentNullException(nameof(contractType));
if (metadataConstraints != null && metadataConstraints.Count == 0) throw new ArgumentOutOfRangeException(nameof(metadataConstraints));
_contractType = contractType;
_contractName = contractName;
_metadataConstraints = metadataConstraints;
}
/// <summary>
/// The type shared between the exporter and importer.
/// </summary>
public Type ContractType { get { return _contractType; } }
/// <summary>
/// A name that discriminates this contract from others with the same type.
/// </summary>
public string ContractName { get { return _contractName; } }
/// <summary>
/// Constraints applied to the contract. Instead of using this collection
/// directly it is advisable to use the <see cref="TryUnwrapMetadataConstraint"/> method.
/// </summary>
public IEnumerable<KeyValuePair<string, object>> MetadataConstraints { get { return _metadataConstraints; } }
/// <summary>
/// Determines equality between two contracts.
/// </summary>
/// <param name="obj">The contract to test.</param>
/// <returns>True if the contracts are equivalent; otherwise, false.</returns>
public override bool Equals(object obj)
{
var contract = obj as CompositionContract;
return contract != null &&
contract._contractType.Equals(_contractType) &&
(_contractName == null ? contract._contractName == null : _contractName.Equals(contract._contractName)) &&
ConstraintEqual(_metadataConstraints, contract._metadataConstraints);
}
/// <summary>
/// Gets a hash code for the contract.
/// </summary>
/// <returns>The hash code.</returns>
public override int GetHashCode()
{
var hc = _contractType.GetHashCode();
if (_contractName != null)
hc = hc ^ _contractName.GetHashCode();
if (_metadataConstraints != null)
hc = hc ^ ConstraintHashCode(_metadataConstraints);
return hc;
}
/// <summary>
/// Creates a string representation of the contract.
/// </summary>
/// <returns>A string representation of the contract.</returns>
public override string ToString()
{
var result = Formatters.Format(_contractType);
if (_contractName != null)
result += " " + Formatters.Format(_contractName);
if (_metadataConstraints != null)
result += string.Format(" {{ {0} }}",
string.Join(Properties.Resources.Formatter_ListSeparatorWithSpace,
_metadataConstraints.Select(kv => string.Format("{0} = {1}", kv.Key, Formatters.Format(kv.Value)))));
return result;
}
/// <summary>
/// Transform the contract into a matching contract with a
/// new contract type (with the same contract name and constraints).
/// </summary>
/// <param name="newContractType">The contract type for the new contract.</param>
/// <returns>A matching contract with a
/// new contract type.</returns>
public CompositionContract ChangeType(Type newContractType)
{
if (newContractType == null) throw new ArgumentNullException(nameof(newContractType));
return new CompositionContract(newContractType, _contractName, _metadataConstraints);
}
/// <summary>
/// Check the contract for a constraint with a particular name and value, and, if it exists,
/// retrieve both the value and the remainder of the contract with the constraint
/// removed.
/// </summary>
/// <typeparam name="T">The type of the constraint value.</typeparam>
/// <param name="constraintName">The name of the constraint.</param>
/// <param name="constraintValue">The value if it is present and of the correct type, otherwise null.</param>
/// <param name="remainingContract">The contract with the constraint removed if present, otherwise null.</param>
/// <returns>True if the constraint is present and of the correct type, otherwise false.</returns>
public bool TryUnwrapMetadataConstraint<T>(string constraintName, out T constraintValue, out CompositionContract remainingContract)
{
if (constraintName == null) throw new ArgumentNullException(nameof(constraintName));
constraintValue = default(T);
remainingContract = null;
if (_metadataConstraints == null)
return false;
object value;
if (!_metadataConstraints.TryGetValue(constraintName, out value))
return false;
if (!(value is T))
return false;
constraintValue = (T)value;
if (_metadataConstraints.Count == 1)
{
remainingContract = new CompositionContract(_contractType, _contractName);
}
else
{
var remainingConstraints = new Dictionary<string, object>(_metadataConstraints);
remainingConstraints.Remove(constraintName);
remainingContract = new CompositionContract(_contractType, _contractName, remainingConstraints);
}
return true;
}
internal static bool ConstraintEqual(IDictionary<string, object> first, IDictionary<string, object> second)
{
if (first == second)
return true;
if (first == null || second == null)
return false;
if (first.Count != second.Count)
return false;
foreach (var firstItem in first)
{
object secondValue;
if (!second.TryGetValue(firstItem.Key, out secondValue))
return false;
if (firstItem.Value == null && secondValue != null ||
secondValue == null && firstItem.Value != null)
{
return false;
}
else
{
var firstEnumerable = firstItem.Value as IEnumerable;
if (firstEnumerable != null && !(firstEnumerable is string))
{
var secondEnumerable = secondValue as IEnumerable;
if (secondEnumerable == null || !Enumerable.SequenceEqual(firstEnumerable.Cast<object>(), secondEnumerable.Cast<object>()))
return false;
}
else if (!firstItem.Value.Equals(secondValue))
{
return false;
}
}
}
return true;
}
private static int ConstraintHashCode(IDictionary<string, object> metadata)
{
var result = -1;
foreach (var kv in metadata)
{
result ^= kv.Key.GetHashCode();
if (kv.Value != null)
{
var sval = kv.Value as string;
if (sval != null)
{
result ^= sval.GetHashCode();
}
else
{
var enumerableValue = kv.Value as IEnumerable;
if (enumerableValue != null)
{
foreach (var ev in enumerableValue)
if (ev != null)
result ^= ev.GetHashCode();
}
else
{
result ^= kv.Value.GetHashCode();
}
}
}
}
return result;
}
}
}

View File

@@ -0,0 +1,41 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Linq;
namespace System.Composition.Runtime.Util
{
internal static class Formatters
{
public static string Format(object value)
{
if (value == null)
throw new ArgumentNullException(nameof(value));
if (value is string)
return "\"" + value + "\"";
return value.ToString();
}
public static string Format(Type type)
{
if (type == null) throw new ArgumentNullException(nameof(type));
if (type.IsConstructedGenericType)
return FormatClosedGeneric(type);
return type.Name;
}
private static string FormatClosedGeneric(Type closedGenericType)
{
if (closedGenericType == null) throw new ArgumentNullException(nameof(closedGenericType));
if (!closedGenericType.IsConstructedGenericType) throw new ArgumentException();
var name = closedGenericType.Name.Substring(0, closedGenericType.Name.IndexOf("`"));
var args = closedGenericType.GenericTypeArguments.Select(t => Format(t));
return string.Format("{0}<{1}>", name, string.Join(Properties.Resources.Formatter_ListSeparatorWithSpace, args));
}
}
}