本文未經作者許可,不得轉載引用,若需引用,請務必通過郵件方式聯系作者,聯系郵箱 xuanzhaopeng#gmail.com
在進行windows桌面應用程序或windows phone app開發的過程中,我們將會使用WPF.NET ,而他的亮點在於將界面的設計和軟件的邏輯完全的分開,所有的數據進行綁定,所有的命令也同樣綁定,這裡不再冗余描述如何綁定變量和命令,而著重講在綁定數據後,後端邏輯中的數據也通過依賴注入的方式進行設計,這麼做的原因在於,我們的app使用的數據可能來自於webservice,譬如手機應用,我們不可能在手機中存儲龐大的數據庫,而是通過webservice來獲取和更新數據,因此,如果我們仍然主動監控數據,這就意味著數據的更新是被動的,必須讓用戶觸發,觸發後將獲得的數據設置到頁面綁定的變量上,而如果是一個實時系統,你怎麼做呢? 只能利用依賴注入,並且依賴注入能讓你的系統更加模塊化。 因此我舉一個例子給大家看。
我們現在有一個ViewModel要初始化
[csharp] [AppViewModel]
class ClockViewModel
{
public ClockViewModel(IServices Services)
{
}
}
[AppViewModel]
class ClockViewModel
{
public ClockViewModel(IServices Services)
{
}
}
這個viewmodel存放在一個dll中,我們現在要動態加載這個類,當然此時必須用Assembly和Attribute
[csharp] private Type GetClassByAttribute(Type attributeType)
{
Assembly assembly = this.GetType().Assembly;
var types = assembly.GetTypes().Where(t => Attribute.IsDefined(t, attributeType)).ToList();
return types.First();
}
private Type GetClassByAttribute(Type attributeType)
{
Assembly assembly = this.GetType().Assembly;
var types = assembly.GetTypes().Where(t => Attribute.IsDefined(t, attributeType)).ToList();
return types.First();
}
通過GetClassByAttribute函數,傳入參數為AppViewModel的類型, 我們就可以得到ClockViewModel的Type
現在我們要在依賴注入中注冊這個Type
[csharp] ype ViewModelType = this.GetClassByAttribute(typeof(AppViewModelAttribute));
this.IoCContainer.RegisterType(ViewModelType);
Type ViewModelType = this.GetClassByAttribute(typeof(AppViewModelAttribute));
this.IoCContainer.RegisterType(ViewModelType);
;
此時,我們通過Assembly只得到了ViewModel的類型,而不是實例化的對象,現在的目標是要初始化這個實例對象
因此我們要利用以下方式得到實例化對象
[csharp] this.ViewModel = this.IoCContainer.Resolve(ViewModelType);
this.ViewModel = this.IoCContainer.Resolve(ViewModelType);
大功告成,我們通過Resolve方法,傳入類型,就可以得到這個對象了,此時回顧前面的所有步驟,基本不存在在一層套一層實例化的冗余!
但是!!! 還沒有結束,可能有些朋友會問,在ViewModel的構造函數中,其中必須傳入一個參數類型為IService接口的對象,但我們根本沒處理過這個對象,所以在我們執行上一行代碼之前,必須先初始化這些接口對象!!
[csharp] this.IoCContainer.RegisterType<IDataStreamingChannelFactory, DataStreamingChannelFactory>();
this.IoCContainer.RegisterType<IStreamingDataProvider, StreamingDataProvider>();
this.IoCContainer.RegisterType<IServices, ServiceRoot>();
this.IoCContainer.RegisterType<IDataStreamingChannelFactory, DataStreamingChannelFactory>();
this.IoCContainer.RegisterType<IStreamingDataProvider, StreamingDataProvider>();
this.IoCContainer.RegisterType<IServices, ServiceRoot>();
我們這裡看一下 ServiceRoot 的構造函數,
[csharp] internal class ServiceRoot : IServices, IDataServices, IInfraServices
{
public ServiceRoot(IIoCContainer ioc, IDataStreamingChannelFactory channelFactory, IStreamingDataProvider streamingProvider)
{
}
}
internal class ServiceRoot : IServices, IDataServices, IInfraServices
{
public ServiceRoot(IIoCContainer ioc, IDataStreamingChannelFactory channelFactory, IStreamingDataProvider streamingProvider)
{
}
}
他的構造函數中,用到了IDataStreamingChannelFactory和IStreamingDataProvider,所以我們在注冊IService之前,就應該把這兩個也注冊了
到此時,所有的步驟結束,完成了一個0耦合的對象實例化的過程。