diff --git a/samples/Shared/IOperator.cs b/samples/Shared/IOperator.cs
new file mode 100644
index 0000000..06bcfd9
--- /dev/null
+++ b/samples/Shared/IOperator.cs
@@ -0,0 +1,7 @@
+namespace Shared
+{
+    public interface IOperator
+    {
+        int Calculate(int x, int y);
+    }
+}
diff --git a/samples/Shared/IPlugin.cs b/samples/Shared/IPlugin.cs
index d52e839..20f74d0 100644
--- a/samples/Shared/IPlugin.cs
+++ b/samples/Shared/IPlugin.cs
@@ -11,9 +11,4 @@ public interface IOutPlugin
     {
         string Get();
     }
-
-    public interface IOperator
-    {
-        int Calculate(int x, int y);
-    }
 }
diff --git a/samples/Shared/RemainderOperator.cs b/samples/Shared/RemainderOperator.cs
new file mode 100644
index 0000000..e8612b7
--- /dev/null
+++ b/samples/Shared/RemainderOperator.cs
@@ -0,0 +1,10 @@
+namespace Shared
+{
+    public class RemainderOperator : IOperator
+    {
+        public int Calculate(int x, int y)
+        {
+            return x % y;
+        }
+    }
+}
diff --git a/samples/SharedPlugins/MultiplyOperator.cs b/samples/SharedPlugins/MultiplyOperator.cs
index 629f815..bbbe87c 100644
--- a/samples/SharedPlugins/MultiplyOperator.cs
+++ b/samples/SharedPlugins/MultiplyOperator.cs
@@ -1,7 +1,9 @@
-using Shared;
+using System.ComponentModel;
+using Shared;
 
 namespace SharedPlugins
 {
+    [DisplayName("The multiplier plugin")]
     public class MultiplyOperator : IOperator
     {
         public int Calculate(int x, int y)
@@ -9,4 +11,4 @@ public int Calculate(int x, int y)
             return x * y;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/samples/WebApp/Controllers/CalculatorController.cs b/samples/WebApp/Controllers/CalculatorController.cs
new file mode 100644
index 0000000..dfc7d3d
--- /dev/null
+++ b/samples/WebApp/Controllers/CalculatorController.cs
@@ -0,0 +1,29 @@
+using System.Collections.Generic;
+using Microsoft.AspNetCore.Mvc;
+using Shared;
+using Weikio.PluginFramework.Abstractions;
+
+namespace WebApp.Controllers
+{
+    [ApiController]
+    [Route("[controller]")]
+    public class CalculatorController : ControllerBase
+    {
+        private readonly IEnumerable<IOperator> _operators;
+        private readonly IEnumerable<Plugin> _plugins;
+
+        public CalculatorController(IEnumerable<IOperator> operators, IEnumerable<Plugin> plugins, IOperator myOperator)
+        {
+            _operators = operators;
+            _plugins = plugins;
+        }
+        
+        [HttpGet]
+        public string Get()
+        {
+            var pluginsList = string.Join(", ", _plugins);
+
+            return pluginsList;
+        }
+    }
+}
diff --git a/samples/WebApp/Program.cs b/samples/WebApp/Program.cs
new file mode 100644
index 0000000..f9af38d
--- /dev/null
+++ b/samples/WebApp/Program.cs
@@ -0,0 +1,21 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
+
+namespace WebApp
+{
+    public class Program
+    {
+        public static void Main(string[] args)
+        {
+            CreateHostBuilder(args).Build().Run();
+        }
+
+        public static IHostBuilder CreateHostBuilder(string[] args) =>
+            Host.CreateDefaultBuilder(args)
+                .ConfigureWebHostDefaults(webBuilder =>
+                {
+                    webBuilder.UseStartup<Startup>();
+                });
+    }
+}
diff --git a/samples/WebApp/Startup.cs b/samples/WebApp/Startup.cs
new file mode 100644
index 0000000..49ae288
--- /dev/null
+++ b/samples/WebApp/Startup.cs
@@ -0,0 +1,60 @@
+using System.Collections.Generic;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Shared;
+using Weikio.PluginFramework.Abstractions;
+using Weikio.PluginFramework.Catalogs;
+
+namespace WebApp
+{
+    public class Startup
+    {
+        public Startup(IConfiguration configuration)
+        {
+            Configuration = configuration;
+        }
+
+        public IConfiguration Configuration { get; }
+
+        // This method gets called by the runtime. Use this method to add services to the container.
+        public void ConfigureServices(IServiceCollection services)
+        {
+            var folderPluginCatalog = new FolderPluginCatalog(@"..\SharedPlugins\bin\debug\netcoreapp3.1", type =>
+            {
+                type.Implements<IOperator>();
+            });
+
+            services.AddPluginFramework()
+                .AddPluginCatalog(folderPluginCatalog)
+                .AddPluginType<IOperator>();
+
+            // Alternatively
+            // services.AddPluginFramework<IOperator>(@"..\SharedPlugins\bin\debug\netcoreapp3.1");
+
+            services.AddControllers();
+        }
+
+        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+        {
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+            }
+
+            app.UseHttpsRedirection();
+
+            app.UseRouting();
+
+            app.UseAuthorization();
+
+            app.UseEndpoints(endpoints =>
+            {
+                endpoints.MapControllers();
+            });
+        }
+    }
+}
diff --git a/samples/WebApp/WebApp.csproj b/samples/WebApp/WebApp.csproj
new file mode 100644
index 0000000..0130830
--- /dev/null
+++ b/samples/WebApp/WebApp.csproj
@@ -0,0 +1,16 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+    <PropertyGroup>
+        <TargetFramework>netcoreapp3.1</TargetFramework>
+    </PropertyGroup>
+
+    <ItemGroup>
+      <ProjectReference Include="..\..\src\Weikio.PluginFramework.Abstractions\Weikio.PluginFramework.Abstractions.csproj" />
+      <ProjectReference Include="..\..\src\Weikio.PluginFramework.AspNetCore\Weikio.PluginFramework.AspNetCore.csproj" />
+      <ProjectReference Include="..\..\src\Weikio.PluginFramework\Weikio.PluginFramework.csproj" />
+      <ProjectReference Include="..\SharedPlugins\SharedPlugins.csproj" />
+      <ProjectReference Include="..\Shared\Shared.csproj" />
+    </ItemGroup>
+
+
+</Project>
diff --git a/samples/WebApp/appsettings.Development.json b/samples/WebApp/appsettings.Development.json
new file mode 100644
index 0000000..8983e0f
--- /dev/null
+++ b/samples/WebApp/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft": "Warning",
+      "Microsoft.Hosting.Lifetime": "Information"
+    }
+  }
+}
diff --git a/samples/WebApp/appsettings.json b/samples/WebApp/appsettings.json
new file mode 100644
index 0000000..d9d9a9b
--- /dev/null
+++ b/samples/WebApp/appsettings.json
@@ -0,0 +1,10 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft": "Warning",
+      "Microsoft.Hosting.Lifetime": "Information"
+    }
+  },
+  "AllowedHosts": "*"
+}
diff --git a/samples/WpfApp/MainWindow.xaml.cs b/samples/WpfApp/MainWindow.xaml.cs
index b08af9f..0701575 100644
--- a/samples/WpfApp/MainWindow.xaml.cs
+++ b/samples/WpfApp/MainWindow.xaml.cs
@@ -22,9 +22,10 @@ private async void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
                 type.Implements<IOperator>();
             });
             
-            var assemblyPluginCatalog = new AssemblyPluginCatalog(typeof(MainWindow).Assembly);
+            var assemblyPluginCatalog = new AssemblyPluginCatalog(typeof(MainWindow).Assembly, type => typeof(IOperator).IsAssignableFrom(type));
+            var typePluginCatalog = new TypePluginCatalog(typeof(RemainderOperator));
             
-            var pluginCatalog = new CompositePluginCatalog(folderPluginCatalog, assemblyPluginCatalog); 
+            var pluginCatalog = new CompositePluginCatalog(folderPluginCatalog, assemblyPluginCatalog, typePluginCatalog); 
             await pluginCatalog.Initialize();
 
             var allPlugins = pluginCatalog.GetPlugins();
diff --git a/src/PluginFramework.sln b/src/PluginFramework.sln
index 6b82da4..78e15c1 100644
--- a/src/PluginFramework.sln
+++ b/src/PluginFramework.sln
@@ -32,6 +32,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfApp", "..\samples\WpfApp
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedPlugins", "..\samples\SharedPlugins\SharedPlugins.csproj", "{6E19B5B2-9106-4EB3-8B0E-1C735FB4C815}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApp", "..\samples\WebApp\WebApp.csproj", "{30C02979-E0C0-4AD0-B88F-23EF28807473}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Weikio.PluginFramework.AspNetCore", "Weikio.PluginFramework.AspNetCore\Weikio.PluginFramework.AspNetCore.csproj", "{E4F3E21D-653A-4AE7-B1DA-63B3F041367C}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -90,6 +94,18 @@ Global
 		{6E19B5B2-9106-4EB3-8B0E-1C735FB4C815}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{6E19B5B2-9106-4EB3-8B0E-1C735FB4C815}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{6E19B5B2-9106-4EB3-8B0E-1C735FB4C815}.Release|Any CPU.Build.0 = Release|Any CPU
+		{30C02979-E0C0-4AD0-B88F-23EF28807473}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{30C02979-E0C0-4AD0-B88F-23EF28807473}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{30C02979-E0C0-4AD0-B88F-23EF28807473}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{30C02979-E0C0-4AD0-B88F-23EF28807473}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7FAF2032-2445-42BF-BB0C-A2ECBAEAE56A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7FAF2032-2445-42BF-BB0C-A2ECBAEAE56A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7FAF2032-2445-42BF-BB0C-A2ECBAEAE56A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7FAF2032-2445-42BF-BB0C-A2ECBAEAE56A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E4F3E21D-653A-4AE7-B1DA-63B3F041367C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E4F3E21D-653A-4AE7-B1DA-63B3F041367C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E4F3E21D-653A-4AE7-B1DA-63B3F041367C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E4F3E21D-653A-4AE7-B1DA-63B3F041367C}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(NestedProjects) = preSolution
 		{6CDBFF3C-932B-4A66-8779-B5C72B33AF7F} = {DE041517-4760-4748-97F6-DB71D6AFFF5B}
@@ -104,5 +120,6 @@ Global
 		{DBC0AD60-7261-4CEB-BE4F-3AD12C39F813} = {FF3A507D-D242-44F6-8940-49E0B51B6F02}
 		{91A58039-85B5-4B2C-8F25-10DD6033F3AA} = {FF3A507D-D242-44F6-8940-49E0B51B6F02}
 		{6E19B5B2-9106-4EB3-8B0E-1C735FB4C815} = {FF3A507D-D242-44F6-8940-49E0B51B6F02}
+		{30C02979-E0C0-4AD0-B88F-23EF28807473} = {FF3A507D-D242-44F6-8940-49E0B51B6F02}
 	EndGlobalSection
 EndGlobal
diff --git a/src/Weikio.PluginFramework.Abstractions/IPluginCatalog.cs b/src/Weikio.PluginFramework.Abstractions/IPluginCatalog.cs
index 3f7dd4d..167d368 100644
--- a/src/Weikio.PluginFramework.Abstractions/IPluginCatalog.cs
+++ b/src/Weikio.PluginFramework.Abstractions/IPluginCatalog.cs
@@ -7,15 +7,26 @@ namespace Weikio.PluginFramework.Abstractions
 {
     public interface IPluginCatalog
     {
+        /// <summary>
+        /// Initializes the catalog
+        /// </summary>
         Task Initialize();
+        
+        /// <summary>
+        /// Gets if the catalog is initialized
+        /// </summary>
         bool IsInitialized { get; }
-        Task<List<PluginOld>> GetPluginsOld();
-        Task<PluginOld> GetPlugin(string name, Version version);
-        Task<Assembly> GetAssembly(PluginOld definition);
-        bool SupportsUnload { get; }
-        Task Unload();
-        bool Unloaded { get; }
+        
+        /// <summary>
+        /// Gets all the plugins
+        /// </summary>
+        /// <returns>List of <see cref="Plugin"/></returns>
         List<Plugin> GetPlugins();
+        
+        /// <summary>
+        /// Gets a single plugin based on its name and version
+        /// </summary>
+        /// <returns>The <see cref="Plugin"/></returns>
         Plugin Get(string name, Version version);
     }
 }
diff --git a/src/Weikio.PluginFramework.Abstractions/PluginDefinition.cs b/src/Weikio.PluginFramework.Abstractions/PluginDefinition.cs
index 5f7e9d2..9c1c455 100644
--- a/src/Weikio.PluginFramework.Abstractions/PluginDefinition.cs
+++ b/src/Weikio.PluginFramework.Abstractions/PluginDefinition.cs
@@ -32,16 +32,16 @@ public override string ToString()
         //     return await GetPlugins(new Dictionary<string, Predicate<Type>>());
         // }
 
-        public async Task<List<Type>> GetTypes()
-        {
-            return await GetTypes(new Dictionary<string, Predicate<Type>>());
-        }
-
-        public async Task<List<Type>> GetTypes(Predicate<Type> filter)
-        {
-            var taggedFilters = new Dictionary<string, Predicate<Type>>() { { string.Empty, filter } };
-            return await GetTypes(taggedFilters);
-        }
+        // public async Task<List<Type>> GetTypes()
+        // {
+        //     return await GetTypes(new Dictionary<string, Predicate<Type>>());
+        // }
+        //
+        // public async Task<List<Type>> GetTypes(Predicate<Type> filter)
+        // {
+        //     var taggedFilters = new Dictionary<string, Predicate<Type>>() { { string.Empty, filter } };
+        //     return await GetTypes(taggedFilters);
+        // }
         
         // public async Task<Plugin> GetPlugins(Predicate<Type> filter)
         // {
@@ -79,31 +79,31 @@ public async Task<List<Type>> GetTypes(Predicate<Type> filter)
         //     return result;
         // }
         
-        public async Task<List<Type>> GetTypes(Dictionary<string, Predicate<Type>> taggedFilters)
-        {
-            var assembly = await Source.GetAssembly(this);
-
-            if (assembly == null)
-            {
-                throw new ArgumentException();
-            }
-
-            var allTypes = assembly.GetExportedTypes();
-            var taggedTypes = new List<(string Tag, Type Type)>();
-
-            if (taggedFilters?.Any() == true)
-            {
-                foreach (var taggedFilter in taggedFilters)
-                {
-                    taggedTypes.AddRange(allTypes.Where(x => taggedFilter.Value(x)).Select(x => (taggedFilter.Key, x)));
-                }
-            }
-            else
-            {
-                taggedTypes.AddRange(allTypes.Select(x => (string.Empty, x)));
-            }
-            
-            return taggedTypes.Select(x => x.Type).ToList();
-        }
+        // public async Task<List<Type>> GetTypes(Dictionary<string, Predicate<Type>> taggedFilters)
+        // {
+        //     var assembly = await Source.GetAssembly(this);
+        //
+        //     if (assembly == null)
+        //     {
+        //         throw new ArgumentException();
+        //     }
+        //
+        //     var allTypes = assembly.GetExportedTypes();
+        //     var taggedTypes = new List<(string Tag, Type Type)>();
+        //
+        //     if (taggedFilters?.Any() == true)
+        //     {
+        //         foreach (var taggedFilter in taggedFilters)
+        //         {
+        //             taggedTypes.AddRange(allTypes.Where(x => taggedFilter.Value(x)).Select(x => (taggedFilter.Key, x)));
+        //         }
+        //     }
+        //     else
+        //     {
+        //         taggedTypes.AddRange(allTypes.Select(x => (string.Empty, x)));
+        //     }
+        //     
+        //     return taggedTypes.Select(x => x.Type).ToList();
+        // }
     }
 }
diff --git a/src/Weikio.PluginFramework.AspNetCore/PluginExtensions.cs b/src/Weikio.PluginFramework.AspNetCore/PluginExtensions.cs
new file mode 100644
index 0000000..5f6a61e
--- /dev/null
+++ b/src/Weikio.PluginFramework.AspNetCore/PluginExtensions.cs
@@ -0,0 +1,14 @@
+using System;
+using Weikio.PluginFramework.Abstractions;
+
+// ReSharper disable once CheckNamespace
+namespace Microsoft.Extensions.DependencyInjection
+{
+    public static class PluginExtensions
+    {
+        public static T Create<T>(this Plugin plugin, IServiceProvider serviceProvider) where T : class
+        {
+            return ActivatorUtilities.CreateInstance(serviceProvider, plugin) as T;
+        }
+    }
+}
diff --git a/src/Weikio.PluginFramework.AspNetCore/PluginFrameworkInitializer.cs b/src/Weikio.PluginFramework.AspNetCore/PluginFrameworkInitializer.cs
new file mode 100644
index 0000000..42819e5
--- /dev/null
+++ b/src/Weikio.PluginFramework.AspNetCore/PluginFrameworkInitializer.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Weikio.PluginFramework.Abstractions;
+
+namespace Weikio.PluginFramework.AspNetCore
+{
+    public class PluginFrameworkInitializer : BackgroundService
+    {
+        private readonly IEnumerable<IPluginCatalog> _pluginCatalogs;
+        private readonly ILogger<PluginFrameworkInitializer> _logger;
+
+        public PluginFrameworkInitializer(IEnumerable<IPluginCatalog> pluginCatalogs, ILogger<PluginFrameworkInitializer> logger)
+        {
+            _pluginCatalogs = pluginCatalogs;
+            _logger = logger;
+        }
+
+        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
+        {
+            try
+            {
+                _logger.LogInformation("Initializing {PluginCatalogCount} plugin catalogs", _pluginCatalogs.Count());
+
+                foreach (var pluginCatalog in _pluginCatalogs)
+                {
+                    try
+                    {
+                        _logger.LogDebug("Initializing {PluginCatalog}", pluginCatalog);
+
+                        await pluginCatalog.Initialize();
+
+                        _logger.LogDebug("Initialized {PluginCatalog}", pluginCatalog);
+                        _logger.LogTrace("Found the following plugins from {PluginCatalog}:", pluginCatalog);
+
+                        foreach (var plugin in pluginCatalog.GetPlugins())
+                        {
+                            _logger.LogTrace(plugin.ToString());
+                        }
+                    }
+                    catch (Exception e)
+                    {
+                        _logger.LogError(e, "Failed to initialize {PluginCatalog}", pluginCatalog);
+                    }
+                }
+
+                _logger.LogInformation("Initialized {PluginCatalogCount} plugin catalogs", _pluginCatalogs.Count());
+            }
+            catch (Exception e)
+            {
+                _logger.LogError(e, "Failed to initialize plugin catalogs");
+
+                throw;
+            }
+        }
+    }
+}
diff --git a/src/Weikio.PluginFramework.AspNetCore/ServiceCollectionExtensions.cs b/src/Weikio.PluginFramework.AspNetCore/ServiceCollectionExtensions.cs
new file mode 100644
index 0000000..152e140
--- /dev/null
+++ b/src/Weikio.PluginFramework.AspNetCore/ServiceCollectionExtensions.cs
@@ -0,0 +1,115 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Weikio.PluginFramework.Abstractions;
+using Weikio.PluginFramework.AspNetCore;
+using Weikio.PluginFramework.Catalogs;
+
+// ReSharper disable once CheckNamespace
+namespace Microsoft.Extensions.DependencyInjection
+{
+    public static class ServiceCollectionExtensions
+    {
+        public static IServiceCollection AddPluginFramework(this IServiceCollection services, Action<TypeFinderCriteriaBuilder> configureTypeFinder = null, string folderPath = "")
+        {
+            services.AddHostedService<PluginFrameworkInitializer>();
+
+            services.AddSingleton(sp =>
+            {
+                var result = new List<Plugin>();
+                var catalogs = sp.GetServices<IPluginCatalog>();
+
+                foreach (var catalog in catalogs)
+                {
+                    var plugins = catalog.GetPlugins();
+
+                    result.AddRange(plugins);
+                }
+
+                return result.AsEnumerable();
+            });
+
+            if (configureTypeFinder == null)
+            {
+                return services;
+            }
+            
+            
+            
+            return services;
+        }
+        
+        public static IServiceCollection AddPluginFramework<TType>(this IServiceCollection services, string dllPath = "") where TType : class
+        {
+            services.AddPluginFramework();
+
+            if (string.IsNullOrWhiteSpace(dllPath))
+            {
+                dllPath = Environment.CurrentDirectory;
+            }
+
+            var typeFinderCriteria = TypeFinderCriteriaBuilder.Create()
+                .AssignableTo(typeof(TType))
+                .Build();
+
+            var catalog = new FolderPluginCatalog(dllPath, typeFinderCriteria);
+            services.AddPluginCatalog(catalog);
+
+            services.AddPluginType<TType>();
+            
+            return services;
+        }
+
+        public static IServiceCollection AddPluginCatalog(this IServiceCollection services, IPluginCatalog pluginCatalog)
+        {
+            services.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IPluginCatalog), pluginCatalog));
+
+            return services;
+        }
+
+        public static IServiceCollection AddPluginType<T>(this IServiceCollection services, ServiceLifetime serviceLifetime = ServiceLifetime.Transient) where T : class
+        {
+            var serviceDescriptorEnumerable = new ServiceDescriptor(typeof(IEnumerable<T>), sp =>
+            {
+                var result = GetTypes<T>(sp);
+
+                return result.AsEnumerable();
+                
+            }, serviceLifetime);
+            
+            var serviceDescriptorSingle = new ServiceDescriptor(typeof(T), sp =>
+            {
+                var result = GetTypes<T>(sp);
+
+                return result.FirstOrDefault();
+                
+            }, serviceLifetime);
+
+            services.Add(serviceDescriptorEnumerable);
+            services.Add(serviceDescriptorSingle);
+
+            return services;
+        }
+
+        private static List<T> GetTypes<T>(IServiceProvider sp) where T : class
+        {
+            var result = new List<T>();
+            var catalogs = sp.GetServices<IPluginCatalog>();
+
+            foreach (var catalog in catalogs)
+            {
+                var plugins = catalog.GetPlugins();
+
+                foreach (var plugin in plugins.Where(x => typeof(T).IsAssignableFrom(x)))
+                {
+                    var op = plugin.Create<T>(sp);
+
+                    result.Add(op);
+                }
+            }
+
+            return result;
+        }
+    }
+}
diff --git a/src/Weikio.PluginFramework.AspNetCore/ServiceProviderExtensions.cs b/src/Weikio.PluginFramework.AspNetCore/ServiceProviderExtensions.cs
new file mode 100644
index 0000000..f6314ce
--- /dev/null
+++ b/src/Weikio.PluginFramework.AspNetCore/ServiceProviderExtensions.cs
@@ -0,0 +1,14 @@
+using System;
+using Weikio.PluginFramework.Abstractions;
+
+// ReSharper disable once CheckNamespace
+namespace Microsoft.Extensions.DependencyInjection
+{
+    public static class ServiceProviderExtensions
+    {
+        public static T Create<T>(this IServiceProvider serviceProvider, Plugin plugin) where T : class
+        {
+            return ActivatorUtilities.CreateInstance(serviceProvider, plugin) as T;
+        }
+    }
+}
diff --git a/src/Weikio.PluginFramework.AspNetCore/Weikio.PluginFramework.AspNetCore.csproj b/src/Weikio.PluginFramework.AspNetCore/Weikio.PluginFramework.AspNetCore.csproj
new file mode 100644
index 0000000..ddb0f06
--- /dev/null
+++ b/src/Weikio.PluginFramework.AspNetCore/Weikio.PluginFramework.AspNetCore.csproj
@@ -0,0 +1,41 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <IsPackable>true</IsPackable>
+    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
+    <Authors>Weik.io</Authors>
+    <Company>Weik.io</Company>
+    <Description>Plugin Framework for ASP.NET Core.</Description>
+    <PackageDescription>Plugin Framework for ASP.NET Core.</PackageDescription>
+    <PackageProjectUrl>https://www.pluginframework.com</PackageProjectUrl>
+    <Copyright>©2020 Weik.io</Copyright>
+    <PackageId>Weikio.PluginFramework.AspNetCore</PackageId>
+    <Product>Weikio.PluginFramework.AspNetCore</Product>
+    <AssemblyName>Weikio.PluginFramework.AspNetCore</AssemblyName>
+    <PackageLicenseExpression>MIT</PackageLicenseExpression>
+    <RepositoryUrl>https://github.com/weikio/PluginFramework</RepositoryUrl>
+    <PackageTags>plugins;addons;aspnetextensions;plugin framework</PackageTags>
+    <PackageIcon>logo_256.png</PackageIcon>
+    <Title>Plugin Framework for ASP.NET Core</Title>
+    <MinVerMinimumMajorMinor>1.0</MinVerMinimumMajorMinor>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <FrameworkReference Include="Microsoft.AspNetCore.App" />
+  </ItemGroup>
+  
+  <ItemGroup>
+    <None Include="../../docs/logo_256.png" Pack="true" Visible="false" PackagePath="" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="MinVer" Version="2.0.0" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Weikio.PluginFramework.Abstractions\Weikio.PluginFramework.Abstractions.csproj" />
+    <ProjectReference Include="..\Weikio.PluginFramework\Weikio.PluginFramework.csproj" />
+  </ItemGroup>
+  
+</Project>
\ No newline at end of file
diff --git a/src/Weikio.PluginFramework/Catalogs/AssemblyPluginCatalog.cs b/src/Weikio.PluginFramework/Catalogs/AssemblyPluginCatalog.cs
index e2203f1..0fe7e96 100644
--- a/src/Weikio.PluginFramework/Catalogs/AssemblyPluginCatalog.cs
+++ b/src/Weikio.PluginFramework/Catalogs/AssemblyPluginCatalog.cs
@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.Diagnostics;
 using System.IO;
 using System.Linq;
 using System.Reflection;
@@ -14,9 +13,36 @@ public class AssemblyPluginCatalog : IPluginCatalog
     {
         private readonly string _assemblyPath;
         private Assembly _assembly;
-        private PluginOld _pluginOld;
         private readonly AssemblyPluginCatalogOptions _options;
         private PluginAssemblyLoadContext _pluginAssemblyLoadContext;
+        private List<TypePluginCatalog> _plugins = null;
+
+        // TODO: Remove the duplicate code from constructors
+        public AssemblyPluginCatalog(string assemblyPath) : this(assemblyPath, options: null)
+        {
+        }
+
+        public AssemblyPluginCatalog(Assembly assembly) : this(assembly, options: null)
+        {
+        }
+
+        public AssemblyPluginCatalog(string assemblyPath, AssemblyPluginCatalogOptions options = null)
+        {
+            if (string.IsNullOrWhiteSpace(assemblyPath))
+            {
+                throw new ArgumentNullException(nameof(assemblyPath));
+            }
+
+            _assemblyPath = assemblyPath;
+            _options = options ?? new AssemblyPluginCatalogOptions();
+        }
+
+        public AssemblyPluginCatalog(Assembly assembly, AssemblyPluginCatalogOptions options = null)
+        {
+            _assembly = assembly;
+            _assemblyPath = _assembly.Location;
+            _options = options ?? new AssemblyPluginCatalogOptions();
+        }
 
         public AssemblyPluginCatalog(string assemblyPath, TypeFinderCriteria criteria = null, AssemblyPluginCatalogOptions options = null)
         {
@@ -33,6 +59,27 @@ public AssemblyPluginCatalog(string assemblyPath, TypeFinderCriteria criteria =
                 _options.TypeFinderCriterias.Add(string.Empty, criteria);
             }
         }
+        
+        public AssemblyPluginCatalog(string assemblyPath, Action<TypeFinderCriteriaBuilder> configureFinder = null, AssemblyPluginCatalogOptions options = null)
+        {
+            if (string.IsNullOrWhiteSpace(assemblyPath))
+            {
+                throw new ArgumentNullException(nameof(assemblyPath));
+            }
+
+            _assemblyPath = assemblyPath;
+            _options = options ?? new AssemblyPluginCatalogOptions();
+
+            if (configureFinder != null)
+            {
+                var builder = new TypeFinderCriteriaBuilder();
+                configureFinder(builder);
+
+                var criteria = builder.Build();
+
+                _options.TypeFinderCriterias.Add("", criteria);
+            }
+        }
 
         public AssemblyPluginCatalog(string assemblyPath, Predicate<Type> filter = null, AssemblyPluginCatalogOptions options = null)
         {
@@ -46,9 +93,7 @@ public AssemblyPluginCatalog(string assemblyPath, Predicate<Type> filter = null,
 
             if (filter != null)
             {
-                var criteria = new TypeFinderCriteria();
-
-                criteria.Query = (context, type) => filter(type);
+                var criteria = new TypeFinderCriteria { Query = (context, type) => filter(type) };
 
                 _options.TypeFinderCriterias.Add(string.Empty, criteria);
             }
@@ -62,9 +107,7 @@ public AssemblyPluginCatalog(Assembly assembly, Predicate<Type> filter = null, A
 
             if (filter != null)
             {
-                var criteria = new TypeFinderCriteria();
-
-                criteria.Query = (context, type) => filter(type);
+                var criteria = new TypeFinderCriteria { Query = (context, type) => filter(type) };
 
                 _options.TypeFinderCriterias.Add(string.Empty, criteria);
             }
@@ -80,12 +123,7 @@ public AssemblyPluginCatalog(string assemblyPath, Dictionary<string, Predicate<T
             _assemblyPath = assemblyPath;
             _options = options ?? new AssemblyPluginCatalogOptions();
 
-            foreach (var taggedFilter in taggedFilters)
-            {
-                var criteria = new TypeFinderCriteria { Query = (context, type) => taggedFilter.Value(type) };
-
-                _options.TypeFinderCriterias.Add(taggedFilter.Key, criteria);
-            }
+            SetFilters(taggedFilters);
         }
 
         public AssemblyPluginCatalog(Assembly assembly, Dictionary<string, Predicate<Type>> taggedFilters, AssemblyPluginCatalogOptions options = null)
@@ -94,6 +132,11 @@ public AssemblyPluginCatalog(Assembly assembly, Dictionary<string, Predicate<Typ
             _assemblyPath = _assembly.Location;
             _options = options ?? new AssemblyPluginCatalogOptions();
 
+            SetFilters(taggedFilters);
+        }
+
+        private void SetFilters(Dictionary<string, Predicate<Type>> taggedFilters)
+        {
             foreach (var taggedFilter in taggedFilters)
             {
                 var criteria = new TypeFinderCriteria { Query = (context, type) => taggedFilter.Value(type) };
@@ -102,7 +145,7 @@ public AssemblyPluginCatalog(Assembly assembly, Dictionary<string, Predicate<Typ
             }
         }
 
-        public Task Initialize()
+        public async Task Initialize()
         {
             if (!string.IsNullOrWhiteSpace(_assemblyPath) && _assembly == null)
             {
@@ -115,138 +158,63 @@ public Task Initialize()
                 _assembly = _pluginAssemblyLoadContext.Load();
             }
 
-            _pluginOld = AssemblyToPluginDefinitionConverter.Convert(_assembly, this);
-
-            IsInitialized = true;
-
-            return Task.CompletedTask;
-        }
-
-        public bool IsInitialized { get; private set; }
-
-        public Task<List<PluginOld>> GetPluginsOld()
-        {
-            if (Unloaded)
-            {
-                throw new CatalogUnloadedException();
-            }
-
-            var result = new List<PluginOld>() { _pluginOld };
+            _plugins = new List<TypePluginCatalog>();
 
-            return Task.FromResult(result);
-        }
+            var finder = new TypeFinder();
 
-        public Task<PluginOld> GetPlugin()
-        {
-            if (Unloaded)
+            if (_options.TypeFinderCriterias?.Any() != true)
             {
-                throw new CatalogUnloadedException();
-            }
-
-            return Task.FromResult(_pluginOld);
-        }
+                var findAll = new TypeFinderCriteria()
+                {
+                    Query = (context, type) => true
+                };
 
-        public Task<PluginOld> GetPlugin(string name, Version version)
-        {
-            if (Unloaded)
-            {
-                throw new CatalogUnloadedException();
+                if (_options.TypeFinderCriterias == null)
+                {
+                    _options.TypeFinderCriterias = new Dictionary<string, TypeFinderCriteria>();
+                }
+                
+                _options.TypeFinderCriterias.Add(string.Empty, findAll);
             }
 
-            if (!string.Equals(name, _pluginOld.Name, StringComparison.InvariantCultureIgnoreCase) ||
-                version != _pluginOld.Version)
+            foreach (var typeFinderCriteria in _options.TypeFinderCriterias)
             {
-                return Task.FromResult<PluginOld>(null);
-            }
-
-            return Task.FromResult(_pluginOld);
-        }
-
-        public Task<Assembly> GetAssembly(PluginOld definition)
-        {
-            return Task.FromResult(_assembly);
-        }
+                var pluginTypes = finder.Find(typeFinderCriteria.Value, _assembly, _pluginAssemblyLoadContext);
 
-        public bool SupportsUnload { get; } = true;
+                foreach (var type in pluginTypes)
+                {
+                    var typePluginCatalog = new TypePluginCatalog(type, new TypePluginCatalogOptions() { PluginNameOptions = _options.PluginNameOptions });
+                    await typePluginCatalog.Initialize();
 
-        public Task Unload()
-        {
-            if (Unloaded)
-            {
-                return Task.CompletedTask;
+                    _plugins.Add(typePluginCatalog);
+                }
             }
 
-            _pluginAssemblyLoadContext.Unload();
-
-            Unloaded = true;
-
-            return Task.CompletedTask;
+            IsInitialized = true;
         }
 
-        public bool Unloaded { get; private set; }
+        public bool IsInitialized { get; private set; }
 
         public List<Plugin> GetPlugins()
         {
-            var finder = new TypeFinder();
+            return _plugins.SelectMany(x => x.GetPlugins()).ToList();
+        }
 
-            var result = new List<Plugin>();
-            
-            foreach (var typeFinderCriteria in _options.TypeFinderCriterias)
+        public Plugin Get(string name, Version version)
+        {
+            foreach (var pluginCatalog in _plugins)
             {
-                var pluginTypes = finder.Find(typeFinderCriteria.Value, _assembly, _pluginAssemblyLoadContext);
+                var foundPlugin = pluginCatalog.Get(name, version);
 
-                foreach (var type in pluginTypes)
+                if (foundPlugin == null)
                 {
-                    var opt = new TypePluginCatalogOptions();
-                    var version = opt.PluginVersionGenerator(opt, type);
-                    var pluginName = opt.PluginNameGenerator(opt, type);
-                    var description = opt.PluginDescriptionGenerator(opt, type);
-                    var productVersion = opt.PluginProductVersionGenerator(opt, type);
-
-                    var plugin = new Plugin(type.Assembly, type, pluginName, version, this, description, productVersion);
-                    result.Add(plugin);
+                    continue;
                 }
-            }
 
-            return result;
-
-            //
-            // var allTypes = assembly.GetExportedTypes();
-            // var taggedTypes = new List<(string Tag, Type Type)>();
-            //
-            // if (_filters?.Any() == true)
-            // {
-            //     foreach (var taggedFilter in _filters)
-            //     {
-            //         taggedTypes.AddRange(allTypes.Where(x => taggedFilter.Value(x)).Select(x => (taggedFilter.Key, x)));
-            //     }
-            // }
-            // else
-            // {
-            //     taggedTypes.AddRange(allTypes.Select(x => (string.Empty, x)));
-            // }
-            //
-            // var result = new List<Plugin>();
-            //
-            // foreach (var taggedType in taggedTypes)
-            // {
-            //     var versionInfo = FileVersionInfo.GetVersionInfo(assembly.Location);
-            //     var pluginName = taggedType.Type.FullName;
-            //     var fileVersion = Version.Parse(versionInfo.FileVersion);
-            //     var description = versionInfo.Comments;
-            //     var productVersion = versionInfo.ProductVersion;
-            //
-            //     var p = new Plugin(_assembly, taggedType.Type, pluginName, fileVersion, this, description, productVersion, taggedType.Tag);
-            //
-            //     result.Add(p);
-            // }
-            //
-            // return result;
-        }
+                return foundPlugin;
+            }
 
-        public Plugin Get(string name, Version version)
-        {
-            throw new NotImplementedException();
+            return null;
         }
     }
 }
diff --git a/src/Weikio.PluginFramework/Catalogs/AssemblyPluginCatalogOptions.cs b/src/Weikio.PluginFramework/Catalogs/AssemblyPluginCatalogOptions.cs
index 2532f6c..fa0f1c8 100644
--- a/src/Weikio.PluginFramework/Catalogs/AssemblyPluginCatalogOptions.cs
+++ b/src/Weikio.PluginFramework/Catalogs/AssemblyPluginCatalogOptions.cs
@@ -7,5 +7,6 @@ public class AssemblyPluginCatalogOptions
     {
         public PluginLoadContextOptions PluginLoadContextOptions = new PluginLoadContextOptions();
         public Dictionary<string, TypeFinderCriteria> TypeFinderCriterias = new Dictionary<string, TypeFinderCriteria>();
+        public PluginNameOptions PluginNameOptions { get; set; } = new PluginNameOptions();
     }
 }
diff --git a/src/Weikio.PluginFramework/Catalogs/CompositePluginCatalog.cs b/src/Weikio.PluginFramework/Catalogs/CompositePluginCatalog.cs
index 21c6418..24fc4f1 100644
--- a/src/Weikio.PluginFramework/Catalogs/CompositePluginCatalog.cs
+++ b/src/Weikio.PluginFramework/Catalogs/CompositePluginCatalog.cs
@@ -12,59 +12,34 @@ public class CompositePluginCatalog : IPluginCatalog
         private readonly List<IPluginCatalog> _catalogs;
         public bool IsInitialized { get; private set; }
 
-        public async Task<List<PluginOld>> GetPluginsOld()
+        public List<Plugin> GetPlugins()
         {
-            var result = new List<PluginOld>();
+            var result = new List<Plugin>();
 
             foreach (var pluginCatalog in _catalogs)
             {
-                var pluginsInCatalog = await pluginCatalog.GetPluginsOld();
+                var pluginsInCatalog = pluginCatalog.GetPlugins();
                 result.AddRange(pluginsInCatalog);
             }
 
             return result;
         }
 
-        public async Task<Assembly> GetAssembly(PluginOld definition)
+        public Plugin Get(string name, Version version)
         {
-            if (definition == null)
-            {
-                throw new ArgumentNullException(nameof(definition));
-            }
-
-            if (definition.Source == null)
+            foreach (var pluginCatalog in _catalogs)
             {
-                throw new ArgumentNullException(nameof(definition.Source));
-            }
-
-            var result = await definition.Source.GetAssembly(definition);
-
-            return result;
-        }
-
-        public bool SupportsUnload { get; }
-        public Task Unload()
-        {
-            throw new NotImplementedException();
-        }
+                var plugin = pluginCatalog.Get(name, version);
 
-        public bool Unloaded { get; }
-        public List<Plugin> GetPlugins()
-        {
-            var result = new List<Plugin>();
+                if (plugin == null)
+                {
+                    continue;
+                }
 
-            foreach (var pluginCatalog in _catalogs)
-            {
-                var pluginsInCatalog = pluginCatalog.GetPlugins();
-                result.AddRange(pluginsInCatalog);
+                return plugin;
             }
 
-            return result;
-        }
-
-        public Plugin Get(string name, Version version)
-        {
-            throw new NotImplementedException();
+            return null;
         }
 
         public CompositePluginCatalog(params IPluginCatalog[] catalogs)
@@ -77,27 +52,6 @@ public void AddCatalog(IPluginCatalog catalog)
             _catalogs.Add(catalog);
         }
 
-        public async Task<PluginOld> GetPlugin(string name, Version version)
-        {
-            PluginOld result = null;
-
-            foreach (var pluginCatalog in _catalogs)
-            {
-                var plugin = await pluginCatalog.GetPlugin(name, version);
-
-                if (plugin == null)
-                {
-                    continue;
-                }
-
-                result = plugin;
-
-                break;
-            }
-
-            return result;
-        }
-
         public async Task Initialize()
         {
             if (_catalogs?.Any() != true)
diff --git a/src/Weikio.PluginFramework/Catalogs/EmptyPluginCatalog.cs b/src/Weikio.PluginFramework/Catalogs/EmptyPluginCatalog.cs
index d5af37b..a23726f 100644
--- a/src/Weikio.PluginFramework/Catalogs/EmptyPluginCatalog.cs
+++ b/src/Weikio.PluginFramework/Catalogs/EmptyPluginCatalog.cs
@@ -15,36 +15,14 @@ public Task Initialize()
 
         public bool IsInitialized { get; } = true;
 
-        public Task<List<PluginOld>> GetPluginsOld()
-        {
-            return Task.FromResult(new List<PluginOld>());
-        }
-
-        public Task<PluginOld> GetPlugin(string name, Version version)
-        {
-            return null;
-        }
-
-        public Task<Assembly> GetAssembly(PluginOld definition)
-        {
-            return null;
-        }
-
-        public bool SupportsUnload { get; }
-        public Task Unload()
-        {
-            throw new NotImplementedException();
-        }
-
-        public bool Unloaded { get; }
         public List<Plugin> GetPlugins()
         {
-            throw new NotImplementedException();
+            return new List<Plugin>();
         }
 
         public Plugin Get(string name, Version version)
         {
-            throw new NotImplementedException();
+            return null;
         }
     }
 }
diff --git a/src/Weikio.PluginFramework/Catalogs/FolderPluginCatalog.cs b/src/Weikio.PluginFramework/Catalogs/FolderPluginCatalog.cs
index 0d096ee..0d86b7a 100644
--- a/src/Weikio.PluginFramework/Catalogs/FolderPluginCatalog.cs
+++ b/src/Weikio.PluginFramework/Catalogs/FolderPluginCatalog.cs
@@ -11,133 +11,99 @@
 using System.Threading.Tasks;
 using Weikio.PluginFramework.Abstractions;
 using Weikio.PluginFramework.Context;
-using AssemblyExtensions = System.Reflection.AssemblyExtensions;
 
 namespace Weikio.PluginFramework.Catalogs
 {
     public class FolderPluginCatalog : IPluginCatalog
     {
         private readonly string _folderPath;
-        private readonly List<(PluginOld PluginDefinition, Assembly Assembly)> _pluginsOld = new List<(PluginOld, Assembly)>();
-        private readonly List<Plugin> _plugins = new List<Plugin>();
         private readonly FolderPluginCatalogOptions _options;
         private readonly List<PluginAssemblyLoadContext> _contexts = new List<PluginAssemblyLoadContext>();
+        private readonly List<AssemblyPluginCatalog> _catalogs = new List<AssemblyPluginCatalog>();
 
         public bool IsInitialized { get; private set; }
 
-        public FolderPluginCatalog(string folderPath, TypeFinderCriteria finderCriteria = null, FolderPluginCatalogOptions options = null)
+        private List<Plugin> Plugins
         {
-            _folderPath = folderPath;
-            _options = options ?? new FolderPluginCatalogOptions();
-
-            if (finderCriteria != null)
+            get
             {
-                _options.TypeFinderCriterias.Add("", finderCriteria);
+                return _catalogs.SelectMany(x => x.GetPlugins()).ToList();
             }
         }
 
-        public FolderPluginCatalog(string folderPath, Action<TypeFinderCriteriaBuilder> configureFinder = null, FolderPluginCatalogOptions options = null)
+        public FolderPluginCatalog(string folderPath) : this(folderPath, new FolderPluginCatalogOptions())
         {
-            _folderPath = folderPath;
-            _options = options ?? new FolderPluginCatalogOptions();
-
-            if (configureFinder != null)
-            {
-                var builder = new TypeFinderCriteriaBuilder();
-                configureFinder(builder);
+        }
 
-                var criteria = builder.Build();
+        public FolderPluginCatalog(string folderPath, FolderPluginCatalogOptions options) : this(folderPath, null, null, options)
+        {
+        }
 
-                _options.TypeFinderCriterias.Add("", criteria);
-            }
+        public FolderPluginCatalog(string folderPath, Action<TypeFinderCriteriaBuilder> configureFinder) : this(folderPath, configureFinder, null, null)
+        {
         }
 
-        public Task<List<PluginOld>> GetPluginsOld()
+        public FolderPluginCatalog(string folderPath, TypeFinderCriteria finderCriteria) : this(folderPath, finderCriteria, null)
         {
-            if (Unloaded)
-            {
-                throw new CatalogUnloadedException();
-            }
+        }
 
-            return Task.FromResult(_pluginsOld.Select(x => x.PluginDefinition).ToList());
+        public FolderPluginCatalog(string folderPath, TypeFinderCriteria finderCriteria, FolderPluginCatalogOptions options) : this(folderPath, null, finderCriteria, options)
+        {
         }
 
-        public Task<PluginOld> GetPlugin(string name, Version version)
+        public FolderPluginCatalog(string folderPath, Action<TypeFinderCriteriaBuilder> configureFinder, FolderPluginCatalogOptions options) : this(folderPath, configureFinder, null, options)
         {
-            if (Unloaded)
-            {
-                throw new CatalogUnloadedException();
-            }
+        }
+        
+        public FolderPluginCatalog(string folderPath, Action<TypeFinderCriteriaBuilder> configureFinder, TypeFinderCriteria finderCriteria, FolderPluginCatalogOptions options)
+        {
+            _folderPath = folderPath;
+            _options = options ?? new FolderPluginCatalogOptions();
 
-            foreach (var plugin in _pluginsOld)
+            if (configureFinder != null)
             {
-                if (string.Equals(name, plugin.PluginDefinition.Name, StringComparison.InvariantCultureIgnoreCase) &&
-                    version == plugin.PluginDefinition.Version)
-                {
-                    return Task.FromResult(plugin.PluginDefinition);
-                }
-            }
+                var builder = new TypeFinderCriteriaBuilder();
+                configureFinder(builder);
 
-            return null;
-        }
+                var criteria = builder.Build();
 
-        public Task<Assembly> GetAssembly(PluginOld definition)
-        {
-            foreach (var plugin in _pluginsOld)
+                _options.TypeFinderCriterias.Add("", criteria);
+            }
+            
+            if (finderCriteria != null)
             {
-                if (string.Equals(definition.Name, plugin.PluginDefinition.Name, StringComparison.InvariantCultureIgnoreCase) &&
-                    definition.Version == plugin.PluginDefinition.Version)
-                {
-                    return Task.FromResult(plugin.Assembly);
-                }
+                _options.TypeFinderCriterias.Add("", finderCriteria);
             }
 
-            return null;
-        }
-
-        public bool SupportsUnload { get; } = true;
-
-        public Task Unload()
-        {
-            foreach (var pluginLoadContext in _contexts)
+            if (_options.TypeFinderCriteria != null)
             {
-                pluginLoadContext.Unload();
+                _options.TypeFinderCriterias.Add("", _options.TypeFinderCriteria);
             }
-
-            _contexts.Clear();
-
-            Unloaded = true;
-
-            return Task.CompletedTask;
         }
 
-        public bool Unloaded { get; private set; }
-
         public List<Plugin> GetPlugins()
         {
-            return _plugins;
+            return Plugins;
         }
 
         public Plugin Get(string name, Version version)
         {
-            if (Unloaded)
+            foreach (var assemblyPluginCatalog in _catalogs)
             {
-                throw new CatalogUnloadedException();
-            }
+                var plugin = assemblyPluginCatalog.Get(name, version);
 
-            foreach (var plugin in _plugins)
-            {
-                if (string.Equals(name, plugin.Name, StringComparison.InvariantCultureIgnoreCase) &&
-                    version == plugin.Version)
+                if (plugin == null)
                 {
-                    return plugin;
+                    continue;
                 }
+
+                return plugin;
             }
 
             return null;
         }
 
-        public Task Initialize()
+        public async Task Initialize()
         {
             var foundFiles = new List<string>();
 
@@ -160,34 +126,20 @@ public Task Initialize()
                     continue;
                 }
 
-                var loadContext = new PluginAssemblyLoadContext(assemblyPath, _options.PluginLoadContextOptions);
-                var assembly = loadContext.Load();
-                _contexts.Add(loadContext);
-
-                var finder = new TypeFinder();
-
-                foreach (var typeFinderCriteria in _options.TypeFinderCriterias)
+                var assemblyCatalogOptions = new AssemblyPluginCatalogOptions
                 {
+                    PluginLoadContextOptions = _options.PluginLoadContextOptions,
+                    TypeFinderCriterias = _options.TypeFinderCriterias,
+                    PluginNameOptions = _options.PluginNameOptions
+                };
 
-                    var pluginTypes = finder.Find(typeFinderCriteria.Value, assembly, loadContext);
+                var assemblyCatalog = new AssemblyPluginCatalog(assemblyPath, assemblyCatalogOptions);
+                await assemblyCatalog.Initialize();
 
-                    foreach (var type in pluginTypes)
-                    {
-                        var opt = new TypePluginCatalogOptions();
-                        var version = opt.PluginVersionGenerator(opt, type);
-                        var pluginName = opt.PluginNameGenerator(opt, type);
-                        var description = opt.PluginDescriptionGenerator(opt, type);
-                        var productVersion = opt.PluginProductVersionGenerator(opt, type);
-
-                        var plugin = new Plugin(type.Assembly, type, pluginName, version, this, description, productVersion);
-                        _plugins.Add(plugin);
-                    }
-                }
+                _catalogs.Add(assemblyCatalog);
             }
 
             IsInitialized = true;
-
-            return Task.CompletedTask;
         }
 
         private bool IsPluginAssembly(string assemblyPath)
@@ -200,92 +152,52 @@ private bool IsPluginAssembly(string assemblyPath)
                     return false;
                 }
 
-                // First try to resolve plugin assemblies using MetadataLoadContext
-                if (_options.TypeFinderCriterias?.Any() == true)
+                if (_options.TypeFinderCriterias?.Any() != true)
                 {
-                    var coreAssemblyPath = typeof(int).Assembly.Location;
-                    var corePath = Path.GetDirectoryName(coreAssemblyPath);
-
-                    var coreLocation = Path.Combine(corePath, "mscorlib.dll");
-
-                    if (!File.Exists(coreLocation))
-                    {
-                        throw new FileNotFoundException(coreLocation);
-                    }
-
-                    var runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll");
-                    var paths = new List<string>(runtimeAssemblies);
-                    paths.Add(assemblyPath);
-
-                    if (_options.PluginLoadContextOptions.UseHostApplicationAssemblies == UseHostApplicationAssembliesEnum.Always)
-                    {
-                        var hostApplicationPath = Environment.CurrentDirectory;
-                        var hostDlls = Directory.GetFiles(hostApplicationPath, "*.dll", SearchOption.AllDirectories);
-
-                        paths.AddRange(hostDlls);
-                    }
-                    else if (_options.PluginLoadContextOptions.UseHostApplicationAssemblies == UseHostApplicationAssembliesEnum.Never)
-                    {
-                        var pluginPath = Path.GetDirectoryName(assemblyPath);
-                        var dllsInPluginPath = Directory.GetFiles(pluginPath, "*.dll", SearchOption.AllDirectories);
-
-                        paths.AddRange(dllsInPluginPath);
-                    }
-                    else if (_options.PluginLoadContextOptions.UseHostApplicationAssemblies == UseHostApplicationAssembliesEnum.Selected)
-                    {
-                        foreach (var hostApplicationAssembly in _options.PluginLoadContextOptions.HostApplicationAssemblies)
-                        {
-                            var assembly = Assembly.Load(hostApplicationAssembly);
-                            paths.Add(assembly.Location);
-                        }
-                    }
-
-                    var resolver = new PathAssemblyResolver(paths);
-
-                    using (var metadataContext = new MetadataLoadContext(resolver))
-                    {
-                        var metadataPluginLoadContext = new MetadataTypeFindingContext(metadataContext);
-                        var readonlyAssembly = metadataContext.LoadFromAssemblyPath(assemblyPath);
+                    // If there are no resolvers, assume that each DLL is a plugin
+                    return true;
+                }
 
-                        var typeFinder = new TypeFinder();
+                var runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll");
+                var paths = new List<string>(runtimeAssemblies) { assemblyPath };
 
-                        foreach (var finderCriteria in _options.TypeFinderCriterias)
-                        {
-                            var typesFound = typeFinder.Find(finderCriteria.Value, readonlyAssembly, metadataPluginLoadContext);
+                if (_options.PluginLoadContextOptions.UseHostApplicationAssemblies == UseHostApplicationAssembliesEnum.Always)
+                {
+                    var hostApplicationPath = Environment.CurrentDirectory;
+                    var hostDlls = Directory.GetFiles(hostApplicationPath, "*.dll", SearchOption.AllDirectories);
 
-                            if (typesFound?.Any() == true)
-                            {
-                                return true;
-                            }
-                        }
-                    }
+                    paths.AddRange(hostDlls);
+                }
+                else if (_options.PluginLoadContextOptions.UseHostApplicationAssemblies == UseHostApplicationAssembliesEnum.Never)
+                {
+                    var pluginPath = Path.GetDirectoryName(assemblyPath);
+                    var dllsInPluginPath = Directory.GetFiles(pluginPath, "*.dll", SearchOption.AllDirectories);
 
-                    if (_options.PluginResolvers.Any() != true)
+                    paths.AddRange(dllsInPluginPath);
+                }
+                else if (_options.PluginLoadContextOptions.UseHostApplicationAssemblies == UseHostApplicationAssembliesEnum.Selected)
+                {
+                    foreach (var hostApplicationAssembly in _options.PluginLoadContextOptions.HostApplicationAssemblies)
                     {
-                        // If there is assembly resolvers but no plugin resolvers, return false by default if not assembly resolver did not match.
-                        return false;
+                        var assembly = Assembly.Load(hostApplicationAssembly);
+                        paths.Add(assembly.Location);
                     }
                 }
 
-                if (_options.PluginResolvers?.Any() != true)
-                {
-                    // If there are no resolvers, assume that each DLL is a plugin
-                    return true;
-                }
+                var resolver = new PathAssemblyResolver(paths);
 
-                // Then using the PEReader
-                var metadata = reader.GetMetadataReader();
+                using (var metadataContext = new MetadataLoadContext(resolver))
+                {
+                    var metadataPluginLoadContext = new MetadataTypeFindingContext(metadataContext);
+                    var readonlyAssembly = metadataContext.LoadFromAssemblyPath(assemblyPath);
 
-                var publicTypes = metadata.TypeDefinitions
-                    .Select(metadata.GetTypeDefinition)
-                    .Where(t => t.Attributes.HasFlag(TypeAttributes.Public))
-                    .ToArray();
+                    var typeFinder = new TypeFinder();
 
-                foreach (var type in publicTypes)
-                {
-                    foreach (var pluginResolver in _options.PluginResolvers)
+                    foreach (var finderCriteria in _options.TypeFinderCriterias)
                     {
-                        if (pluginResolver(assemblyPath, metadata, type))
+                        var typesFound = typeFinder.Find(finderCriteria.Value, readonlyAssembly, metadataPluginLoadContext);
+
+                        if (typesFound?.Any() == true)
                         {
                             return true;
                         }
@@ -307,6 +219,7 @@ public List<Type> Find(TypeFinderCriteria criteria, Assembly assembly, ITypeFind
             }
 
             var result = new List<Type>();
+
             var types = assembly.GetExportedTypes();
 
             foreach (var type in types)
@@ -343,7 +256,7 @@ public List<Type> Find(TypeFinderCriteria criteria, Assembly assembly, ITypeFind
 
                 if (string.IsNullOrWhiteSpace(criteria.Name) == false)
                 {
-                    var regEx = new Regex(criteria.Name, RegexOptions.Compiled);
+                    var regEx = NameToRegex(criteria.Name);
 
                     if (regEx.IsMatch(type.FullName) == false)
                     {
@@ -370,18 +283,36 @@ public List<Type> Find(TypeFinderCriteria criteria, Assembly assembly, ITypeFind
                         continue;
                     }
                 }
+                
+                if (criteria.AssignableTo != null)
+                {
+                    var assignableToType = typeFindingContext.FindType(criteria.AssignableTo);
+
+                    if (assignableToType.IsAssignableFrom(type) == false)
+                    {
+                        continue;
+                    }
+                }
 
                 result.Add(type);
             }
 
             return result;
         }
+
+        private static Regex NameToRegex(string nameFilter)
+        {
+            // https://stackoverflow.com/a/30300521/66988
+            var regex = "^" + Regex.Escape(nameFilter).Replace("\\?", ".").Replace("\\*", ".*") + "$";
+            return new Regex(regex, RegexOptions.Compiled);
+        }
     }
 
     public class TypeFinderCriteria
     {
         public Type Inherits { get; set; }
         public Type Implements { get; set; }
+        public Type AssignableTo { get; set; }
         public bool? IsAbstract { get; set; }
         public bool? IsInterface { get; set; }
         public string Name { get; set; }
@@ -392,6 +323,7 @@ public class TypeFinderCriteriaBuilder
     {
         private Type _inherits;
         private Type _implements;
+        private Type _assignable;
         private bool _isAbstract;
         private bool _isInterface;
         private string _name;
@@ -403,6 +335,7 @@ public TypeFinderCriteria Build()
                 IsInterface = _isInterface,
                 Implements = _implements,
                 Inherits = _inherits,
+                AssignableTo = _assignable,
                 Name = _name,
                 IsAbstract = _isAbstract
             };
@@ -464,6 +397,13 @@ public TypeFinderCriteriaBuilder IsInterface(bool isInterface)
 
             return this;
         }
+        
+        public TypeFinderCriteriaBuilder AssignableTo(Type assignableTo)
+        {
+            _assignable = assignableTo;
+
+            return this;
+        }
     }
 
     public interface ITypeFindingContext
diff --git a/src/Weikio.PluginFramework/Catalogs/FolderPluginCatalogOptions.cs b/src/Weikio.PluginFramework/Catalogs/FolderPluginCatalogOptions.cs
index 1bebaf9..3001917 100644
--- a/src/Weikio.PluginFramework/Catalogs/FolderPluginCatalogOptions.cs
+++ b/src/Weikio.PluginFramework/Catalogs/FolderPluginCatalogOptions.cs
@@ -10,10 +10,10 @@ public class FolderPluginCatalogOptions
     {
         public bool IncludSubfolders { get; set; } = true;
         public List<string> SearchPatterns = new List<string>() {"*.dll"};
-        public List<Func<string, MetadataReader, TypeDefinition, bool>> PluginResolvers = new List<Func<string, MetadataReader, TypeDefinition, bool>>();
-        // public List<Func<ITypeFindingContext, Type, bool>> TypePluginResolvers = new List<Func<ITypeFindingContext, Type, bool>>();
+        // public List<Func<string, MetadataReader, TypeDefinition, bool>> PluginResolvers = new List<Func<string, MetadataReader, TypeDefinition, bool>>();
         public PluginLoadContextOptions PluginLoadContextOptions = new PluginLoadContextOptions();
         public TypeFinderCriteria TypeFinderCriteria = null;
         public Dictionary<string, TypeFinderCriteria> TypeFinderCriterias = new Dictionary<string, TypeFinderCriteria>();
+        public PluginNameOptions PluginNameOptions { get; set; } = new PluginNameOptions();
     }
 }
diff --git a/src/Weikio.PluginFramework/Catalogs/PluginNameOptions.cs b/src/Weikio.PluginFramework/Catalogs/PluginNameOptions.cs
new file mode 100644
index 0000000..6fc8ab7
--- /dev/null
+++ b/src/Weikio.PluginFramework/Catalogs/PluginNameOptions.cs
@@ -0,0 +1,74 @@
+using System;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Reflection;
+
+namespace Weikio.PluginFramework.Catalogs
+{
+    public class PluginNameOptions
+    {
+        public Func<PluginNameOptions, Type, string> PluginNameGenerator { get; set; } = (options, type) =>
+        {
+            var displayNameAttribute = type.GetCustomAttribute(typeof(DisplayNameAttribute), true) as DisplayNameAttribute;
+
+            if (displayNameAttribute == null)
+            {
+                return type.FullName;
+            }
+
+            if (string.IsNullOrWhiteSpace(displayNameAttribute.DisplayName))
+            {
+                return type.FullName;
+            }
+
+            return displayNameAttribute.DisplayName;
+        };
+
+        public Func<PluginNameOptions, Type, Version> PluginVersionGenerator { get; set; } = (options, type) =>
+        {
+            var assemblyLocation = type.Assembly.Location;
+            Version version;
+
+            if (!string.IsNullOrWhiteSpace(assemblyLocation))
+            {
+                var versionInfo = FileVersionInfo.GetVersionInfo(assemblyLocation);
+
+                version = Version.Parse(versionInfo.FileVersion);
+            }
+            else
+            {
+                version = new Version(1, 0, 0, 0);
+            }
+
+            return version;
+        };
+
+        public Func<PluginNameOptions, Type, string> PluginDescriptionGenerator { get; set; } = (options, type) =>
+        {
+            var assemblyLocation = type.Assembly.Location;
+
+            if (string.IsNullOrWhiteSpace(assemblyLocation))
+            {
+                return string.Empty;
+            }
+
+            var versionInfo = FileVersionInfo.GetVersionInfo(assemblyLocation);
+
+            return versionInfo.Comments;
+        };
+
+        public Func<PluginNameOptions, Type, string> PluginProductVersionGenerator { get; set; } = (options, type) =>
+        {
+            var assemblyLocation = type.Assembly.Location;
+
+            if (string.IsNullOrWhiteSpace(assemblyLocation))
+            {
+                return string.Empty;
+            }
+
+            var versionInfo = FileVersionInfo.GetVersionInfo(assemblyLocation);
+
+            return versionInfo.ProductVersion;
+        };
+    }
+}
diff --git a/src/Weikio.PluginFramework/Catalogs/TypePluginCatalog.cs b/src/Weikio.PluginFramework/Catalogs/TypePluginCatalog.cs
index 7135abc..423088f 100644
--- a/src/Weikio.PluginFramework/Catalogs/TypePluginCatalog.cs
+++ b/src/Weikio.PluginFramework/Catalogs/TypePluginCatalog.cs
@@ -13,61 +13,66 @@ public class TypePluginCatalog : IPluginCatalog
         private readonly TypePluginCatalogOptions _options;
         private Plugin _plugin;
 
-        public TypePluginCatalog(Type pluginType, TypePluginCatalogOptions options = null)
+        public TypePluginCatalog(Type pluginType) : this(pluginType, null, null, null)
         {
-            _pluginType = pluginType;
-            _options = options ?? new TypePluginCatalogOptions();
+            
         }
-
-        public Task Initialize()
+            
+        public TypePluginCatalog(Type pluginType, PluginNameOptions nameOptions) : this (pluginType, null, nameOptions, null)
         {
-            var version = _options.PluginVersionGenerator(_options, _pluginType);
-            var pluginName = _options.PluginNameGenerator(_options, _pluginType);
-            var description = _options.PluginDescriptionGenerator(_options, _pluginType);
-            var productVersion = _options.PluginProductVersionGenerator(_options, _pluginType);
-
-            _pluginOld = new PluginOld(pluginName, version, this, description, productVersion);
-            _plugin = new Plugin(_pluginType.Assembly, _pluginType, pluginName, version, this, description, productVersion);
-            IsInitialized = true;
-
-            return Task.CompletedTask;
         }
 
-        public bool IsInitialized { get; private set; }
-
-        public Task<List<PluginOld>> GetPluginsOld()
+        public TypePluginCatalog(Type pluginType, Action<PluginNameOptions> configure) : this(pluginType, configure, null, null)
         {
-            var result = new List<PluginOld>() { _pluginOld };
+        }
 
-            return Task.FromResult(result);
+        public TypePluginCatalog(Type pluginType, TypePluginCatalogOptions options) : this(pluginType, null, null, options)
+        {
         }
 
-        public Task<PluginOld> GetPlugin(string name, Version version)
+        public TypePluginCatalog(Type pluginType, Action<PluginNameOptions> configure, PluginNameOptions nameOptions, TypePluginCatalogOptions options)
         {
-            if (!string.Equals(name, _pluginOld.Name, StringComparison.InvariantCultureIgnoreCase) ||
-                version != _pluginOld.Version)
+            if (pluginType == null)
             {
-                return Task.FromResult<PluginOld>(null);
+                throw new ArgumentNullException(nameof(pluginType));
             }
 
-            return Task.FromResult(_pluginOld);
-        }
+            _pluginType = pluginType;
+            _options = options ?? new TypePluginCatalogOptions();
 
-        public Task<Assembly> GetAssembly(PluginOld definition)
-        {
-            return Task.FromResult(_pluginType.Assembly);
+            if (nameOptions == null)
+            {
+                nameOptions = new PluginNameOptions();
+            }
+
+            if (configure != null)
+            {
+                configure(nameOptions);
+            }
+
+            _options.PluginNameOptions = nameOptions;
         }
 
-        public bool SupportsUnload { get; }
-        public Task Unload()
+        public Task Initialize()
         {
-            throw new NotImplementedException();
+            var namingOptions = _options.PluginNameOptions;
+            var version = namingOptions.PluginVersionGenerator(namingOptions, _pluginType);
+            var pluginName = namingOptions.PluginNameGenerator(namingOptions, _pluginType);
+            var description = namingOptions.PluginDescriptionGenerator(namingOptions, _pluginType);
+            var productVersion = namingOptions.PluginProductVersionGenerator(namingOptions, _pluginType);
+
+            _pluginOld = new PluginOld(pluginName, version, this, description, productVersion);
+            _plugin = new Plugin(_pluginType.Assembly, _pluginType, pluginName, version, this, description, productVersion);
+            IsInitialized = true;
+
+            return Task.CompletedTask;
         }
 
-        public bool Unloaded { get; }
+        public bool IsInitialized { get; private set; }
+
         public List<Plugin> GetPlugins()
         {
-            return new List<Plugin>(){_plugin};
+            return new List<Plugin>() { _plugin };
         }
 
         public Plugin Get(string name, Version version)
diff --git a/src/Weikio.PluginFramework/Catalogs/TypePluginCatalogOptions.cs b/src/Weikio.PluginFramework/Catalogs/TypePluginCatalogOptions.cs
index 2556ec3..728d7f4 100644
--- a/src/Weikio.PluginFramework/Catalogs/TypePluginCatalogOptions.cs
+++ b/src/Weikio.PluginFramework/Catalogs/TypePluginCatalogOptions.cs
@@ -1,74 +1,7 @@
-using System;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Reflection;
-
-namespace Weikio.PluginFramework.Catalogs
+namespace Weikio.PluginFramework.Catalogs
 {
     public class TypePluginCatalogOptions
     {
-        public Func<TypePluginCatalogOptions, Type, string> PluginNameGenerator { get; set; } = (options, type) =>
-        {
-            var displayNameAttribute = type.GetCustomAttribute(typeof(DisplayNameAttribute), true) as DisplayNameAttribute;
-
-            if (displayNameAttribute == null)
-            {
-                return type.FullName;
-            }
-
-            if (string.IsNullOrWhiteSpace(displayNameAttribute.DisplayName))
-            {
-                return type.FullName;
-            }
-
-            return displayNameAttribute.DisplayName;
-        };
-        
-        public Func<TypePluginCatalogOptions, Type, Version> PluginVersionGenerator { get; set; } = (options, type) =>
-        {
-            var assemblyLocation = type.Assembly.Location;
-            Version version;
-
-            if (!string.IsNullOrWhiteSpace(assemblyLocation))
-            {
-                var versionInfo = FileVersionInfo.GetVersionInfo(assemblyLocation);
-
-                version = Version.Parse(versionInfo.FileVersion);
-            }
-            else
-            {
-                version = new Version(1, 0, 0, 0);
-            }
-
-            return version;
-        };
-        
-        public Func<TypePluginCatalogOptions, Type, string> PluginDescriptionGenerator { get; set; } = (options, type) =>
-        {
-            var assemblyLocation = type.Assembly.Location;
-
-            if (string.IsNullOrWhiteSpace(assemblyLocation))
-            {
-                return string.Empty;
-            }
-
-            var versionInfo = FileVersionInfo.GetVersionInfo(assemblyLocation);
-
-            return versionInfo.Comments;
-        };
-        
-        public Func<TypePluginCatalogOptions, Type, string> PluginProductVersionGenerator { get; set; } = (options, type) =>
-        {
-            var assemblyLocation = type.Assembly.Location;
-
-            if (string.IsNullOrWhiteSpace(assemblyLocation))
-            {
-                return string.Empty;
-            }
-
-            var versionInfo = FileVersionInfo.GetVersionInfo(assemblyLocation);
-
-            return versionInfo.ProductVersion;
-        };
+        public PluginNameOptions PluginNameOptions { get; set; } = new PluginNameOptions();
     }
 }
diff --git a/tests/Assemblies/JsonNetNew/JsonNetNew.csproj b/tests/Assemblies/JsonNetNew/JsonNetNew.csproj
index fefa2f1..060466c 100644
--- a/tests/Assemblies/JsonNetNew/JsonNetNew.csproj
+++ b/tests/Assemblies/JsonNetNew/JsonNetNew.csproj
@@ -9,7 +9,7 @@
   </PropertyGroup>
   
   <ItemGroup>
-    <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
+    <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
   </ItemGroup>
 
   <ItemGroup>
diff --git a/tests/unit/Weikio.PluginFramework.Tests/AssemblyPluginCatalogTests.cs b/tests/unit/Weikio.PluginFramework.Tests/AssemblyPluginCatalogTests.cs
index 76c0033..22a5bf7 100644
--- a/tests/unit/Weikio.PluginFramework.Tests/AssemblyPluginCatalogTests.cs
+++ b/tests/unit/Weikio.PluginFramework.Tests/AssemblyPluginCatalogTests.cs
@@ -7,161 +7,138 @@
 using Weikio.PluginFramework.Catalogs;
 using Weikio.PluginFramework.Context;
 using Xunit;
+using Xunit.Abstractions;
 
 namespace Weikio.PluginFramework.Tests
 {
     public class AssemblyPluginCatalogTests
     {
-        [Fact]
-        public async Task CanInitialize()
+        private readonly ITestOutputHelper _testOutputHelper;
+
+        public AssemblyPluginCatalogTests(ITestOutputHelper testOutputHelper)
         {
-            throw new NotImplementedException();;
-            // var catalog = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\netstandard2.0\TestAssembly1.dll");
-            // await catalog.Initialize();
-            //
-            // var allPlugins = await catalog.GetPluginsOld();
-            //
-            // Assert.Single(allPlugins);
+            _testOutputHelper = testOutputHelper;
         }
-        
+
         [Fact]
-        public async Task CanUnload()
+        public async Task CanInitialize()
         {
-            throw new NotImplementedException();;
-            // var catalog = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\netstandard2.0\TestAssembly1.dll");
-            // await catalog.Initialize();
-            //
-            // var pluginDefinition = (await catalog.GetAll()).Single();
-            //
-            // var pluginExporter = new PluginExporter();
-            // var plugin = await pluginExporter.Get(pluginDefinition);
-            //
-            // dynamic jsonResolver = Activator.CreateInstance(plugin.Types.First());
-            // jsonResolver.RunMe();
-            //
-            // await catalog.Unload();
-            //
-            // await Assert.ThrowsAsync<CatalogUnloadedException>(async () => await pluginExporter.Get(pluginDefinition));
+            var catalog = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\netstandard2.0\TestAssembly1.dll");
+            await catalog.Initialize();
+
+            var allPlugins = catalog.GetPlugins();
+
+            Assert.Single(allPlugins);
         }
-        
+
         [Fact]
         public async Task ThrowsIfAssemblyNotFound()
         {
-            throw new NotImplementedException();;
-            // var catalog = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\netstandard2.0\notexists.dll");
-            //
-            // await Assert.ThrowsAsync<ArgumentException>(async () => await catalog.Initialize());
+            var catalog = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\netstandard2.0\notexists.dll");
+
+            await Assert.ThrowsAsync<ArgumentException>(async () => await catalog.Initialize());
         }
-        
+
         [Fact]
         public void ThrowsIfAssemblyPathMissing()
         {
-            throw new NotImplementedException();;
-            // Assert.Throws<ArgumentNullException>(() => new AssemblyPluginCatalog(""));
-            //
-            // string path = null;
-            // Assert.Throws<ArgumentNullException>(() => new AssemblyPluginCatalog(path));
+            Assert.Throws<ArgumentNullException>(() => new AssemblyPluginCatalog(""));
+
+            string path = null;
+            Assert.Throws<ArgumentNullException>(() => new AssemblyPluginCatalog(path));
         }
-        
+
         [Fact]
         public async Task CanUseReferencedDependencies()
         {
-            throw new NotImplementedException();;
-
-            // // Make sure that the referenced version of JSON.NET is loaded into memory
-            // var json = Newtonsoft.Json.JsonConvert.SerializeObject(1);
-            //
-            // var assemblyCatalog1 = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonNew\netstandard2.0\JsonNetNew.dll");
-            // await assemblyCatalog1.Initialize();
-            //
-            // var assemblyCatalog2 = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonOld\netstandard2.0\JsonNetOld.dll");
-            // await assemblyCatalog2.Initialize();
-            //
-            // var newPluginDefinition = (await assemblyCatalog1.GetAll()).Single();
-            // var oldPluginDefinition = (await assemblyCatalog2.GetAll()).Single();
-            //
-            // var pluginExporter = new PluginExporter();
-            // var newPlugin = await pluginExporter.Get(newPluginDefinition);
-            // var oldPlugin = await pluginExporter.Get(oldPluginDefinition);
-            //
-            // dynamic newPluginJsonResolver = Activator.CreateInstance(newPlugin.Types.First());
-            // var newPluginVersion = newPluginJsonResolver.GetVersion();
-            //
-            // dynamic oldPluginJsonResolver = Activator.CreateInstance(oldPlugin.Types.First());
-            // var oldPluginVersion = oldPluginJsonResolver.GetVersion();
-            //
-            // Assert.Equal("12.0.0.0", newPluginVersion);
-            // Assert.Equal("9.0.0.0", oldPluginVersion);
+            // Make sure that the referenced version of JSON.NET is loaded into memory
+            var json = Newtonsoft.Json.JsonConvert.SerializeObject(1);
+            _testOutputHelper.WriteLine(json);
+
+            var options = new AssemblyPluginCatalogOptions()
+            {
+                PluginLoadContextOptions = new PluginLoadContextOptions() { UseHostApplicationAssemblies = UseHostApplicationAssembliesEnum.Never }
+            };
+
+            var assemblyCatalog1 = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonNew\netstandard2.0\JsonNetNew.dll", options);
+            await assemblyCatalog1.Initialize();
+
+            var assemblyCatalog2 = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonOld\netstandard2.0\JsonNetOld.dll", options);
+            await assemblyCatalog2.Initialize();
+
+            var newPlugin = assemblyCatalog1.Single();
+            var oldPlugin = assemblyCatalog2.Single();
+
+            dynamic newPluginJsonResolver = Activator.CreateInstance(newPlugin);
+            var newPluginVersion = newPluginJsonResolver.GetVersion();
+
+            dynamic oldPluginJsonResolver = Activator.CreateInstance(oldPlugin);
+            var oldPluginVersion = oldPluginJsonResolver.GetVersion();
+
+            Assert.Equal("10.0.0.0", newPluginVersion);
+            Assert.Equal("9.0.0.0", oldPluginVersion);
         }
 
         [Fact]
         public async Task CanUseHostsDependencies()
         {
-            throw new NotImplementedException();;
-
-            // // Make sure that the referenced version of JSON.NET is loaded into memory
-            // var json = Newtonsoft.Json.JsonConvert.SerializeObject(1);
-            //
-            // var options = new AssemblyPluginCatalogOptions();
-            // options.PluginLoadContextOptions = new PluginLoadContextOptions() { UseHostApplicationAssemblies = UseHostApplicationAssembliesEnum.Always };
-            //
-            // var folder1Catalog = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonNew\netstandard2.0\JsonNetNew.dll", options);
-            // await folder1Catalog.Initialize();
-            //
-            // var folder2Catalog = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonOld\netstandard2.0\JsonNetOld.dll", options);
-            // await folder2Catalog.Initialize();
-            //
-            // var newPluginDefinition = (await folder1Catalog.GetAll()).Single();
-            // var oldPluginDefinition = (await folder2Catalog.GetAll()).Single();
-            //
-            // var pluginExporter = new PluginExporter();
-            // var newPlugin = await pluginExporter.Get(newPluginDefinition);
-            // var oldPlugin = await pluginExporter.Get(oldPluginDefinition);
-            //
-            // dynamic newPluginJsonResolver = Activator.CreateInstance(newPlugin.Types.First());
-            // var newPluginVersion = newPluginJsonResolver.GetVersion();
-            //
-            // dynamic oldPluginJsonResolver = Activator.CreateInstance(oldPlugin.Types.First());
-            // var oldPluginVersion = oldPluginJsonResolver.GetVersion();
-            //
-            // Assert.Equal("10.0.0.0", newPluginVersion);
-            // Assert.Equal("10.0.0.0", oldPluginVersion);
+            // Make sure that the referenced version of JSON.NET is loaded into memory
+            var json = Newtonsoft.Json.JsonConvert.SerializeObject(1);
+            _testOutputHelper.WriteLine(json);
+
+            var options = new AssemblyPluginCatalogOptions
+            {
+                PluginLoadContextOptions = new PluginLoadContextOptions() { UseHostApplicationAssemblies = UseHostApplicationAssembliesEnum.Always }
+            };
+
+            var folder1Catalog = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonNew\netstandard2.0\JsonNetNew.dll", options);
+            await folder1Catalog.Initialize();
+            
+            var folder2Catalog = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonOld\netstandard2.0\JsonNetOld.dll", options);
+            await folder2Catalog.Initialize();
+
+            var newPlugin = folder1Catalog.Single();
+            var oldPlugin = folder2Catalog.Single();
+            
+            dynamic newPluginJsonResolver = Activator.CreateInstance(newPlugin);
+            var newPluginVersion = newPluginJsonResolver.GetVersion();
+            
+            dynamic oldPluginJsonResolver = Activator.CreateInstance(oldPlugin);
+            var oldPluginVersion = oldPluginJsonResolver.GetVersion();
+            
+            Assert.Equal("12.0.0.0", newPluginVersion);
+            Assert.Equal("12.0.0.0", oldPluginVersion);
         }
-        
+
         [Fact]
         public async Task CanUseSelectedHoststDependencies()
         {
-            throw new NotImplementedException();;
-            //
-            // // Make sure that the referenced version of JSON.NET is loaded into memory
-            // var json = Newtonsoft.Json.JsonConvert.SerializeObject(1);
-            // // Make sure that the referenced version of Microsoft.Extensions.Logging is loaded into memory
-            // var logging = new Microsoft.Extensions.Logging.LoggerFactory();
-            //
-            // var options = new AssemblyPluginCatalogOptions();;
-            // options.PluginLoadContextOptions = new PluginLoadContextOptions()
-            // {
-            //     UseHostApplicationAssemblies = UseHostApplicationAssembliesEnum.Selected,
-            //     HostApplicationAssemblies = new List<AssemblyName>()
-            //     {
-            //         typeof(Microsoft.Extensions.Logging.LoggerFactory).Assembly.GetName()
-            //     }
-            // };
-            //
-            // var catalog = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonOld\netstandard2.0\JsonNetOld.dll", options);
-            // await catalog.Initialize();
-            //
-            // var oldPluginDefinition = (await catalog.GetAll()).Single();
-            //
-            // var pluginExporter = new PluginExporter();
-            // var oldPlugin = await pluginExporter.Get(oldPluginDefinition);
-            //
-            // dynamic oldPluginJsonResolver = Activator.CreateInstance(oldPlugin.Types.First());
-            // var oldPluginVersion = oldPluginJsonResolver.GetVersion();
-            // var loggerVersion = oldPluginJsonResolver.GetLoggingVersion();
-            //
-            // Assert.Equal("3.1.2.0", loggerVersion);
-            // Assert.Equal("9.0.0.0", oldPluginVersion);
+            // Make sure that the referenced version of JSON.NET is loaded into memory
+            var json = Newtonsoft.Json.JsonConvert.SerializeObject(1);
+            // Make sure that the referenced version of Microsoft.Extensions.Logging is loaded into memory
+            var logging = new Microsoft.Extensions.Logging.LoggerFactory();
+            
+            var options = new AssemblyPluginCatalogOptions();;
+            options.PluginLoadContextOptions = new PluginLoadContextOptions()
+            {
+                UseHostApplicationAssemblies = UseHostApplicationAssembliesEnum.Selected,
+                HostApplicationAssemblies = new List<AssemblyName>()
+                {
+                    typeof(Microsoft.Extensions.Logging.LoggerFactory).Assembly.GetName()
+                }
+            };
+            
+            var catalog = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonOld\netstandard2.0\JsonNetOld.dll", options);
+            await catalog.Initialize();
+            
+            var oldPlugin = catalog.Single();
+            
+            dynamic oldPluginJsonResolver = Activator.CreateInstance(oldPlugin);
+            var oldPluginVersion = oldPluginJsonResolver.GetVersion();
+            var loggerVersion = oldPluginJsonResolver.GetLoggingVersion();
+            
+            Assert.Equal("3.1.2.0", loggerVersion);
+            Assert.Equal("9.0.0.0", oldPluginVersion);
         }
     }
 }
diff --git a/tests/unit/Weikio.PluginFramework.Tests/DefaultOptionsTests.cs b/tests/unit/Weikio.PluginFramework.Tests/DefaultOptionsTests.cs
index e6dcc0f..ba473f1 100644
--- a/tests/unit/Weikio.PluginFramework.Tests/DefaultOptionsTests.cs
+++ b/tests/unit/Weikio.PluginFramework.Tests/DefaultOptionsTests.cs
@@ -15,46 +15,32 @@ public class DefaultOptionsTests
         [Fact]
         public async Task CanConfigureDefaultOptions()
         {
-            throw new NotImplementedException();;
-            //
-            // // Make sure that the referenced version of JSON.NET is loaded into memory
-            // var json = Newtonsoft.Json.JsonConvert.SerializeObject(1);
-            //
-            // PluginLoadContextOptions.Defaults.UseHostApplicationAssemblies = UseHostApplicationAssembliesEnum.Always;
-            //
-            // var assemblyPluginCatalog = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonNew\netstandard2.0\JsonNetNew.dll");
-            // await assemblyPluginCatalog.Initialize();
-            //
-            // var folderPluginCatalog = new FolderPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonOld\netstandard2.0", new FolderPluginCatalogOptions()
-            // {
-            //     AssemblyPluginResolvers = new List<Func<Assembly, bool>>()
-            //     {
-            //         assembly =>
-            //         {
-            //             var result = assembly.ExportedTypes.Any(x => x.Name.EndsWith("JsonResolver"));
-            //
-            //             return result;
-            //         }
-            //     }
-            // });
-            //     
-            // await folderPluginCatalog.Initialize();
-            //
-            // var assemblyPluginDefinition = (await assemblyPluginCatalog.GetAll()).Single();
-            // var folderPluginDefinition = (await folderPluginCatalog.GetAll()).Single();
-            //
-            // var pluginExporter = new PluginExporter();
-            // var newPlugin = await pluginExporter.Get(assemblyPluginDefinition);
-            // var oldPlugin = await pluginExporter.Get(folderPluginDefinition);
-            //
-            // dynamic newPluginJsonResolver = Activator.CreateInstance(newPlugin.Types.First());
-            // var newPluginVersion = newPluginJsonResolver.GetVersion();
-            //
-            // dynamic oldPluginJsonResolver = Activator.CreateInstance(oldPlugin.Types.First());
-            // var oldPluginVersion = oldPluginJsonResolver.GetVersion();
-            //
-            // Assert.Equal("10.0.0.0", newPluginVersion);
-            // Assert.Equal("10.0.0.0", oldPluginVersion);
+            // Make sure that the referenced version of JSON.NET is loaded into memory
+            var json = Newtonsoft.Json.JsonConvert.SerializeObject(1);
+            PluginLoadContextOptions.Defaults.UseHostApplicationAssemblies = UseHostApplicationAssembliesEnum.Always;
+
+            Action<TypeFinderCriteriaBuilder> configureFinder = configure =>
+            {
+                configure.HasName("*JsonResolver");
+            };
+            
+            var assemblyPluginCatalog = new AssemblyPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonNew\netstandard2.0\JsonNetNew.dll", configureFinder);
+            var folderPluginCatalog = new FolderPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonOld\netstandard2.0", configureFinder);
+            
+            await assemblyPluginCatalog.Initialize();
+            await folderPluginCatalog.Initialize();
+            
+            var newPlugin = assemblyPluginCatalog.Single();
+            var oldPlugin = folderPluginCatalog.Single();
+            
+            dynamic newPluginJsonResolver = Activator.CreateInstance(newPlugin);
+            var newPluginVersion = newPluginJsonResolver.GetVersion();
+            
+            dynamic oldPluginJsonResolver = Activator.CreateInstance(oldPlugin);
+            var oldPluginVersion = oldPluginJsonResolver.GetVersion();
+            
+            Assert.Equal("12.0.0.0", newPluginVersion);
+            Assert.Equal("12.0.0.0", oldPluginVersion);
         }
     }
 }
diff --git a/tests/unit/Weikio.PluginFramework.Tests/FolderCatalogTests.cs b/tests/unit/Weikio.PluginFramework.Tests/FolderCatalogTests.cs
index 10a5196..2d7a662 100644
--- a/tests/unit/Weikio.PluginFramework.Tests/FolderCatalogTests.cs
+++ b/tests/unit/Weikio.PluginFramework.Tests/FolderCatalogTests.cs
@@ -18,190 +18,87 @@ public class FolderCatalogTests
         [Fact]
         public async Task CanInitialize()
         {
-            throw new NotImplementedException();;
-            // var plugins = new FolderPluginCatalog(_pluginFolder);
-            // await plugins.Initialize();
-            //
-            // var dllCount = Directory.GetFiles(_pluginFolder, "*.dll").Length;
-            // var pluginCount = (await plugins.GetPluginsOld()).Count;
-            //
-            // Assert.Equal(dllCount, pluginCount);
-        }
-        
-        [Fact]
-        public async Task CanUnload()
-        {
-            throw new NotImplementedException();;
-            // var catalog = new FolderPluginCatalog(_pluginFolder);
-            // await catalog.Initialize();
-            //
-            // await catalog.GetPluginsOld();
-            //
-            // await catalog.Unload();
-            //
-            // await Assert.ThrowsAsync<CatalogUnloadedException>(async () => await catalog.GetPluginsOld());
+            var catalog = new FolderPluginCatalog(_pluginFolder);
+            await catalog.Initialize();
+            
+            var plugins = catalog.GetPlugins();
+            
+            Assert.NotEmpty(plugins);
         }
 
         [Fact]
-        public async Task CanInitializeWithPluginResolver()
+        public async Task CanInitializeWithCriteria()
         {
-            throw new NotImplementedException();;
+            var catalog = new FolderPluginCatalog(_pluginFolder, configure =>
+            {
+                configure.HasName("*Plugin");
+            });
+            
+            await catalog.Initialize();
 
-            // var options = new FolderPluginCatalogOptions();
-            //
-            // options.PluginResolvers.Add((assembly, metadata, type) =>
-            // {
-            //     var typeName = metadata.GetString(type.Name);
-            //
-            //     if (typeName.EndsWith("Plugin"))
-            //     {
-            //         return true;
-            //     }
-            //
-            //     return false;
-            // });
-            //
-            // var plugins = new FolderPluginCatalog(_pluginFolder, options);
-            // await plugins.Initialize();
-            //
-            // var pluginCount = (await plugins.GetPluginsOld()).Count;
-            //
-            // Assert.Equal(2, pluginCount);
-        }
-
-        [Fact]
-        public async Task CanInitializeWithMultiplePluginResolver()
-        {
-            throw new NotImplementedException();;
-            // var options = new FolderPluginCatalogOptions();
-            //
-            // options.PluginResolvers.Add((assembly, metadata, type) =>
-            // {
-            //     var typeName = metadata.GetString(type.Name);
-            //
-            //     if (typeName.EndsWith("Plugin"))
-            //     {
-            //         return true;
-            //     }
-            //
-            //     return false;
-            // });
-            //
-            // options.PluginResolvers.Add((assembly, metadata, type) => assembly.ToLowerInvariant().EndsWith("testassembly3.dll"));
-            //
-            // var plugins = new FolderPluginCatalog(_pluginFolder, options);
-            // await plugins.Initialize();
-            //
-            // var pluginCount = (await plugins.GetPluginsOld()).Count;
-            //
-            // Assert.Equal(3, pluginCount);
-        }
-
-        [Fact]
-        public async Task CanInitializeWithAssemblyPluginResolver()
-        {
-            throw new NotImplementedException();;
-            // var options = new FolderPluginCatalogOptions();
-            //
-            // options.AssemblyPluginResolvers.Add(assembly =>
-            // {
-            //     var types = assembly.GetExportedTypes();
-            //
-            //     if (types.Any(x => x.Name.EndsWith("Plugin")))
-            //     {
-            //         return true;
-            //     }
-            //
-            //     return false;
-            // });
-            //
-            // var plugins = new FolderPluginCatalog(_pluginFolder, options);
-            // await plugins.Initialize();
-            //
-            // var pluginCount = (await plugins.GetPluginsOld()).Count;
-            //
-            // Assert.Equal(2, pluginCount);
+            var pluginCount = catalog.GetPlugins().Count;
+            
+            Assert.Equal(2, pluginCount);
         }
 
         [Fact]
         public async Task CanUseReferencedDependencies()
         {
-            throw new NotImplementedException();;
+            PluginLoadContextOptions.Defaults.UseHostApplicationAssemblies = UseHostApplicationAssembliesEnum.Never;
+            
+            Action<TypeFinderCriteriaBuilder> configureFinder = configure =>
+            {
+                configure.HasName("*JsonResolver");
+            };
+            
+            var folder1Catalog = new FolderPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonNew\netstandard2.0", configureFinder);
+            var folder2Catalog = new FolderPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonOld\netstandard2.0", configureFinder);
+            
+            await folder1Catalog.Initialize();
+            await folder2Catalog.Initialize();
 
-            // var options = new FolderPluginCatalogOptions();
-            //
-            // options.AssemblyPluginResolvers.Add(assembly =>
-            // {
-            //     var result = assembly.ExportedTypes.Any(x => x.Name.EndsWith("JsonResolver"));
-            //
-            //     return result;
-            // });
-            //
-            // var folder1Catalog = new FolderPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonNew\netstandard2.0", options);
-            // await folder1Catalog.Initialize();
-            //
-            // var folder2Catalog = new FolderPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonOld\netstandard2.0", options);
-            // await folder2Catalog.Initialize();
-            //
-            // var newPluginDefinition = (await folder1Catalog.GetAll()).Single();
-            // var oldPluginDefinition = (await folder2Catalog.GetAll()).Single();
-            //
-            // var pluginExporter = new PluginExporter();
-            // var newPlugin = await pluginExporter.Get(newPluginDefinition);
-            // var oldPlugin = await pluginExporter.Get(oldPluginDefinition);
-            //
-            // dynamic newPluginJsonResolver = Activator.CreateInstance(newPlugin.Types.First());
-            // var newPluginVersion = newPluginJsonResolver.GetVersion();
-            //
-            // dynamic oldPluginJsonResolver = Activator.CreateInstance(oldPlugin.Types.First());
-            // var oldPluginVersion = oldPluginJsonResolver.GetVersion();
-            //
-            // Assert.Equal("12.0.0.0", newPluginVersion);
-            // Assert.Equal("9.0.0.0", oldPluginVersion);
+            var newPlugin = folder1Catalog.Single();
+            var oldPlugin = folder2Catalog.Single();
+            
+            dynamic newPluginJsonResolver = Activator.CreateInstance(newPlugin);
+            var newPluginVersion = newPluginJsonResolver.GetVersion();
+            
+            dynamic oldPluginJsonResolver = Activator.CreateInstance(oldPlugin);
+            var oldPluginVersion = oldPluginJsonResolver.GetVersion();
+            
+            Assert.Equal("10.0.0.0", newPluginVersion);
+            Assert.Equal("9.0.0.0", oldPluginVersion);
         }
 
         [Fact]
         public async Task CanUseSelectedHoststDependencies()
         {
-            throw new NotImplementedException();;
+            // Make sure that the referenced version of JSON.NET is loaded into memory
+            var json = Newtonsoft.Json.JsonConvert.SerializeObject(1);
+            // Make sure that the referenced version of Microsoft.Extensions.Logging is loaded into memory
+            var logging = new Microsoft.Extensions.Logging.LoggerFactory();
+
+            var options = new FolderPluginCatalogOptions
+            {
+                TypeFinderCriteria = new TypeFinderCriteria() { Name = "*JsonResolver" },
+                PluginLoadContextOptions = new PluginLoadContextOptions()
+                {
+                    UseHostApplicationAssemblies = UseHostApplicationAssembliesEnum.Selected,
+                    HostApplicationAssemblies = new List<AssemblyName>() { typeof(Microsoft.Extensions.Logging.LoggerFactory).Assembly.GetName() }
+                }
+            };
+
+            var catalog = new FolderPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonOld\netstandard2.0", options);
+            await catalog.Initialize();
 
-            //
-            // // Make sure that the referenced version of JSON.NET is loaded into memory
-            // var json = Newtonsoft.Json.JsonConvert.SerializeObject(1);
-            // // Make sure that the referenced version of Microsoft.Extensions.Logging is loaded into memory
-            // var logging = new Microsoft.Extensions.Logging.LoggerFactory();
-            //
-            // var options = new FolderPluginCatalogOptions();
-            // options.AssemblyPluginResolvers.Add(assembly =>
-            // {
-            //     var result = assembly.ExportedTypes.Any(x => x.Name.EndsWith("JsonResolver"));
-            //
-            //     return result;
-            // });
-            //
-            // options.PluginLoadContextOptions = new PluginLoadContextOptions()
-            // {
-            //     UseHostApplicationAssemblies = UseHostApplicationAssembliesEnum.Selected,
-            //     HostApplicationAssemblies = new List<AssemblyName>()
-            //     {
-            //         typeof(Microsoft.Extensions.Logging.LoggerFactory).Assembly.GetName()
-            //     }
-            // };
-            //
-            // var catalog = new FolderPluginCatalog(@"..\..\..\..\..\Assemblies\bin\JsonOld\netstandard2.0", options);
-            // await catalog.Initialize();
-            //
-            // var oldPluginDefinition = (await catalog.GetAll()).Single();
-            //
-            // var pluginExporter = new PluginExporter();
-            // var oldPlugin = await pluginExporter.Get(oldPluginDefinition);
-            //
-            // dynamic oldPluginJsonResolver = Activator.CreateInstance(oldPlugin.Types.First());
-            // var oldPluginVersion = oldPluginJsonResolver.GetVersion();
-            // var loggerVersion = oldPluginJsonResolver.GetLoggingVersion();
-            //
-            // Assert.Equal("3.1.2.0", loggerVersion);
-            // Assert.Equal("9.0.0.0", oldPluginVersion);
+            var oldPlugin = catalog.Single();
+            
+            dynamic oldPluginJsonResolver = Activator.CreateInstance(oldPlugin);
+            var oldPluginVersion = oldPluginJsonResolver.GetVersion();
+            var loggerVersion = oldPluginJsonResolver.GetLoggingVersion();
+            
+            Assert.Equal("3.1.2.0", loggerVersion);
+            Assert.Equal("9.0.0.0", oldPluginVersion);
         }
     }
 }
diff --git a/tests/unit/Weikio.PluginFramework.Tests/TestClass.cs b/tests/unit/Weikio.PluginFramework.Tests/TestClass.cs
index d3bfdef..ac0b76f 100644
--- a/tests/unit/Weikio.PluginFramework.Tests/TestClass.cs
+++ b/tests/unit/Weikio.PluginFramework.Tests/TestClass.cs
@@ -1,7 +1,10 @@
 using System;
+using System.Linq;
+using System.Linq.Expressions;
 using System.Reflection;
 using System.Threading.Tasks;
 using Xunit;
+using Xunit.Abstractions;
 
 namespace Weikio.PluginFramework.Tests
 {
@@ -12,6 +15,13 @@ public class TestClass
 
     public class Test
     {
+        private readonly ITestOutputHelper _testOutputHelper;
+
+        public Test(ITestOutputHelper testOutputHelper)
+        {
+            _testOutputHelper = testOutputHelper;
+        }
+
         // Roslyn generated?
         public dynamic Configuration { get; set; }
         
@@ -30,15 +40,31 @@ public void MyTest()
                 var y = s + i;
             });
 
+            var simpleAction = new Action(() =>
+            {
+                _testOutputHelper.WriteLine("Hello action");
+            });
+            
+            var simpleFunc = new Func<string>(() =>
+            {
+                return "Hello func";
+            });
+            
             var asyncTest = new Action<Task<string>, int>(async (Task<string> s, int i) =>
             {
                 var d = await s;
                 var y = d + i;
             });
-
+            
             Create(myFuncTest);
             Create(myActionTest);
             Create(asyncTest);
+
+            var type = CreateType(simpleFunc);
+
+            var hmmh = Activator.CreateInstance(type);
+            
+
         }
 
         public void Create(MulticastDelegate multicastDelegate)
@@ -48,5 +74,25 @@ public void Create(MulticastDelegate multicastDelegate)
             var parameters = methodInfo.GetParameters();
             var returnType = methodInfo.ReturnType;
         }
+
+        public Type CreateType(MulticastDelegate multicastDelegate)
+        {
+            var methodInfo = multicastDelegate.GetMethodInfo();
+            var types = methodInfo.GetParameters().Select(p => p.ParameterType);
+            types = types.Concat(new[] { methodInfo.ReturnType });
+
+            if (methodInfo.ReturnType == typeof(void))
+            {
+                var actionType = Expression.GetActionType(types.ToArray());
+            }
+            else
+            {
+                var funcType = Expression.GetFuncType(types.ToArray());
+
+                return funcType;
+            }
+
+            return null;
+        }
     }
 }
diff --git a/tests/unit/Weikio.PluginFramework.Tests/TypePluginCatalogTests.cs b/tests/unit/Weikio.PluginFramework.Tests/TypePluginCatalogTests.cs
index 7ece9dd..35076ac 100644
--- a/tests/unit/Weikio.PluginFramework.Tests/TypePluginCatalogTests.cs
+++ b/tests/unit/Weikio.PluginFramework.Tests/TypePluginCatalogTests.cs
@@ -1,5 +1,5 @@
-using System.Linq;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
+using Weikio.PluginFramework.Abstractions;
 using Weikio.PluginFramework.Catalogs;
 using Weikio.PluginFramework.Tests.Plugins;
 using Xunit;
@@ -14,9 +14,8 @@ public async Task CanInitialize()
             var catalog = new TypePluginCatalog(typeof(TypePlugin));
             await catalog.Initialize();
 
-            var allPlugins = await catalog.GetPluginsOld();
-
-            Assert.Single(allPlugins);
+            var plugins = catalog.GetPlugins();
+            Assert.Single(plugins);
         }
 
         [Fact]
@@ -25,31 +24,35 @@ public async Task NameIsTypeFullName()
             var catalog = new TypePluginCatalog(typeof(TypePlugin));
             await catalog.Initialize();
 
-            var thePlugin = (await catalog.GetPluginsOld()).First();
-
+            var thePlugin = catalog.Single();
+        
             Assert.Equal("Weikio.PluginFramework.Tests.Plugins.TypePlugin", thePlugin.Name);
         }
-
+        
         [Fact]
         public async Task CanConfigureNameResolver()
         {
-            var catalog = new TypePluginCatalog(typeof(TypePlugin), new TypePluginCatalogOptions() { PluginNameGenerator = (options, type) => "HelloOptions" });
-
+            var catalog = new TypePluginCatalog(typeof(TypePlugin), configure =>
+            {
+                configure.PluginNameGenerator = (opt, type) => "HelloOptions";
+            });
+        
             await catalog.Initialize();
 
-            var thePlugin = (await catalog.GetPluginsOld()).First();
-
+            var thePlugin = catalog.Single();
+        
             Assert.Equal("HelloOptions", thePlugin.Name);
         }
-
+        
+        
         [Fact]
         public async Task CanSetNameByAttribute()
         {
             var catalog = new TypePluginCatalog(typeof(TypePluginWithName));
             await catalog.Initialize();
 
-            var thePlugin = (await catalog.GetPluginsOld()).First();
-
+            var thePlugin = catalog.Single();
+        
             Assert.Equal("MyCustomName", thePlugin.Name);
         }
     }
diff --git a/tests/unit/Weikio.PluginFramework.Tests/Weikio.PluginFramework.Tests.csproj b/tests/unit/Weikio.PluginFramework.Tests/Weikio.PluginFramework.Tests.csproj
index 50b3073..b63b8b7 100644
--- a/tests/unit/Weikio.PluginFramework.Tests/Weikio.PluginFramework.Tests.csproj
+++ b/tests/unit/Weikio.PluginFramework.Tests/Weikio.PluginFramework.Tests.csproj
@@ -8,7 +8,7 @@
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.*" />
     <PackageReference Include="xunit" Version="2.4.*" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.*" />
-    <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
+    <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
     <PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.2" />
   </ItemGroup>