Last active
March 24, 2019 19:42
-
-
Save natenho/3d7a8193ae1c5782e244e9fddb6f5949 to your computer and use it in GitHub Desktop.
Integrating MEF with DependencyInjection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Taken from https://weblogs.asp.net/ricardoperes/integrating-managed-extensibility-framework-with-the-net-service-provider | |
// Other interesting links: | |
// https://weblogs.asp.net/ricardoperes/dynamically-loading-middleware-in-asp-net-core | |
// https://weblogs.asp.net/ricardoperes/using-mef-in-net-core | |
public static class ContainerConfigurationExtensions | |
{ | |
public static ContainerConfiguration WithAssembliesInPath(this ContainerConfiguration configuration, string path, SearchOption searchOption = SearchOption.TopDirectoryOnly) | |
{ | |
return WithAssembliesInPath(configuration, path, null, searchOption); | |
} | |
public static ContainerConfiguration WithAssembliesInPath(this ContainerConfiguration configuration, string path, AttributedModelProvider conventions, SearchOption searchOption = SearchOption.TopDirectoryOnly) | |
{ | |
var assemblyFiles = Directory.GetFiles(path, "*.dll", searchOption); | |
var assemblies = assemblyFiles.Select(AssemblyLoadContext.Default.LoadFromAssemblyPath); | |
configuration = configuration.WithAssemblies(assemblies, conventions); | |
return configuration; | |
} | |
} | |
public static class ServiceCollectionExtensions | |
{ | |
public static IServiceCollection AddFromAssembliesInPath<T>(this IServiceCollection services, ServiceLifetime lifetime, string path = null)where T : class | |
{ | |
var factory = new ExportFactory<T, object>(() => new Tuple<T, Action>(Activator.CreateInstance<T>(), () => | |
{ | |
} | |
), new object ()); | |
var conventions = new ConventionBuilder(); | |
var builder = conventions.ForTypesDerivedFrom<T>().Export<T>(); | |
if (lifetime == ServiceLifetime.Singleton) | |
{ | |
builder = builder.Shared(); | |
} | |
path = path ?? AppContext.BaseDirectory; | |
var configuration = new ContainerConfiguration().WithAssembliesInPath(path, conventions); | |
using (var container = configuration.CreateContainer()) | |
{ | |
var svcs = container.GetExports<Lazy<T>>(); | |
foreach (var svc in svcs) | |
{ | |
services.Add(new ServiceDescriptor(typeof (T), sp => svc.Value, lifetime)); | |
} | |
} | |
return services; | |
} | |
public static IServiceCollection AddSingletonFromAssembliesInPath<T>(this IServiceCollection services, string path = null)where T : class | |
{ | |
return AddFromAssembliesInPath<T>(services, ServiceLifetime.Singleton, path); | |
} | |
public static IServiceCollection AddScopedFromAssembliesInPath<T>(this IServiceCollection services, string path = null)where T : class | |
{ | |
return AddFromAssembliesInPath<T>(services, ServiceLifetime.Scoped, path); | |
} | |
public static IServiceCollection AddTransientFromAssembliesInPath<T>(this IServiceCollection services, string path = null)where T : class | |
{ | |
return AddFromAssembliesInPath<T>(services, ServiceLifetime.Transient, path); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment