Created
September 25, 2019 00:39
-
-
Save boggydigital/7d8536e7856a302f773ebdd7786a5a44 to your computer and use it in GitHub Desktop.
DependencyManager sample
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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