翻譯|行業資訊|編輯:龔雪|2022-05-30 10:21:29.753|閱讀 273 次
概述:本文主要介紹WPF MVVM應用程序中的依賴注入并演示如何設置,歡迎下載相關工具體驗~
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
當解決方案的規模和范圍擴大時,保持整體應用程序的靈活性變得更加困難。 對象之間的依賴關系不斷增長,更改一個類可能需要更新其他類,依賴注入 (DI) 可以幫助解決這一挑戰。
如您所知,依賴注入是“控制反轉”(IoC)編程原理的一種形式。 這意味著類不會創建它們所依賴的對象,DI 框架具有負責揭示和解決依賴關系的容器。
假設您有一個使用數據服務獲取數據的視圖模型:
public class UserViewModel { MyDataService dataService; public UserViewModel() { this.dataService = new MyDataService(); } }
視圖模型依賴于一個服務——這意味著 MyDataService 是 UserViewModel 的依賴,直接在視圖模型類中創建服務非常容易,但是這種方法有幾個缺點:
如果將 MyDataService 傳遞給 UserViewModel 的構造函數,則可以避免這些問題:
public class UserViewModel { MyDataService dataService; public UserViewModel(MyDataService dataService) { this.dataService = dataService; } }
不幸的是,這種技術也有缺陷:
依賴注入的主要思想是集中解決所有依賴,這意味著您的程序中有一個單獨的塊來初始化新的類實例并將參數傳遞給它們。 盡管您可以為此實現自己的邏輯,但使用 DI 框架來幫助避免/消除示例代碼會更方便。
依賴注入模式具有以下優點:
.NET 社區有許多很棒的框架來幫助您在應用程序中實現依賴注入模式,所有這些框架都有兩個主要特點:
容器是 DI 框架中的中心對象,可以自動檢測和解決類依賴關系。 某些框架可以將參數注入類屬性,但最常見的方法是將參數注入構造函數。
讓我們修改 MainViewModel 構造函數,使其接受接口替代類:
public class MainViewModel { IDataService dataService; public MainViewModel(IDataService dataService) { this.dataService = dataService; } }
這將允許您在將來使用不同的 IDataService 實現。
進行此更改后,我們需要創建一個 DI 容器來注冊 MyDataService 并實例化 MainViewModel:
protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); var builder = new ContainerBuilder(); //allow the Autofac container resolve unknown types builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); //register the MyDataService class as the IDataService interface in the DI container builder.RegisterType<MyDataService>().As<IDataService>().SingleInstance(); IContainer container = builder.Build(); //get a MainViewModel instance MainViewModel mainViewModel = container.Resolve<MainViewModel>(); }
在此示例中,我們使用了 Autofac 框架,但您可以使用任何其他 DI 框架,例如 Unity 或 Ninject。 DI 容器創建 MainViewModel 并自動將 MyDataService 注入 MainViewModel 構造函數,這允許您在每次創建具有 IDataService 參數類型的類時避免 MyDataService 初始化。
然后我們需要將 MainViewModel 連接到它的視圖:MainView,最明顯的策略是在視圖構造函數中設置 DataContext:
public MainView() { InitializeComponent(); this.DataContext = container.Resolve<MainViewModel>(); }
但是,要訪問 DI 容器,您必須將其設為靜態或將其傳遞給每個視圖構造函數。 一個更好的解決方案是創建一個標記擴展,它根據其類型返回一個視圖模型實例:
public class DISource : MarkupExtension { public static Func<Type, object> Resolver { get; set; } public Type Type { get; set; } public override object ProvideValue(IServiceProvider serviceProvider) => Resolver?.Invoke(Type); }
<UserControl DataContext="{local:DISource Type=local:MainViewModel}">
最初,標記擴展未綁定到任何 DI 容器。 要允許擴展使用您的容器,請按以下方式指定視圖模型解析器:
public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); //... IContainer container = builder.Build(); DISource.Resolver = (type) => { return container.Resolve(type); }; } }
這種技術允許 DISource 與任何可能的容器一起工作。
在上面的示例中,我們使用了不與可視控件通信的抽象數據服務。 如您所知,許多DevExpress WPF服務使用視圖控件,因此服務必須知道使用哪個控件。 例如,如果您希望將 NavigationFrameService 注入到視圖模型中,還需要將此服務附加到相應的 NavigationFrame 控件。
在視圖模型中創建一個包含服務的公共屬性,并將服務綁定到 NavigationFrame:
public class MainViewModel { public INavigationService NavigationService { get; } public MainViewModel(INavigationService navigationService) => NavigationService = navigationService; }
<dxwui:NavigationFrame> <dxmvvm:Interaction.Behaviors> <common:AttachServiceBehavior Service="{Binding NavigationService}"/> </dxmvvm:Interaction.Behaviors> </dxwui:NavigationFrame>
AttachServiceBehavior 是一個簡單的附加操作,它在服務屬性更改時調用 NavigationFrameService.Attach。 雖然 AttachServiceBehavior 不包含在我們的庫中,但您可以在此處獲取其代碼:。即使 MainViewModel 使用 NavigationFrameService,它也不必實現 ISupportServices 接口。 此外,導航中涉及的所有子視圖都可以在不附加到 NavigationFrame 的情況下使用該服務——因為它已經在主視圖級別進行了配置。
并非所有DevExpress 服務都需要可視化組件,某些服務,例如 或 ,不需要顯式附加,因此您可以將它們作為任何其他非 DevExpress 服務注入。
在某些情況下,如果需要為特定視圖配置服務,則使用 DI 容器注入服務可能并不明智。 例如,如果您有一個綁定到視圖模型命令的服務,就會出現這種情況,直接在視圖中定義服務并在那里配置所有綁定要容易得多。
DevExpress WPF擁有120+個控件和庫,將幫助您交付滿足甚至超出企業需求的高性能業務應用程序。通過DevExpress WPF能創建有著強大互動功能的XAML基礎應用程序,這些應用程序專注于當代客戶的需求和構建未來新一代支持觸摸的解決方案。 無論是Office辦公軟件的衍伸產品,還是以數據為中心的商業智能產品,都能通過DevExpress WPF控件來實現。
DevExpress技術交流群6:600715373 歡迎一起進群討論
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:慧都網