我們在第三篇中學習里一個簡易的IoC框架。今天我們接著上次的程序,實現帶參數構造函數對象的實例和屬性的注入 。
我們知道可以通過反射獲取類的構造函數及參數(GetConstructors方法);可以獲取屬性和屬性的類型(GetProperties方法)。通過Activator的CreateInstance(Type type, params object[] args)方法可以創建帶參數構造函數的實例。通過SetValue方法可以給屬性賦值,這樣一來,我們就上次的代碼稍加改造就可以實現屬性的注入了。
下面是完成的代碼:

Domain
????public?class?Person

????
{

????????public?string?Name?
{?get;?set;?}

????????public?int?Age?
{?get;?set;?}
????}

???public?class?PersonDao

????
{
????????private?int?intProp;

????????public?PersonDao(int?intProp)

????????
{
????????????this.intProp?=?intProp;
????????}


????????public?Person?Entity?
{?get;?set;?}

????????public?override?string?ToString()

????????
{
????????????return?"構造函數參數intProp為:"?+?this.intProp;
????????}
????}?

ObjectFactory
public?class?ObjectFactory

????
{
????????private?IDictionary<string,?object>?objectDefine?=?new?Dictionary<string,?object>();

????????private?ObjectFactory(string?fileName)

????????
{
????????????InstanceObjects(fileName);??//?實例IoC容器
????????????DiObjects(fileName);??//?屬性注入
????????}

????????private?static?ObjectFactory?instance;

????????private?static?object?lockHelper?=?new?object();

????????public?static?ObjectFactory?Instance(string?fileName)

????????
{
????????????if?(instance?==?null)

????????????
{
????????????????lock?(lockHelper)

????????????????
{
????????????????????instance?=?instance????new?ObjectFactory(fileName);
????????????????}
????????????}
????????????return?instance;
????????}


????????/**////?<summary>
????????///?實例IoC容器
????????///?</summary>
????????///?<param?name="fileName"></param>
????????private?void?InstanceObjects(string?fileName)

????????
{
????????????XElement?root?=?XElement.Load(fileName);
????????????var?objects?=?from?obj?in?root.Elements("object")
??????????????????????????select?obj;

????????????//無參構造函數
????????????objectDefine?=?objects.Where(obj?=>
????????????????obj.Element("constructor-arg")?==?null).ToDictionary(
????????????????????k?=>?k.Attribute("id").Value,?
????????????????????v?=>?

????????????????????
{
????????????????????????string?typeName?=?v.Attribute("type").Value;??
????????????????????????Type?type?=?Type.GetType(typeName);??
????????????????????????return?Activator.CreateInstance(type);
????????????????????}
????????????????);

????????????//有參構造函數
????????????foreach?(XElement?item?in?objects.Where(obj?=>?
????????????????obj.Element("constructor-arg")?!=?null))

????????????
{??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
????????????????string?id?=?item.Attribute("id").Value;
????????????????string?typeName?=?item.Attribute("type").Value;
????????????????Type?type?=?Type.GetType(typeName);
????????????????var?args?=?from?property?in?type.GetConstructors()[0].GetParameters()
???????????????????????????join?el?in?item.Elements("constructor-arg")
???????????????????????????on?property.Name?equals?el.Attribute("name").Value
???????????????????????????select?Convert.ChangeType(el.Attribute("value").Value,
???????????????????????????property.ParameterType);
????????????????object?obj?=?Activator.CreateInstance(type,?args.ToArray());
????????????????objectDefine.Add(id,?obj);
????????????}
????????}


????????/**////?<summary>
????????///?屬性注入
????????///?</summary>
????????///?<param?name="fileName"></param>
????????private?void?DiObjects(string?fileName)

????????
{
????????????XElement?root?=?XElement.Load(fileName);
????????????var?objects?=?from?obj?in?root.Elements("object")
??????????????????????????select?obj;

????????????foreach?(KeyValuePair<string,object>?item?in?objectDefine)

????????????
{
????????????????foreach?(var?el?in?objects.Where(e?=>?
????????????????????e.Attribute("id").Value?==?item.Key).Elements("property"))

????????????????
{
????????????????????Type?type?=?item.Value.GetType();
????????????????????//獲取屬性
????????????????????foreach?(PropertyInfo?property?in?type.GetProperties())

????????????????????
{
????????????????????????if?(property.Name?==?el.Attribute("name").Value)

????????????????????????
{
????????????????????????????if?(el.Attribute("value")?!=?null)

????????????????????????????
{
????????????????????????????????//設置屬性值
????????????????????????????????property.SetValue(item.Value,?
????????????????????????????????????Convert.ChangeType(el.Attribute("value").Value,?
????????????????????????????????????property.PropertyType),?null);
????????????????????????????}
????????????????????????????else?if?(el.Attribute("ref")?!=?null)

????????????????????????????
{
????????????????????????????????object?refObject?=?null;

????????????????????????????????if?(objectDefine.ContainsKey(el.Attribute("ref").Value))

????????????????????????????????
{
????????????????????????????????????refObject?=?objectDefine[el.Attribute("ref").Value];
????????????????????????????????}
????????????????????????????????//設置關聯對象屬性
????????????????????????????????property.SetValue(item.Value,?refObject,?null);
????????????????????????????}
????????????????????????}
????????????????????}
????????????????}
????????????}
????????}


????????/**////?<summary>
????????///?獲取對象
????????///?</summary>
????????///?<param?name="id"></param>
????????///?<returns></returns>
????????public?object?GetObject(string?id)

????????
{
????????????object?result?=?null;

????????????if?(objectDefine.ContainsKey(id))

????????????
{
????????????????result?=?objectDefine[id];
????????????}

????????????return?result;
????????}
????} ?

App.config
<?xml?version="1.0"?encoding="utf-8"??>
<objects>
??<object?id="person"?type="SpringNetMyDi.Person,?SpringNetMyDi">
????<!--屬性值類型注入-->
????<property?name="Name"?value="Liu?Dong"/>
????<property?name="Age"?value="27"/>
??</object>
??<object?id="personDao"?type="SpringNetMyDi.PersonDao,?SpringNetMyDi">
????<!--構造器注入-->
????<constructor-arg?name="intProp"?value="1"/>
????<property?name="Entity"?ref="person"?/>
????
??</object>
</objects> ?

Program
???class?Program

????
{
????????static?void?Main(string[]?args)

????????
{
????????????ObjectFactory?factory?=?ObjectFactory.Instance(@"F:\Exercise\SpringNet\Step1\SpringNet_Lesson9\SpringNetMyDi\Objects.xml");

????????????PersonDao?dao?=?(PersonDao)factory.GetObject("personDao");

????????????Console.WriteLine("姓名:"?+?dao.Entity.Name);
????????????Console.WriteLine("年齡:"?+?dao.Entity.Age);
????????????Console.WriteLine(dao);

????????????Console.ReadLine();
????????}
????} ?
?輸入結果:

?
?
?
?
?代碼下載
?
?
返回目錄