Skip to content

Instantly share code, notes, and snippets.

@boggydigital
Created September 25, 2019 00:39
Show Gist options
  • Save boggydigital/7d8536e7856a302f773ebdd7786a5a44 to your computer and use it in GitHub Desktop.
Save boggydigital/7d8536e7856a302f773ebdd7786a5a44 to your computer and use it in GitHub Desktop.
DependencyManager sample
using System;
namespace DI
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class DependsOnInstancesAttribute : Attribute
{
public DependsOnInstancesAttribute(params Type[] instanceTypes)
{
InstanceTypes = instanceTypes;
}
public Type[] InstanceTypes { get; private set; }
}
public interface IPrintDelegate
{
void Print(string text);
}
public interface IInvokeDelegate
{
void Invoke();
}
public class TestClass1 : IPrintDelegate
{
public void Print(string text)
{
Console.WriteLine($"{text}");
}
}
[DependsOnInstances(typeof(TestClass1))]
public class TestClass2 : IInvokeDelegate
{
private IPrintDelegate printDelegate;
public TestClass2(IPrintDelegate printDelegate)
{
this.printDelegate = printDelegate;
}
public void Invoke()
{
printDelegate.Print("Hello world!");
}
}
public interface IGetUntypedInstanceDelegate
{
object GetUntypedInstance(Type type);
}
public interface IGetTypedInstanceDelegate
{
T GetTypedInstance<T>(Type type) where T: class;
}
public class DependencyManager: IGetUntypedInstanceDelegate, IGetTypedInstanceDelegate
{
public object GetUntypedInstance(Type type)
{
var dependsOnInstancesAttribute = Attribute.GetCustomAttribute(
type,
typeof(DependsOnInstancesAttribute))
as DependsOnInstancesAttribute;
if (dependsOnInstancesAttribute == null)
{
var defaultConstructor = type.GetConstructor(Type.EmptyTypes)!;
if (defaultConstructor != null)
return defaultConstructor.Invoke(null);
throw new ArgumentException($"Type {type.Name} doesn't contain an accessible default constructor");
}
else
{
var instanceTypes = dependsOnInstancesAttribute.InstanceTypes;
var constructor = type.GetConstructor(instanceTypes);
if (constructor == null)
throw new ArgumentException($"Type {type.Name} doesn't contain an accessible constructor accepting instance types: {string.Join(',', dependsOnInstancesAttribute.InstanceTypes as object[])}");
object[] dependencies = new object[instanceTypes.Length];
for (var ii = 0; ii < dependencies.Length; ii++)
dependencies[ii] = GetUntypedInstance(instanceTypes[ii]);
return constructor.Invoke(dependencies);
}
}
public T GetTypedInstance<T>(Type type) where T: class
{
return GetUntypedInstance(type) as T;
}
}
class Program
{
static void Main(string[] args)
{
var dependencyManager = new DependencyManager();
var invokeDelegate = dependencyManager.GetTypedInstance<IInvokeDelegate>(
typeof(TestClass2));
invokeDelegate.Invoke();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment