Skip to content

Instantly share code, notes, and snippets.

@Porges
Last active March 23, 2017 03:31
Show Gist options
  • Select an option

  • Save Porges/b7738a632513290b5a42240c14e88ad2 to your computer and use it in GitHub Desktop.

Select an option

Save Porges/b7738a632513290b5a42240c14e88ad2 to your computer and use it in GitHub Desktop.
The only dependency injection framework you'll ever need
using System;
using System.Collections.Generic;
namespace StaticDependencyRegistration
{
public static class Program
{
public static void Main()
{
var rand = Register.PerCaller(() => new Random(Guid.NewGuid().GetHashCode()));
var intBasedRegistrations =
rand.AndPerCaller(_ => _.Get<Random>().Next())
.AndPerCaller(_ => new List<int> { _.Get<int>() })
.AndPerCaller(_ => _.Get<List<int>>().ToArray());
var doubleBasedRegistrations =
rand.AndPerCaller(_ => _.Get<Random>().NextDouble())
.AndSingle(_ => new List<double> { _.Get<double>() })
.AndSingle(_ => _.Get<List<double>>().ToArray());
var registrations = intBasedRegistrations.Combine(doubleBasedRegistrations);
// ints create a new array each time:
Console.WriteLine(string.Join(", ", registrations.Get<int[]>()));
Console.WriteLine(string.Join(", ", registrations.Get<int[]>()));
// doubles create only one array (used "Single" registration):
Console.WriteLine(string.Join(", ", registrations.Get<double[]>()));
Console.WriteLine(string.Join(", ", registrations.Get<double[]>()));
}
}
public static class Register
{
public static InstanceRegistration<T> Instance<T>(T it) => new InstanceRegistration<T>(it);
public static Registration<T> PerCaller<T>(Func<T> f) => new Registration<T>(f);
public static Registration<T> SingleInstance<T>(Func<T> f)
{
var lazy = new Lazy<T>(f);
return new Registration<T>(() => lazy.Value);
}
}
public static class Extensions
{
public static InstanceRegistration<TLeft, TRight> AndInstance<TLeft, TRight>(this TLeft left, TRight right)
=> new InstanceRegistration<TLeft, TRight>(left, right);
public static Registration<TLeft, TRight> AndSingle<TLeft, TRight>(this TLeft left, Func<TLeft, TRight> right)
{
var lazy = new Lazy<TRight>(() => right(left));
return new Registration<TLeft, TRight>(left, () => lazy.Value);
}
public static Registration<TLeft, TRight> AndPerCaller<TLeft, TRight>(this TLeft left, Func<TLeft, TRight> right)
=> new Registration<TLeft, TRight>(left, () => right(left));
public static InstanceRegistration<TLeft, TRight> Combine<TLeft, TRight>(this TLeft left, TRight right) => left.AndInstance(right);
public static T Get<T>(this IGet<T> it) => it.Get;
public static T Get<T>(this IGet<IGet<T>> it) => it.Get.Get();
public static T Get<T>(this IGet<IGet<IGet<T>>> it) => it.Get.Get();
public static T Get<T>(this IGet<IGet<IGet<IGet<T>>>> it) => it.Get.Get();
public static T Get<T>(this IGet<IGet<IGet<IGet<IGet<T>>>>> it) => it.Get.Get();
public static T Get<T>(this IGet<IGet<IGet<IGet<IGet<IGet<T>>>>>> it) => it.Get.Get();
public static T Get<T>(this IGet<IGet<IGet<IGet<IGet<IGet<IGet<T>>>>>>> it) => it.Get.Get();
public static T Get<T>(this IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<T>>>>>>>> it) => it.Get.Get();
public static T Get<T>(this IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<T>>>>>>>>> it) => it.Get.Get();
public static T Get<T>(this IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<T>>>>>>>>>> it) => it.Get.Get();
public static T Get<T>(this IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<T>>>>>>>>>>> it) => it.Get.Get();
public static T Get<T>(this IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<T>>>>>>>>>>>> it) => it.Get.Get();
public static T Get<T>(this IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<T>>>>>>>>>>>>> it) => it.Get.Get();
public static T Get<T>(this IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<T>>>>>>>>>>>>>> it) => it.Get.Get();
public static T Get<T>(this IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<T>>>>>>>>>>>>>>> it) => it.Get.Get();
public static T Get<T>(this IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<T>>>>>>>>>>>>>>>> it) => it.Get.Get();
public static T Get<T>(this IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<IGet<T>>>>>>>>>>>>>>>>> it) => it.Get.Get();
}
public interface IGet<out T>
{
T Get { get; }
}
public class Registration<T> : IGet<T>
{
private readonly Func<T> _factory;
public Registration(Func<T> factory)
{
_factory = factory;
}
T IGet<T>.Get => _factory();
}
public class InstanceRegistration<T> : IGet<T>
{
private readonly T _instance;
public InstanceRegistration(T instance)
{
_instance = instance;
}
T IGet<T>.Get => _instance;
}
public class InstanceRegistration<TLeft, TRight> : InstanceRegistration<TLeft>, IGet<TRight>
{
private readonly TRight _right;
public InstanceRegistration(TLeft left, TRight right) : base(left)
{
_right = right;
}
TRight IGet<TRight>.Get => _right;
}
public class Registration<TLeft, TRight> : InstanceRegistration<TLeft>, IGet<TRight>
{
private readonly Func<TRight> _right;
public Registration(TLeft left, Func<TRight> right) : base(left)
{
_right = right;
}
TRight IGet<TRight>.Get => _right();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment