Skip to content

Instantly share code, notes, and snippets.

@Hafthor
Created June 17, 2022 01:00
Show Gist options
  • Save Hafthor/39e1c2d7b73b4fe4a3e3a8058ed072d3 to your computer and use it in GitHub Desktop.
Save Hafthor/39e1c2d7b73b4fe4a3e3a8058ed072d3 to your computer and use it in GitHub Desktop.
minimal dependency injector
public class Jab : Attribute {
public T Resolve<T>() where T : class {
return (T)Resolve(typeof(T));
}
public object Resolve(Type typ) {
var typeToInstantiate = (from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsDefined(typeof(Jab), false) && t.IsClass && t.IsPublic && t.GetInterfaces().Contains(typ)
select t).Single();
var defaultConstructor = (from c in typeToInstantiate.GetConstructors().ToList()
where c.IsPublic && c.GetParameters().Length == 0
select c).SingleOrDefault();
var instanceConstructors = from c in typeToInstantiate.GetConstructors().ToList()
where c.IsPublic && c.IsDefined(typeof(Jab), false)
select c as MethodBase;
var staticMethods = from m in typeToInstantiate.GetMethods().ToList()
where m.IsStatic && m.IsPublic && m.IsDefined(typeof(Jab), false) && m.ReturnType == typeToInstantiate
select m as MethodBase;
var factoryMethod = instanceConstructors.Concat(staticMethods).SingleOrDefault() ?? defaultConstructor;
var methodArguments = (from p in factoryMethod.GetParameters().ToList() select Resolve(p.ParameterType)).ToArray();
var obj = factoryMethod is ConstructorInfo ctor ? ctor.Invoke(methodArguments) : factoryMethod.Invoke(null, methodArguments);
var props = from p in obj.GetType().GetProperties()
where p.CanWrite && p.IsDefined(typeof(Jab), false)
select p;
props.ToList().ForEach(p => p.SetMethod.Invoke(obj, new object[] { Resolve(p.PropertyType) }));
var fields = from f in obj.GetType().GetFields()
where f.IsPublic && f.IsDefined(typeof(Jab), false)
select f;
fields.ToList().ForEach(f => f.SetValue(obj, Resolve(f.FieldType)));
return obj;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment