這個場景跟《手寫Unity容器--極致簡陋版Unity容器》不同,這裡構造AndroidPhone的時候,AndroidPhone依賴於1個IPad 1、IPhone介面 2、AndroidPhone實現 3、IPad介面 4、IPad實現 5、IHeadPhone介面 6、IHeadPhone實現 ...
這個場景跟《手寫Unity容器--極致簡陋版Unity容器》不同,這裡構造AndroidPhone的時候,AndroidPhone依賴於1個IPad
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();
}
}