So playing with my own test Dependency Injector class. (yeah tons out there but this is just for fun)
Works decent but I don't know how to get the correct constructor based on the Interface passed in.
internal class DiContainer
{
private readonly Dictionary<Type, RegistryRecord> registry = new Dictionary<Type, RegistryRecord>();
private static DiContainer instance;
private DiContainer()
{
}
public static DiContainer GetInstance()
{
return instance ??= new DiContainer();
}
public void Register<T, C>() where C : class, T
{
registry.Add(typeof(T), new RegistryRecord
{
InterfaceType = typeof(T),
ConcreteType = typeof(C),
IsSingleTon = false
});
}
public void Register<C>() where C : class
{
Register(typeof(C));
}
public void Register(Type t)
{
registry.Add(t, new RegistryRecord
{
InterfaceType = t,
ConcreteType = t,
IsSingleTon = false
});
}
public void RegisterSingleton<T, C>(C instance = null) where C : class, T
{
registry.Add(typeof(T), new RegistryRecord
{
InterfaceType = typeof(T),
ConcreteType = typeof(C),
IsSingleTon = true,
Instance = instance
});
}
public T Get<T>()
{
return (T) Get(typeof(T));
}
public object Get(Type t)
{
ConstructorInfo constructor;
RegistryRecord r = null;
if (t.IsInterface && registry.ContainsKey(t))
{
r = registry[t];
if (r.IsSingleTon && r.Instance != null) return r.Instance;
constructor = r.ConcreteType.GetConstructors(BindingFlags.Instance | BindingFlags.Public)[0];
}
else
{
//todo how do we select the correct constructor?
constructor = t.GetConstructors(BindingFlags.Instance | BindingFlags.Public)[0];
}
var parameters = constructor.GetParameters();
//recurse to build dependency chain
var objects = parameters.Select(parameter => Get(parameter.ParameterType)).ToList();
var obj = constructor.Invoke(objects.ToArray());
if (r != null && r.IsSingleTon)
{
r.Instance = obj;
}
return obj;
}
}
internal class RegistryRecord
{
public Type InterfaceType { get; set; }
public Type ConcreteType { get; set; }
public object Instance { get; set; }
public bool IsSingleTon { get; set; }
}
So the problem is:
constructor = t.GetConstructors(BindingFlags.Instance | BindingFlags.Public)[0];
I am just assuming the first constructor which is awful. But I have the definition of the interface I could be using.
How do I get the parameters of my interface and check them against the constructor?
Would like to select a constructor that matches the interface, or at least partially matches optimally.
Aucun commentaire:
Enregistrer un commentaire