This commit is contained in:
Rodrigo B. de Oliveira 2012-10-05 12:19:36 -03:00
Родитель e59265aea5
Коммит 02a5b5d1b8
41 изменённых файлов: 1694 добавлений и 0 удалений

12
.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,12 @@
bin
obj
build
out
libs
.gradle
*.iml
*.ipr
*.iws
*~
*.user
gradle.properties

16
build.gradle Executable file
Просмотреть файл

@ -0,0 +1,16 @@
apply plugin: 'idea'
buildscript {
repositories {
ivy { url '../repository' }
ivy { url 'http://unity-technologies.github.com/kaizen/repositories/integration' }
}
dependencies {
classpath group: 'kaizen', name: 'kaizen', version: 'latest.integration'
}
}
apply plugin: 'kaizen-bundle'
version = '1.0'

Двоичные данные
gradle/wrapper/gradle-wrapper.jar поставляемый Executable file

Двоичный файл не отображается.

6
gradle/wrapper/gradle-wrapper.properties поставляемый Executable file
Просмотреть файл

@ -0,0 +1,6 @@
#Thu Sep 27 09:13:56 BRT 2012
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-1.2-bin.zip

164
gradlew поставляемый Executable file
Просмотреть файл

@ -0,0 +1,164 @@
#!/bin/bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/"
APP_HOME="`pwd -P`"
cd "$SAVED"
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

90
gradlew.bat поставляемый Executable file
Просмотреть файл

@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

15
settings.gradle Executable file
Просмотреть файл

@ -0,0 +1,15 @@
include 'CodeEditor.Composition'
//include 'CodeEditor.Text'
//include 'CodeEditor.Collections'
//include 'CodeEditor.UI.UnityEditor'
rootProject.children.each { project ->
def projectDirName = "src/$project.name"
project.projectDir = new File(settingsDir, projectDirName)
assert project.projectDir.isDirectory()
project.buildFileName = "${project.name}.gradle"
assert project.buildFile.isFile()
}

Просмотреть файл

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{2ED73522-E34D-4CAB-8A42-6421FB9B1E77}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CodeEditor.Composition.Tests</RootNamespace>
<AssemblyName>CodeEditor.Composition.Tests</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="nunit.framework, Version=2.6.0.12051, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\NUnit\bin\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CompositionContainerTest.cs" />
<Compile Include="LazyImportManyTest.cs" />
<Compile Include="ImportDefinitionProviderTest.cs" />
<Compile Include="LazyImportTest.cs" />
<Compile Include="LazyTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Frameworks\CodeEditor.Composition\CodeEditor.Composition.csproj">
<Project>{9DB8BFD3-06C8-4A8C-8842-5931B924B56C}</Project>
<Name>CodeEditor.Composition</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -0,0 +1,4 @@
dependencies {
editor project(path: ':CodeEditor.Composition', configuration: 'editor')
editor group: 'nunit', name: 'nunit.framework', version: '2.6.0.12051'
}

Просмотреть файл

@ -0,0 +1,142 @@
using CodeEditor.Composition.Hosting;
using CodeEditor.Composition.Primitives;
using NUnit.Framework;
namespace CodeEditor.Composition.Tests
{
[TestFixture]
public class CompositionContainerTest
{
private CompositionContainer _container;
[SetUp]
public void SetUp()
{
_container = new CompositionContainer(GetType().Assembly);
}
[Test]
public void ContainerIsExportedAsExportProvider()
{
Assert.AreSame(_container, GetExportedValue<IExportProvider>());
}
[Test]
public void GetExportedValueAlwaysReturnSameValue()
{
var service = GetExportedValue<AService>();
Assert.IsNotNull(service);
Assert.AreSame(service, GetExportedValue<AService>());
}
[Test]
public void GetExportedValueSatisfiesPropertyImports()
{
Assert.AreSame(GetExportedValue<AService>(), GetExportedValue<AServiceWithDependencies>().AService);
}
[Test]
public void GetExportedValueSatisfiesFieldImports()
{
Assert.AreSame(GetExportedValue<AService>(), GetExportedValue<AServiceWithFieldDependencies>().AService);
}
[Test]
public void GetExportedValueSatisfiesInterfaceImportImplementedByInternalType()
{
Assert.AreSame(GetExportedValue<IService>(), GetExportedValue<IServiceWithDependencies>().AService);
}
[Test]
public void GetExportedValueSatisfiesImportingConstructor()
{
Assert.AreSame(GetExportedValue<IService>(), GetExportedValue<ServiceWithImportingConstructor>().AService);
}
[Test]
public void PartCanExportMultipleContracts()
{
Assert.AreSame(GetExportedValue<IContract1>(), GetExportedValue<IContract2>());
Assert.IsTrue(GetExportedValue<IContract1>() is PartWithMultipleContracts);
}
private T GetExportedValue<T>()
{
return _container.GetExportedValue<T>();
}
// ReSharper disable ClassNeverInstantiated.Global
[Export]
public class AService
{
}
[Export]
public class AServiceWithDependencies
{
[Import]
// ReSharper disable UnusedAutoPropertyAccessor.Global
public AService AService { get; set; }
// ReSharper restore UnusedAutoPropertyAccessor.Global
}
[Export]
public class AServiceWithFieldDependencies
{
[Import]
public AService AService;
}
public interface IServiceWithDependencies
{
IService AService { get; }
}
public interface IService
{
}
// ReSharper disable UnusedMember.Global
[Export(typeof(IService))]
internal class ServiceImpl : IService
{
}
[Export(typeof(IServiceWithDependencies))]
internal class ServiceWithDependenciesImpl : IServiceWithDependencies
{
[Import]
// ReSharper disable UnusedAutoPropertyAccessor.Global
public IService AService { get; set; }
// ReSharper restore UnusedAutoPropertyAccessor.Global
}
// ReSharper restore UnusedMember.Global
[Export]
public class ServiceWithImportingConstructor
{
[ImportingConstructor]
ServiceWithImportingConstructor(IService service)
{
AService = service;
}
public IService AService { get; private set; }
}
// ReSharper restore ClassNeverInstantiated.Global
public interface IContract1
{
}
public interface IContract2
{
}
[Export(typeof(IContract1))]
[Export(typeof(IContract2))]
public class PartWithMultipleContracts : IContract1, IContract2
{
}
}
}

Просмотреть файл

@ -0,0 +1,48 @@
using System.Linq;
using CodeEditor.Composition.Primitives;
using NUnit.Framework;
namespace CodeEditor.Composition.Tests
{
[TestFixture]
public class ImportDefinitionProviderTest
{
[Test]
public void LazyImport()
{
var provider = new ImportDefinitionProvider();
var import = provider.ImportsFor(typeof(ClassWithLazyImport)).Single();
Assert.AreEqual(typeof(IService), import.ContractType);
Assert.AreEqual(ImportCardinality.One, import.Cardinality);
}
[Test]
public void LazyImportMany()
{
var provider = new ImportDefinitionProvider();
var import = provider.ImportsFor(typeof(ClassWithLazyImportMany)).Single();
Assert.AreEqual(typeof(IService), import.ContractType);
Assert.AreEqual(ImportCardinality.Many, import.Cardinality);
}
public class ClassWithLazyImport
{
[Import]
public Lazy<IService, IServiceMetadata> Service;
}
public class ClassWithLazyImportMany
{
[ImportMany]
public Lazy<IService, IServiceMetadata>[] Services;
}
public interface IService
{
}
public interface IServiceMetadata
{
}
}
}

Просмотреть файл

@ -0,0 +1,76 @@
using System.Linq;
using CodeEditor.Composition.Hosting;
using NUnit.Framework;
namespace CodeEditor.Composition.Tests
{
[TestFixture]
public class LazyImportManyTest
{
[Test]
public void OnlyServicesWithMatchingMetadataAreProvided()
{
var container = new CompositionContainer(GetType().Assembly);
var service = container.GetExportedValue<ServiceWithImports>();
Assert.IsNotNull(service.Imports);
var expected = new[]
{
new {Type = typeof(Service1), Name = "Foo"},
new {Type = typeof(Service2), Name = "Bar"}
};
var actual = service.Imports
.Select(import => new {Type = import.Value.GetType(), import.Metadata.Name});
CollectionAssert.AreEquivalent(expected, actual.ToArray());
}
[Export]
// ReSharper disable ClassNeverInstantiated.Local
class ServiceWithImports
{
[ImportMany]
#pragma warning disable 649
public Lazy<IService, IServiceMetadata>[] Imports;
#pragma warning restore 649
}
interface IService
{
}
[ExportServiceWithMetadata("Foo")]
class Service1 : IService
{
}
[ExportServiceWithMetadata("Bar")]
class Service2 : IService
{
}
[Export(typeof(IService))]
// ReSharper disable UnusedMember.Local
class ServiceWithoutMetadata : IService
// ReSharper restore UnusedMember.Local
{
}
// ReSharper restore ClassNeverInstantiated.Local
interface IServiceMetadata
{
string Name { get; }
}
class ExportServiceWithMetadata : ExportAttribute, IServiceMetadata
{
public string Name { get; private set; }
public ExportServiceWithMetadata(string name) : base(typeof(IService))
{
Name = name;
}
}
}
}

Просмотреть файл

@ -0,0 +1,50 @@
using CodeEditor.Composition.Hosting;
using NUnit.Framework;
namespace CodeEditor.Composition.Tests
{
[TestFixture]
public class LazyImportTest
{
[Test]
public void MetadataIsProvided()
{
var container = new CompositionContainer(GetType().Assembly);
var service = container.GetExportedValue<ServiceWithLazyImport>();
Assert.IsNotNull(service.Import);
Assert.AreEqual(42, service.Import.Metadata.Value);
Assert.IsNotNull(service.Import.Value);
Assert.AreSame(service.Import.Value, service.Import.Value);
}
[Export]
public class ServiceWithLazyImport
{
[Import]
public Lazy<ServiceWithMetadata, IServiceMetadata> Import;
}
[ExportWithMetadata(42)]
public class ServiceWithMetadata
{
}
public interface IServiceMetadata
{
int Value { get; }
}
class ExportWithMetadataAttribute : ExportAttribute, IServiceMetadata
{
public int Value { get; private set; }
public ExportWithMetadataAttribute(int value)
{
Value = value;
}
}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
using NUnit.Framework;
namespace CodeEditor.Composition.Tests
{
[TestFixture]
public class LazyTest
{
[Test]
public void FactoryIsInvokedOnlyOnce()
{
var count = 0;
var lazy = new Lazy<object>(() => (object) ++count);
Assert.AreEqual(0, count);
Assert.AreEqual(1, lazy.Value);
Assert.AreEqual(1, count);
Assert.AreEqual(1, lazy.Value);
Assert.AreEqual(1, count);
}
}
}

Просмотреть файл

@ -0,0 +1,8 @@
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("CodeEditor.Composition.Tests")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Просмотреть файл

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{9DB8BFD3-06C8-4A8C-8842-5931B924B56C}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CodeEditor.Composition</RootNamespace>
<AssemblyName>CodeEditor.Composition</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<OldToolsVersion>3.5</OldToolsVersion>
<SolutionDir Condition="'$(SolutionDir)' == ''">..\..\..\</SolutionDir>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\$(Configuration)\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\$(Configuration)\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CompositionError.cs" />
<Compile Include="CompositionException.cs" />
<Compile Include="Hosting\AssemblyExtensions.cs" />
<Compile Include="Hosting\DirectoryCatalog.cs" />
<Compile Include="ICompositionContainer.cs" />
<Compile Include="Lazy.cs" />
<Compile Include="Hosting\AggregateCatalog.cs" />
<Compile Include="Hosting\AssemblyCatalog.cs" />
<Compile Include="Hosting\CompositionContainer.cs" />
<Compile Include="ContractAttribute.cs" />
<Compile Include="ExportAttribute.cs" />
<Compile Include="Primitives\CustomAttribute.cs" />
<Compile Include="ImportManyAttribute.cs" />
<Compile Include="Primitives\Export.cs" />
<Compile Include="Primitives\ExportDefinition.cs" />
<Compile Include="Primitives\IExportDefinitionProvider.cs" />
<Compile Include="Primitives\IMetadataProvider.cs" />
<Compile Include="Primitives\ImportDefinition.cs" />
<Compile Include="ImportAttribute.cs" />
<Compile Include="ImportingConstructor.cs" />
<Compile Include="Primitives\ImportCardinality.cs" />
<Compile Include="Primitives\ImportDefinitionProvider.cs" />
<Compile Include="Primitives\TypeExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -0,0 +1,2 @@
version = '1.0'

Просмотреть файл

@ -0,0 +1,17 @@
using System;
namespace CodeEditor.Composition
{
public class CompositionError
{
public CompositionError(Type contractType, string message)
{
ContractType = contractType;
Message = message;
}
public Type ContractType { get; private set; }
public string Message { get; private set; }
}
}

Просмотреть файл

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
namespace CodeEditor.Composition
{
public class CompositionException : Exception
{
private readonly IList<CompositionError> _errors = new List<CompositionError>();
public CompositionException(CompositionError error) : base(error.Message)
{
Add(error);
}
public CompositionException(Exception cause, CompositionError error) : base(error.Message, cause)
{
Add(error);
}
public IList<CompositionError> Errors
{
get { return _errors; }
}
private void Add(CompositionError error)
{
_errors.Add(error);
}
}
}

Просмотреть файл

@ -0,0 +1,19 @@
using System;
namespace CodeEditor.Composition
{
public abstract class ContractAttribute : Attribute
{
private readonly Type _contractType;
protected ContractAttribute(Type contractType)
{
_contractType = contractType;
}
public Type ContractType
{
get { return _contractType; }
}
}
}

Просмотреть файл

@ -0,0 +1,15 @@
using System;
namespace CodeEditor.Composition
{
/// <summary>
/// Marks a class as an export.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class ExportAttribute : ContractAttribute
{
public ExportAttribute(Type contractType) : base(contractType) {}
public ExportAttribute() : base(null) {}
}
}

Просмотреть файл

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CodeEditor.Composition.Primitives;
namespace CodeEditor.Composition.Hosting
{
public class AggregateCatalog : IExportDefinitionProvider
{
private readonly IExportDefinitionProvider[] _exportDefinitionProviders;
public AggregateCatalog(IEnumerable<IExportDefinitionProvider> exportProviders) : this(exportProviders.ToArray())
{
}
public AggregateCatalog(params IExportDefinitionProvider[] exportDefinitionProviders)
{
_exportDefinitionProviders = exportDefinitionProviders;
}
public IEnumerable<ExportDefinition> GetExports(Type contractType)
{
return _exportDefinitionProviders.SelectMany(provider => provider.GetExports(contractType));
}
}
}

Просмотреть файл

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using CodeEditor.Composition.Primitives;
namespace CodeEditor.Composition.Hosting
{
public class AssemblyCatalog : IExportDefinitionProvider
{
public static IExportDefinitionProvider For(IEnumerable<Assembly> assemblies)
{
return new AggregateCatalog(AssemblyCatalogsFor(assemblies));
}
private static IEnumerable<IExportDefinitionProvider> AssemblyCatalogsFor(IEnumerable<Assembly> assemblies)
{
return assemblies
.Where(assembly => assembly.IsSafeForComposition())
.Select(assembly => (IExportDefinitionProvider) new AssemblyCatalog(assembly));
}
private Dictionary<Type, ExportDefinition[]> _exports;
private readonly Assembly _assembly;
public AssemblyCatalog(Assembly assembly)
{
_assembly = assembly;
}
public IEnumerable<ExportDefinition> GetExports(Type contractType)
{
ExportDefinition[] exportsDefinition;
return Exports().TryGetValue(contractType, out exportsDefinition)
? exportsDefinition
: NoExportsDefinition;
}
private Dictionary<Type, ExportDefinition[]> Exports()
{
lock (this)
return _exports ?? (_exports = ComputeExports());
}
private Dictionary<Type, ExportDefinition[]> ComputeExports()
{
return _assembly
.GetTypes()
.SelectMany<Type, ExportDefinition>(ExportsFromType)
.Where(e => e != null)
.GroupBy(e => e.ContractType)
.ToDictionary(e => e.Key, e => e.ToArray());
}
private IEnumerable<ExportDefinition> ExportsFromType(Type implementation)
{
return CustomAttribute<ExportAttribute>
.AllFrom(implementation)
.Select(attribute => new ExportDefinition(attribute.ContractType ?? implementation, implementation));
}
private static readonly ExportDefinition[] NoExportsDefinition = new ExportDefinition[0];
}
}

Просмотреть файл

@ -0,0 +1,36 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
namespace CodeEditor.Composition.Hosting
{
static class AssemblyExtensions
{
public static bool IsSafeForComposition(this Assembly assembly)
{
return CaresForComposition(assembly) && TypesAreAccessible(assembly);
}
private static bool CaresForComposition(Assembly assembly)
{
return assembly
.GetReferencedAssemblies()
.Any(name => name.FullName.Equals(typeof(ExportAttribute).Assembly.FullName));
}
private static bool TypesAreAccessible(Assembly assembly)
{
try
{
assembly.GetTypes();
return true;
}
catch (Exception e)
{
Trace.Write(string.Format("Error loading types from assembly `{0}': {1}", assembly, e));
return false;
}
}
}
}

Просмотреть файл

@ -0,0 +1,206 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using CodeEditor.Composition.Primitives;
namespace CodeEditor.Composition.Hosting
{
public class CompositionContainer : ICompositionContainer
{
private readonly Dictionary<Type, Export[]> _exports = new Dictionary<Type, Export[]>();
private readonly Dictionary<Type, Lazy<object>> _parts = new Dictionary<Type, Lazy<object>>();
private readonly IExportDefinitionProvider _exportDefinitionProvider;
private readonly ImportDefinitionProvider _importDefinitionProvider = new ImportDefinitionProvider();
public CompositionContainer(Assembly assembly)
: this(new AssemblyCatalog(assembly))
{
}
public CompositionContainer(params Assembly[] assemblies)
: this(AssemblyCatalog.For(assemblies))
{
}
public CompositionContainer(IExportDefinitionProvider definitionProvider)
{
_exportDefinitionProvider = definitionProvider;
AddExportedValue<IExportProvider>(this);
}
public void AddExportedValue<T>(T value)
{
AddExport(new Export(new ExportDefinition(typeof(T), value.GetType()), () => value));
}
private void AddExport(Export export)
{
_exports.Add(export.Definition.ContractType, new[] {export});
}
public T GetExportedValue<T>()
{
return (T) GetExportedValue(typeof(T));
}
public object GetExportedValue(Type contractType)
{
var export = GetExport(contractType);
if (export == null)
throw NoExportFoundError(contractType);
return export.Value;
}
private Export GetExport(Type contractType)
{
return GetExports(contractType).SingleOrDefault();
}
public IEnumerable<Export> GetExports(Type contractType)
{
lock (_exports)
return DoGetExports(contractType);
}
private IEnumerable<Export> DoGetExports(Type contractType)
{
Export[] existing;
if (_exports.TryGetValue(contractType, out existing))
return existing;
var exports = CreateExportsFor(contractType);
_exports.Add(contractType, exports);
return exports;
}
private Export[] CreateExportsFor(Type contractType)
{
return _exportDefinitionProvider
.GetExports(contractType)
.Select(e => new Export(e, FactoryFor(e)))
.ToArray();
}
private Func<object> FactoryFor(ExportDefinition exportDefinition)
{
return AccessorFor(exportDefinition, GetPartFor(exportDefinition.Implementation));
}
private Lazy<object> GetPartFor(Type implementation)
{
lock (_parts)
return DoGetPartFor(implementation);
}
private Lazy<object> DoGetPartFor(Type implementation)
{
Lazy<object> existing;
if (_parts.TryGetValue(implementation, out existing))
return existing;
var part = NewPartFor(implementation);
_parts.Add(implementation, part);
return part;
}
private Lazy<object> NewPartFor(Type implementation)
{
return new Lazy<object>(() => InstantiatePart(implementation));
}
private object InstantiatePart(Type implementation)
{
var importingConstructor = ImportingConstructorOf(implementation);
var part = importingConstructor != null
? CreateInstanceThrough(importingConstructor)
: Activator.CreateInstance(implementation);
ComposeParts(part);
return part;
}
private Func<object> AccessorFor(ExportDefinition exportDefinition, Lazy<object> part)
{
return () =>
{
try
{
return part.Value;
}
catch (Exception e)
{
throw new CompositionException(e,
new CompositionError(exportDefinition.ContractType, string.Format("Failed to create `{0}' to satisfy `{1}'!", exportDefinition.Implementation, exportDefinition.ContractType)));
}
};
}
private object CreateInstanceThrough(ConstructorInfo importingConstructor)
{
return importingConstructor.Invoke(ExportedValuesFor(importingConstructor).ToArray());
}
private IEnumerable<object> ExportedValuesFor(ConstructorInfo importingConstructor)
{
return importingConstructor.GetParameters().Select(p => GetExportedValue(p.ParameterType));
}
private static ConstructorInfo ImportingConstructorOf(Type implementation)
{
return implementation.InstanceConstructors().SingleOrDefault(IsImportingConstructor);
}
private static bool IsImportingConstructor(ConstructorInfo c)
{
return Attribute.IsDefined(c, typeof(ImportingConstructor));
}
private void ComposeParts(object part)
{
foreach (var import in ImportsOf(part))
Satisfy(import, part);
}
private void Satisfy(ImportDefinition importDefinition, object part)
{
var exports = GetExportsSatisfying(importDefinition);
Validate(importDefinition, exports);
importDefinition.SatisfyWith(exports, part);
}
private static void Validate(ImportDefinition importDefinition, Export[] exports)
{
switch (importDefinition.Cardinality)
{
case ImportCardinality.One:
if (exports.Length == 0)
throw NoExportFoundError(importDefinition.ContractType);
if (exports.Length != 1)
throw TooManyExportsError(importDefinition, exports);
break;
}
}
private static CompositionException TooManyExportsError(ImportDefinition importDefinition, Export[] exports)
{
return new CompositionException(
new CompositionError(importDefinition.ContractType, string.Format("Too many exports for `{0}': `{1}'.", importDefinition.ContractType, exports.Select(e => e.Definition.Implementation.FullName).ToList())));
}
private Export[] GetExportsSatisfying(ImportDefinition importDefinition)
{
return GetExports(importDefinition.ContractType)
.Where(importDefinition.IsSatisfiableBy)
.ToArray();
}
private IEnumerable<ImportDefinition> ImportsOf(object value)
{
return _importDefinitionProvider.ImportsFor(value.GetType());
}
private static CompositionException NoExportFoundError(Type contractType)
{
return new CompositionException(
new CompositionError(contractType, string.Format("Export `{0}' not found!", contractType)));
}
}
}

Просмотреть файл

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using CodeEditor.Composition.Primitives;
namespace CodeEditor.Composition.Hosting
{
public class DirectoryCatalog : IExportDefinitionProvider
{
private readonly IExportDefinitionProvider _catalog;
public DirectoryCatalog(string directory)
{
_catalog = AssemblyCatalog.For(AllAssembliesIn(directory));
}
public IEnumerable<ExportDefinition> GetExports(Type contractType)
{
return _catalog.GetExports(contractType);
}
private static Assembly[] AllAssembliesIn(string directory)
{
return Directory.GetFiles(directory, "*.dll").Select(s => Assembly.LoadFrom(s)).ToArray();
}
}
}

Просмотреть файл

@ -0,0 +1,8 @@
using CodeEditor.Composition.Primitives;
namespace CodeEditor.Composition
{
public interface ICompositionContainer : IExportProvider
{
}
}

Просмотреть файл

@ -0,0 +1,20 @@
using System;
using CodeEditor.Composition.Primitives;
namespace CodeEditor.Composition
{
/// <summary>
/// Imports a service.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class ImportAttribute : ContractAttribute
{
public ImportAttribute(Type contractType) : base(contractType) {}
public ImportAttribute() : base(null) {}
public virtual ImportCardinality Cardinality
{
get { return ImportCardinality.One; }
}
}
}

Просмотреть файл

@ -0,0 +1,20 @@
using System;
using CodeEditor.Composition.Primitives;
namespace CodeEditor.Composition
{
/// <summary>
/// Imports all providers of a service.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class ImportManyAttribute : ImportAttribute
{
public ImportManyAttribute(Type contractType) : base(contractType) { }
public ImportManyAttribute() : base(null) { }
public override ImportCardinality Cardinality
{
get { return ImportCardinality.Many; }
}
}
}

Просмотреть файл

@ -0,0 +1,9 @@
using System;
namespace CodeEditor.Composition
{
[AttributeUsage(AttributeTargets.Constructor)]
public class ImportingConstructor : Attribute
{
}
}

Просмотреть файл

@ -0,0 +1,62 @@
using System;
namespace CodeEditor.Composition
{
/// <summary>
/// A lazy import to allow selecting the right service based on
/// available metadata.
///
/// The service is only requested from the container when <see cref="Lazy{T}.Value"/>
/// is called.
/// </summary>
/// <typeparam name="T">the contract type</typeparam>
/// <typeparam name="TMetadata">the metadata type (must be compatible with a metadata attribute)</typeparam>
public class Lazy<T, TMetadata> : Lazy<T> where T: class
{
private readonly TMetadata _metadata;
public Lazy(Func<T> valueFactory, TMetadata metadata) : base(valueFactory)
{
_metadata = metadata;
}
public Lazy(Func<object> valueFactory, TMetadata metadata) : base(() => (T)valueFactory())
{
_metadata = metadata;
}
public TMetadata Metadata
{
get { return _metadata; }
}
}
public class Lazy<T> where T : class
{
private Func<T> _valueFactory;
private bool _hasValue;
private T _value;
public Lazy(Func<T> valueFactory)
{
_valueFactory = valueFactory;
}
public T Value
{
get
{
lock (this)
{
if (!_hasValue)
{
_value = _valueFactory();
_valueFactory = null;
_hasValue = true;
}
return _value;
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace CodeEditor.Composition.Primitives
{
static class CustomAttribute<T> where T : Attribute
{
public static T From(MemberInfo member)
{
return (T)Attribute.GetCustomAttribute(member, typeof(T));
}
public static IEnumerable<T> AllFrom(MemberInfo member)
{
return Attribute.GetCustomAttributes(member, typeof(T)).Cast<T>();
}
}
}

Просмотреть файл

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace CodeEditor.Composition.Primitives
{
public interface IExportProvider
{
IEnumerable<Export> GetExports(Type contractType);
}
public static class ExportProviderExtensions
{
public static IEnumerable<Export> GetExportsWhereMetadata<T>(this IExportProvider provider, Func<T, bool> predicate, Type contractType)
{
return provider.GetExports(contractType).Where(e => e.Metadata.OfType<T>().Any(predicate));
}
}
public class Export : Lazy<object>, IMetadataProvider
{
public Export(ExportDefinition definition, Func<object> valueFactory) : base(valueFactory)
{
Definition = definition;
}
public ExportDefinition Definition
{
get; private set;
}
public IEnumerable<object> Metadata
{
get { return Definition.Metadata; }
}
}
}

Просмотреть файл

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
namespace CodeEditor.Composition.Primitives
{
public class ExportDefinition : IMetadataProvider
{
public ExportDefinition(Type contractType, Type definition)
{
ContractType = contractType;
Implementation = definition;
}
public Type ContractType { get; private set; }
public Type Implementation { get; private set; }
public IEnumerable<object> Metadata
{
get { return Attribute.GetCustomAttributes(Implementation); }
}
}
}

Просмотреть файл

@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
namespace CodeEditor.Composition.Primitives
{
public interface IExportDefinitionProvider
{
IEnumerable<ExportDefinition> GetExports(Type contractType);
}
}

Просмотреть файл

@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace CodeEditor.Composition.Primitives
{
public interface IMetadataProvider
{
IEnumerable<object> Metadata { get; }
}
}

Просмотреть файл

@ -0,0 +1,8 @@
namespace CodeEditor.Composition.Primitives
{
public enum ImportCardinality
{
One,
Many
}
}

Просмотреть файл

@ -0,0 +1,32 @@
using System;
namespace CodeEditor.Composition.Primitives
{
public class ImportDefinition
{
private readonly Action<Export[], object> _action;
private readonly Func<Export, bool> _constraint;
public ImportDefinition(Type contractType, ImportCardinality cardinality, Action<Export[], object> action, Func<Export, bool> constraint)
{
ContractType = contractType;
Cardinality = cardinality;
_action = action;
_constraint = constraint;
}
public Type ContractType { get; private set; }
public ImportCardinality Cardinality { get; private set; }
public void SatisfyWith(Export[] export, object target)
{
_action(export, target);
}
public bool IsSatisfiableBy(Export export)
{
return _constraint(export);
}
}
}

Просмотреть файл

@ -0,0 +1,159 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace CodeEditor.Composition.Primitives
{
public class ImportDefinitionProvider
{
public IEnumerable<ImportDefinition> ImportsFor(Type type)
{
return type
.InstanceMembers()
.Select(m => new {Member = m, Attribute = ImportAttributeFrom(m)})
.Where(m => m.Attribute != null)
.Select(m => FromMember(m.Member, m.Attribute));
}
private static ImportDefinition FromMember(MemberInfo member, ImportAttribute import)
{
var property = member as PropertyInfo;
if (property != null)
return FromProperty(property, import);
var field = member as FieldInfo;
if (field != null)
return FromField(field, import);
throw new CompositionException(new CompositionError(import.ContractType, string.Format("Unsupported import `{0}'.", member)));
}
private static ImportDefinition FromField(FieldInfo fieldInfo, ImportAttribute import)
{
return ImportDefinitionFrom(import, fieldInfo.FieldType, fieldInfo.SetValue);
}
private static ImportDefinition FromProperty(PropertyInfo p, ImportAttribute import)
{
return ImportDefinitionFrom(import, p.PropertyType, (part, value) => p.SetValue(part, value, null));
}
private static ImportDefinition ImportDefinitionFrom(ImportAttribute import, Type actualType, Action<object, object> setter)
{
return new ImportDefinitionBuilder(import, actualType, setter).Build();
}
private static ImportAttribute ImportAttributeFrom(MemberInfo member)
{
return CustomAttribute<ImportAttribute>.From(member);
}
}
internal class ImportDefinitionBuilder
{
private readonly ImportAttribute _import;
private readonly Type _actualType;
private readonly Action<object, object> _setter;
private readonly bool _isLazyType;
private readonly Type _contractType;
private readonly Type _elementType;
public ImportDefinitionBuilder(ImportAttribute import, Type actualType, Action<object, object> setter)
{
_import = import;
_actualType = actualType;
_setter = setter;
_elementType = ElementType();
_isLazyType = IsLazyType(_elementType);
_contractType = ContractType();
}
public ImportDefinition Build()
{
return new ImportDefinition(_contractType, Cardinality, BuildSetter(), Constraint());
}
private Func<Export, bool> Constraint()
{
if (_isLazyType)
return MetadataConstraintFor(MetadataType);
return _ => true;
}
private static Func<Export, bool> MetadataConstraintFor(Type metadataType)
{
return export => export.Metadata.Any(metadataType.IsInstanceOfType);
}
private ImportCardinality Cardinality
{
get { return _import.Cardinality; }
}
private Action<Export[], object> BuildSetter()
{
return _isLazyType
? LazySetterFor(_elementType, _setter, Cardinality, MetadataType)
: EagerSetterFor(_elementType, _setter, Cardinality);
}
private Type MetadataType
{
get { return _elementType.GetGenericArguments()[1]; }
}
private static Action<Export[], object> LazySetterFor(Type elementType, Action<object, object> setter, ImportCardinality cardinality, Type metadataType)
{
if (cardinality == ImportCardinality.Many)
return (exports, part) => setter(part, ArrayOf(elementType, exports.Select(e => LazyInstanceFor(elementType, metadataType, e))));
return (exports, part) => setter(part, LazyInstanceFor(elementType, metadataType, exports.Single()));
}
private static Action<Export[], object> EagerSetterFor(Type elementType, Action<object, object> setter, ImportCardinality cardinality)
{
if (cardinality == ImportCardinality.Many)
return (exports, part) => setter(part, ArrayOf(elementType, exports.Select(e => e.Value)));
return (exports, part) => setter(part, exports.Single().Value);
}
private static Array ArrayOf(Type elementType, IEnumerable<object> elements)
{
var source = elements.ToArray();
var result = Array.CreateInstance(elementType, source.Length);
Array.Copy(source, result, source.Length);
return result;
}
private static object LazyInstanceFor(Type lazyType, Type metadataType, Export export)
{
Func<object> factory = () => export.Value;
var metadata = export.Metadata.Single(metadataType.IsInstanceOfType);
return Activator.CreateInstance(lazyType, new[] { factory, metadata });
}
private Type ContractType()
{
return _import.ContractType ?? InferContractTypeFromElementType();
}
private Type InferContractTypeFromElementType()
{
return _isLazyType
? _elementType.GetGenericArguments()[0]
: _elementType;
}
private Type ElementType()
{
return _import.Cardinality == ImportCardinality.Many
? _actualType.GetElementType()
: _actualType;
}
private static bool IsLazyType(Type t)
{
return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Lazy<,>);
}
}
}

Просмотреть файл

@ -0,0 +1,20 @@
using System;
using System.Reflection;
namespace CodeEditor.Composition.Primitives
{
static class TypeExtensions
{
private const BindingFlags InstanceMemberFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
public static MemberInfo[] InstanceMembers(this Type type)
{
return type.GetMembers(InstanceMemberFlags);
}
public static ConstructorInfo[] InstanceConstructors(this Type type)
{
return type.GetConstructors(InstanceMemberFlags);
}
}
}

Просмотреть файл

@ -0,0 +1,12 @@
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("CodeEditor.Composition")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyProduct("CodeEditor")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]