Skip to content

Instantly share code, notes, and snippets.

@natenho
Last active March 24, 2019 19:42
Show Gist options
  • Save natenho/3d7a8193ae1c5782e244e9fddb6f5949 to your computer and use it in GitHub Desktop.
Save natenho/3d7a8193ae1c5782e244e9fddb6f5949 to your computer and use it in GitHub Desktop.
Integrating MEF with DependencyInjection
// 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