Skip to content

Instantly share code, notes, and snippets.

@vtml
Created March 19, 2019 10:25
Show Gist options
  • Save vtml/e544a808eac716502e7cb544b50be3d0 to your computer and use it in GitHub Desktop.
Save vtml/e544a808eac716502e7cb544b50be3d0 to your computer and use it in GitHub Desktop.
Sitecore Super Power Friendly Dependency Injection
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Http.Controllers;
using System.Web.Mvc;
using Isobar.Foundation.SitecoreUtilities.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Isobar.Foundation.DependencyInjection
{
public static class ServiceCollectionExtensions
{
private const string DefaultControllerFilter = "*Controller";
public static void AddClassesWithServiceAttribute(this IServiceCollection serviceCollection, IReflectionExtensions reflectionExtensions)
{
serviceCollection.AddClassesWithServiceAttribute(reflectionExtensions, Assembly.GetCallingAssembly());
}
public static void AddClassesWithServiceAttribute(this IServiceCollection serviceCollection, IReflectionExtensions reflectionExtensions, params string[] assemblyFilters)
{
var assemblies = reflectionExtensions.GetAssemblies(assemblyFilters);
serviceCollection.AddClassesWithServiceAttribute(reflectionExtensions, assemblies);
}
public static void AddClassesWithServiceAttribute(this IServiceCollection serviceCollection, IReflectionExtensions reflectionExtensions, params Assembly[] assemblies)
{
var typesWithAttributes = assemblies
.Where(assembly => !assembly.IsDynamic)
.SelectMany(reflectionExtensions.GetExportedTypes)
.Where(type => !type.IsAbstract && !type.IsGenericTypeDefinition)
.Select(type => new { type.GetCustomAttribute<ServiceAttribute>()?.Lifetime, ServiceType = type, ImplementationType = type.GetCustomAttribute<ServiceAttribute>()?.ServiceType })
.Where(t => t.Lifetime != null);
foreach (var type in typesWithAttributes)
{
if (type.ImplementationType == null)
serviceCollection.TryAdd(type.ServiceType, type.Lifetime.Value);
else
serviceCollection.TryAdd(type.ImplementationType, type.ServiceType, type.Lifetime.Value);
}
}
public static void AddClassesWithDefaultInterface(this IServiceCollection serviceCollection, IReflectionExtensions reflectionExtensions, params string[] assemblyFilters)
{
var assemblies = reflectionExtensions.GetAssemblies(assemblyFilters);
serviceCollection.AddClassesWithDefaultInterface(reflectionExtensions, assemblies);
}
public static void AddClassesWithDefaultInterface(this IServiceCollection serviceCollection, IReflectionExtensions reflectionExtensions, params Assembly[] assemblies)
{
var typesWithDefaultInterface = assemblies
.Where(assembly => !assembly.IsDynamic)
.SelectMany(reflectionExtensions.GetExportedTypes)
.Where(reflectionExtensions.IsRealClass);
foreach (var type in typesWithDefaultInterface)
{
var defaultInterface = reflectionExtensions.GetDefaultImplementedInterface(type);
if (defaultInterface != null)
serviceCollection.TryAddTransient(defaultInterface, type);
}
}
public static void AddByWildcard(this IServiceCollection serviceCollection, Lifetime lifetime, string classFilter, IReflectionExtensions reflectionExtensions, params Assembly[] assemblies)
{
if (assemblies == null || !assemblies.Any())
assemblies = new[] { Assembly.GetCallingAssembly() };
var types = reflectionExtensions.GetTypesImplementing(typeof(object), assemblies, classFilter);
serviceCollection.TryAdd(lifetime, types.ToArray());
}
public static void TryAdd(this IServiceCollection serviceCollection, Lifetime lifetime, params Type[] types)
{
foreach (var type in types)
{
serviceCollection.TryAdd(type, lifetime);
}
}
public static void TryAdd<T>(this IServiceCollection serviceCollection, Lifetime lifetime)
{
serviceCollection.TryAdd(typeof(T), lifetime);
}
public static void TryAdd(this IServiceCollection serviceCollection, Type type, Lifetime lifetime)
{
switch (lifetime)
{
case Lifetime.Singleton:
serviceCollection.TryAddSingleton(type);
break;
case Lifetime.Transient:
serviceCollection.TryAddTransient(type);
break;
default:
throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null);
}
}
public static void TryAdd(this IServiceCollection serviceCollection, Type serviceType, Type implementationType, Lifetime lifetime)
{
switch (lifetime)
{
case Lifetime.Singleton:
serviceCollection.TryAddSingleton(serviceType, implementationType);
break;
case Lifetime.Transient:
serviceCollection.TryAddTransient(serviceType, implementationType);
break;
default:
throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null);
}
}
public static void AddTypesImplementingInCurrentAssembly<T>(this IServiceCollection serviceCollection, Lifetime lifetime, IReflectionExtensions reflectionExtensions)
{
var types = reflectionExtensions.GetTypesImplementing(typeof(T), Assembly.GetCallingAssembly());
serviceCollection.TryAdd(lifetime, types.ToArray());
}
public static void AddTypesImplementing<T>(this IServiceCollection servicecollection, Lifetime lifetime, IReflectionExtensions reflectionExtensions, params string[] assemblies)
{
servicecollection.AddTypesImplementing<T>(lifetime, reflectionExtensions, reflectionExtensions.GetAssemblies(assemblies));
}
public static void AddTypesImplementing<T>(this IServiceCollection serviceCollection, Lifetime lifetime, IReflectionExtensions reflectionExtensions, params Assembly[] assemblies)
{
var types = reflectionExtensions.GetTypesImplementing(typeof(T), assemblies);
serviceCollection.TryAdd(lifetime, types.ToArray());
}
public static void AddMvcControllersInCurrentAssembly(this IServiceCollection serviceCollection, IReflectionExtensions reflectionExtensions, params string[] classFilters)
{
AddMvcControllers(serviceCollection, reflectionExtensions, Assembly.GetCallingAssembly());
}
public static void AddMvcControllers(this IServiceCollection serviceCollection, IReflectionExtensions reflectionExtensions, params string[] assemblyFilters)
{
serviceCollection.AddMvcControllers(reflectionExtensions, reflectionExtensions.GetAssemblies(assemblyFilters));
}
public static void AddMvcControllers(this IServiceCollection serviceCollection, IReflectionExtensions reflectionExtensions, params Assembly[] assemblies)
{
serviceCollection.AddMvcControllers(reflectionExtensions, assemblies, new[] { DefaultControllerFilter });
}
public static void AddMvcControllers(this IServiceCollection serviceCollection, IReflectionExtensions reflectionExtensions, string[] assemblyFilters, params string[] classFilters)
{
serviceCollection.AddMvcControllers(reflectionExtensions, reflectionExtensions.GetAssemblies(assemblyFilters), classFilters);
}
private static void AddMvcControllers(this IServiceCollection serviceCollection, IReflectionExtensions reflectionExtensions, IEnumerable<Assembly> assemblies, string[] classFilters)
{
var assemblyList = assemblies as IList<Assembly> ?? assemblies.ToList();
var controllers = reflectionExtensions.GetTypesImplementing(typeof(IController), assemblyList, classFilters);
foreach (var controller in controllers)
{
serviceCollection.TryAddTransient(controller);
}
var apiControllers = reflectionExtensions.GetTypesImplementing(typeof(IHttpController), assemblyList, classFilters);
foreach (var apiController in apiControllers)
{
serviceCollection.TryAddTransient(apiController);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment