這個場景跟《手寫Unity容器--第一層依賴注入》又不同,這里構造AndroidPhone的時候,AndroidPhone依賴于1個IPad,且依賴于1個IHeadPhone,而HeadPhone又依賴于1個IRootPhone


1、IPhone介面
namespace SimplestUnity_nLayer
{
interface IPhone
{
void Call();
}
}
2、AndroidPhone實作
namespace SimplestUnity_nLayer
{
public class AndroidPhone : IPhone
{
public AndroidPhone(IPad iPad, IHeadPhone iHeadPhone)
{
Console.WriteLine("{0}建構式", this.GetType().Name);
}
}
}
3、IPad介面
namespace SimplestUnity_nLayer
{
public interface IPad
{
void Show();
}
}
4、IPad實作
namespace SimplestUnity_nLayer
{
public class AndroidPad:IPad
{
public AndroidPad()
{
Console.WriteLine("{0}建構式", this.GetType().Name);
}
public void Show()
{
Console.WriteLine("看{0}", this.GetType().Name);
}
}
}
5、IHeadPhone介面
namespace SimplestUnity_nLayer
{
public interface IHeadPhone
{
}
}
6、IHeadPhone實作
namespace SimplestUnity_nLayer
{
public class HeadPhone : IHeadPhone
{
public HeadPhone(IRootPhone iRootPhone)
{
Console.WriteLine("Headphone 被構造");
}
}
}
7、IRootPhone介面
namespace SimplestUnity_nLayer
{
public interface IRootPhone
{
}
}
8、IRootPhone實作
namespace SimplestUnity_nLayer
{
public class RootPhone : IRootPhone
{
public RootPhone()
{
Console.WriteLine("RootPhone 被構造");
}
}
}
9、容器--介面
public interface IDavidContainer
{
void RegisterType<TFrom, TTo>();
T Resolve<T>();
}
10、容器--實作
namespace SimplestUnity_nLayer
{
/// <summary>
/// 容器--工廠
/// </summary>
public class DaivdContainer:IDaivdContainer
{
private Dictionary<string, Type> containerDictionary = new Dictionary<string, Type>();//字典
/// <summary>
/// 注冊型別
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTo"></typeparam>
public void RegisterType<TFrom, TTo>()
{
containerDictionary.Add(typeof(TFrom).FullName, typeof(TTo));
}
/// <summary>
/// 獲取實體
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Resolve<T>()
{
Type type = containerDictionary[typeof(T).FullName];
return (T)this.CreateInstance(type);
}
private object CreateInstance(Type type)
{
//1、得到型別的所有建構式
ConstructorInfo[] ctorArray = type.GetConstructors();
//2、只得到有標記DavidInjectionConstructor特性的建構式,如果都沒有標記特性,那么得到引數最多的建構式
ConstructorInfo currentCtor = null;
if (ctorArray.Count(c => c.IsDefined(typeof(DavidInjectionConstructor), true)) > 0)
{
currentCtor = ctorArray.FirstOrDefault(c => c.IsDefined(typeof(DavidInjectionConstructor), true));//得到第1個標記DavidInjectionConstructor特性的建構式
}
else
{
currentCtor = ctorArray.OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();//得到引數個數最多的建構式
}
List<object> paraList = new List<object>();
//遞回:隱形的跳出條件,條件就是GetParameters結果為空,targetType擁有無引數建構式
foreach (var para in currentCtor.GetParameters())
{
//得到的引數型別是IPad,抽象無法創建實體
var paraType = para.ParameterType;
//所以根據IPad Key,得到AndroidPad型別,具體型別就可以創建實體
var targetParaType = containerDictionary[paraType.FullName];
//繼續檢查targetParaType的建構式,不能直接創建實體了
Object obj = this.CreateInstance(targetParaType);
paraList.Add(obj);
}
return Activator.CreateInstance(type, paraList.ToArray());
}
}
}
11、呼叫
class Program
{
static void Main(string[] args)
{
DaivdContainer davidContainer = new DaivdContainer();
davidContainer.RegisterType<IPhone, AndroidPhone>();
davidContainer.RegisterType<IPad, AndroidPad>();
davidContainer.RegisterType<IHeadPhone, HeadPhone>();
davidContainer.RegisterType<IRootPhone, RootPhone>();
IPhone iphone = davidContainer.Resolve<IPhone>();
iphone.Call();
}
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/143945.html
標籤:其他
