diff --git a/src/AvalonStudio.Shell.Extensibility/AvalonStudio.Shell.Extensibility.csproj b/src/AvalonStudio.Shell.Extensibility/AvalonStudio.Shell.Extensibility.csproj
index 122ebb4..7fd94ca 100644
--- a/src/AvalonStudio.Shell.Extensibility/AvalonStudio.Shell.Extensibility.csproj
+++ b/src/AvalonStudio.Shell.Extensibility/AvalonStudio.Shell.Extensibility.csproj
@@ -11,6 +11,7 @@
+
diff --git a/src/AvalonStudio.Shell.Extensibility/IoC.cs b/src/AvalonStudio.Shell.Extensibility/IoC.cs
index ad7071b..50190ff 100644
--- a/src/AvalonStudio.Shell.Extensibility/IoC.cs
+++ b/src/AvalonStudio.Shell.Extensibility/IoC.cs
@@ -1,19 +1,19 @@
using System;
using System.Collections.Generic;
-using System.Composition.Hosting;
using System.Linq;
+using Microsoft.VisualStudio.Composition;
namespace AvalonStudio.Extensibility
{
public static class IoC
{
- private static CompositionHost s_compositionHost;
+ private static ExportProvider s_exportProvider;
public static object Get(Type t, string contract = null)
{
- if (s_compositionHost != null)
+ if (s_exportProvider != null)
{
- return s_compositionHost.GetExport(t, contract);
+ return s_exportProvider.AsExportProvider().GetExports(t, null, contract).SingleOrDefault();
}
return default;
@@ -21,9 +21,9 @@ public static object Get(Type t, string contract = null)
public static T Get(string contract)
{
- if (s_compositionHost != null)
+ if (s_exportProvider != null)
{
- return s_compositionHost.GetExport(contract);
+ return s_exportProvider.GetExportedValue(contract);
}
return default;
@@ -31,9 +31,9 @@ public static T Get(string contract)
public static T Get()
{
- if (s_compositionHost != null)
+ if (s_exportProvider != null)
{
- return s_compositionHost.GetExport();
+ return s_exportProvider.GetExportedValue();
}
return default;
@@ -41,9 +41,9 @@ public static T Get()
public static IEnumerable GetInstances()
{
- if (s_compositionHost != null)
+ if (s_exportProvider != null)
{
- return s_compositionHost.GetExports();
+ return s_exportProvider.GetExportedValues();
}
return Enumerable.Empty();
@@ -51,17 +51,17 @@ public static IEnumerable GetInstances()
public static IEnumerable GetInstances(string contract)
{
- if (s_compositionHost != null)
+ if (s_exportProvider != null)
{
- return s_compositionHost.GetExports(contract);
+ return s_exportProvider.GetExportedValues(contract);
}
return Enumerable.Empty();
}
- public static void Initialise(CompositionHost host)
+ public static void Initialise(ExportProvider exportProvider)
{
- s_compositionHost = host;
+ s_exportProvider = exportProvider;
}
}
}
\ No newline at end of file
diff --git a/src/AvalonStudio.Shell/AvalonStudio.Shell.csproj b/src/AvalonStudio.Shell/AvalonStudio.Shell.csproj
index 9f9cc7b..e8e1295 100644
--- a/src/AvalonStudio.Shell/AvalonStudio.Shell.csproj
+++ b/src/AvalonStudio.Shell/AvalonStudio.Shell.csproj
@@ -14,6 +14,7 @@
+
diff --git a/src/AvalonStudio.Shell/CompositionRoot.cs b/src/AvalonStudio.Shell/CompositionRoot.cs
index e1b299e..5f17b36 100644
--- a/src/AvalonStudio.Shell/CompositionRoot.cs
+++ b/src/AvalonStudio.Shell/CompositionRoot.cs
@@ -1,29 +1,88 @@
using AvalonStudio.Extensibility;
using AvalonStudio.Extensibility.Utils;
+using Microsoft.VisualStudio.Composition;
using System.Collections.Generic;
-using System.Composition.Convention;
-using System.Composition.Hosting;
+using System.IO;
using System.Reflection;
+using System.Threading;
+using System.Threading.Tasks;
namespace AvalonStudio
{
public static class CompositionRoot
{
- public static CompositionHost CreateContainer(ExtensionManager extensionManager)
+ public static async Task CreateExportProviderAsync(
+ ExtensionManager extensionManager,
+ CancellationToken cancellationToken = default)
{
- var conventions = new ConventionBuilder();
- conventions.ForTypesDerivedFrom().Export();
-
- // TODO AppDomain here is a custom appdomain from namespace AvalonStudio.Extensibility.Utils. It is able
- // to load any assembly in the bin directory (so not really appdomain) we need to get rid of this
- // once all our default extensions are published with a manifest and copied to extensions dir.
- var assemblies = AppDomain.CurrentDomain.GetAssemblies();
- var extensionAssemblies = LoadMefComponents(extensionManager);
-
- var configuration = new ContainerConfiguration()
- .WithAssemblies(assemblies, conventions)
- .WithAssemblies(extensionAssemblies);
- return configuration.CreateContainer();
+ var resolver = Resolver.DefaultInstance;
+
+ ComposableCatalog catalog;
+
+ var cachedCatalog = new CachedCatalog();
+
+ var cacheIsValid = false;
+ var cachePath = "";
+
+ if (cacheIsValid)
+ {
+ using (var cacheStream = File.OpenRead(cachePath))
+ {
+ catalog = await cachedCatalog.LoadAsync(cacheStream, resolver, cancellationToken);
+ }
+ }
+ else
+ {
+ var discovery = new AttributedPartDiscovery(resolver, true);
+
+ // TODO AppDomain here is a custom appdomain from namespace AvalonStudio.Extensibility.Utils. It is able
+ // to load any assembly in the bin directory (so not really appdomain) we need to get rid of this
+ // once all our default extensions are published with a manifest and copied to extensions dir.
+ var assemblies = AppDomain.CurrentDomain.GetAssemblies();
+ var extensionAssemblies = LoadMefComponents(extensionManager);
+
+ catalog = ComposableCatalog.Create(resolver)
+ .AddParts(await discovery.CreatePartsAsync(assemblies).ConfigureAwait(false))
+ .AddParts(await discovery.CreatePartsAsync(extensionAssemblies).ConfigureAwait(false));
+
+ // TODO: cache catalog
+ //using (var cacheStream = File.OpenWrite(cachePath))
+ //{
+ // await cachedCatalog.SaveAsync(catalog, cacheStream, cancellationToken);
+ //}
+ }
+
+ var configuration = CompositionConfiguration.Create(catalog);
+
+ // TODO: log errors to file
+
+ var compositionErrors = configuration.CompositionErrors;
+
+ while (!compositionErrors.IsEmpty)
+ {
+ var error = compositionErrors.Peek();
+
+ System.Console.WriteLine();
+ System.Console.WriteLine("Composition Error:");
+ System.Console.WriteLine();
+
+ foreach (var entry in error)
+ {
+ System.Console.WriteLine(entry.Message);
+
+ foreach (var part in entry.Parts)
+ {
+ System.Console.WriteLine($" Part: {part.Definition.Id}");
+ }
+ }
+
+ compositionErrors = compositionErrors.Pop();
+ }
+
+ var exportProviderFactory = configuration.CreateExportProviderFactory();
+ var exportProvider = exportProviderFactory.CreateExportProvider();
+
+ return exportProvider;
}
private static IEnumerable LoadMefComponents(ExtensionManager extensionManager)
diff --git a/src/AvalonStudio.Shell/Shell.cs b/src/AvalonStudio.Shell/Shell.cs
index c4eb2fd..bf6005e 100644
--- a/src/AvalonStudio.Shell/Shell.cs
+++ b/src/AvalonStudio.Shell/Shell.cs
@@ -17,7 +17,8 @@ public static class Shell
Platform.Initialise();
var extensionManager = new ExtensionManager();
- var container = CompositionRoot.CreateContainer(extensionManager);
+ // we shouldn't do this, instead a progress dialog should be shown
+ var container = CompositionRoot.CreateExportProviderAsync(extensionManager).Result;
IoC.Initialise(container);
diff --git a/src/Packages.targets b/src/Packages.targets
index df65112..7586e41 100644
--- a/src/Packages.targets
+++ b/src/Packages.targets
@@ -7,6 +7,7 @@
+
diff --git a/src/Versions.props b/src/Versions.props
index 1fde0d5..7745069 100644
--- a/src/Versions.props
+++ b/src/Versions.props
@@ -3,6 +3,7 @@
0.6.2-build536
0.6.2-build5984-beta
+ 15.8.98
10.0.3
8.0.1