-
[DX_WPF] Dynamic Load Modules In DevExpress MVVM For WPFDevExpress/DX_WPF 2023. 11. 23. 11:07
방식 1.
Libaray Nuget Package
https://github.com/dlsenfl3/DXDynamicModule
Nuget 추가.
사용.
https://github.com/dlsenfl3/DXModularWithDynamic
App.xaml.cs
Project Module
ViewModelSource 나 ViewModelBase 둘중 하나만 사용. (같은 거)
ViewModelSource and ViewModelBase are interchangeable solutions that should not be used together.
Understanding POCOViewModel / ViewModelBase with ViewModelSource.Create()
You have yet to view any tickets. Your search criteria do not match any tickets. A server error occurred while processing your request. Please try again at a later time.
supportcenter.devexpress.com
View
주석 처리된 부분 풀리면 생성자 2번 불림.
ViewModelSource 사용 시
선언 안해도 (new Module 할 때 뷰 지정해줘서?!)실질적으로 바인딩되어 사용가능?
ModuleDViewModel.Create 사용해야
this.RaisePropertiesChanged();
Raise~ 사용가능.
ViewModelBase 사용시
둘 다 사용가능?!
DevExpress MVVM Framework. Interaction of ViewModels. IDocumentManagerService.
OTHER RELATED ARTICLES: Getting Started with DevExpress MVVM Framework. Commands and View Models.DevExpress MVVM Framework. Introduction to Services, DXMessageBoxService and DialogService.THIS POST: DevExpress MVVM Framework. Interaction of ViewModels. ID
community.devexpress.com
Service 등록/사용
DevExpress MVVM Framework. Introduction to POCO ViewModels.
OTHER RELATED ARTICLES: Getting Started with DevExpress MVVM Framework. Commands and View Models.DevExpress MVVM Framework. Introduction to Services, DXMessageBoxService and DialogService.DevExpress MVVM Framework. Interaction of ViewModels. IDocumentManag
community.devexpress.com
방식2.
module Dynamic load
App.xaml.cs0.01MBMainViewModel.cs0.00MBModuleViewModel.cs0.00MB런타임시 모듈 동적 로드
App.xaml.cs
using System; using DevExpress.Mvvm; using DevExpress.Mvvm.ModuleInjection; using DevExpress.Mvvm.UI; using DevExpress.Xpf.Core; using DXApplication1.Common; using DXApplication1.Main.Properties; using DXApplication1.Main.ViewModels; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Reflection; using System.Windows; using AppModules = DXApplication1.Common.Modules; using DevExpress.Data.Utils; using DXApplication1.Main.Views; namespace DXApplication1.Main { public partial class App : Application { public App() { ApplicationThemeHelper.UpdateApplicationThemeName(); SplashScreenManager.CreateThemed().ShowOnStartup(); } protected override void OnExit(ExitEventArgs e) { ApplicationThemeHelper.SaveApplicationThemeName(); base.OnExit(e); } void OnApplicationStartup(object sender, StartupEventArgs e) { Bootstrapper.Run(); } } public class Bootstrapper { private List<Assembly> assemblies = new List<Assembly>(); private List<string> keyNames = new List<string>(); public List<DevExpress.Mvvm.ModuleInjection.Module> modules = new List<DevExpress.Mvvm.ModuleInjection.Module>(); public static Bootstrapper Default { get; protected set; } public static void Run() { Default = new Bootstrapper(); Default.RunCore(); } protected Bootstrapper() { } const string StateVersion = "1.0"; public virtual void RunCore() { ConfigureTypeLocators(); RegisterModules(); if (!RestoreState()) InjectModules(); ConfigureNavigation(); ShowMainWindow(); } protected IModuleManager Manager { get { return ModuleManager.DefaultManager; } } protected virtual void ConfigureTypeLocators() { assemblies.Add(typeof(MainViewModel).Assembly); //var mainAssembly = typeof(MainViewModel).Assembly; //var modulesAssembly = typeof(ModuleViewModel).Assembly; //var assemblies = new[] { mainAssembly, modulesAssembly }; //ViewModelLocator.Default = new ViewModelLocator(assemblies); //ViewLocator.Default = new ViewLocator(assemblies); } protected virtual void RegisterModules() { Manager.GetRegion(Regions.Documents).VisualSerializationMode = VisualSerializationMode.PerKey; Manager.Register(Regions.MainWindow, new DevExpress.Mvvm.ModuleInjection.Module(AppModules.Main, ()=>MainViewModel.Create(), typeof(MainView))); // First, find all modules var foundModules = Directory.EnumerateFiles(System.Environment.CurrentDirectory, "*.Modules.dll", SearchOption.AllDirectories); if (foundModules.Count() == 0) return; foreach (var item in foundModules) { var asm = Assembly.LoadFrom(item); foreach (Type type in asm.GetTypes()) { MethodInfo info = type.GetMethod("Create"); if (info == null) continue; assemblies.Add(asm); string keyField = (string)type.GetProperty("Key").GetValue(type); // returns ModuleViewModel string viewName = (string)type.GetProperty("ViewName").GetValue(type); // returns ModuleView keyNames.Add(keyField); var module = new DevExpress.Mvvm.ModuleInjection.Module(keyField, () => info.Invoke(null, new object[] {$"{keyField}Module" }), viewName); modules.Add(module); } } // Update view locator(s) ViewModelLocator.Default = new ViewModelLocator(assemblies); ViewLocator.Default = new ViewLocator(assemblies); // Register all modules modules.ForEach(module => Manager.Register(Regions.Documents, module)); modules.ForEach(module => Manager.Register(Regions.Navigation, module)); //if(keyNames.Where(key => key == "ModuleViewModel").Any()) //{ //} //Manager.Register(Regions.Navigation, new DevExpress.Mvvm.ModuleInjection.Module(keyNames.Where(key => key == "ModuleViewModel").FirstOrDefault(), () => new NavigationItem("Module1"))); //Manager.Register(Regions.Navigation, new DevExpress.Mvvm.ModuleInjection.Module(AppModules.Module1, () => new NavigationItem("Module1"))); //Manager.Register(Regions.Navigation, new DevExpress.Mvvm.ModuleInjection.Module(AppModules.Module2, () => new NavigationItem("Module2"))); //Manager.Register(Regions.Documents, new Module(AppModules.Module1, () => ModuleViewModel.Create("Module1"), typeof(ModuleView))); //Manager.Register(Regions.Documents, new Module(AppModules.Module2, () => ModuleViewModel.Create("Module2"), typeof(ModuleView))); } protected virtual bool RestoreState() { #if !DEBUG if (Settings.Default.StateVersion != StateVersion) return false; return Manager.Restore(Settings.Default.LogicalState, Settings.Default.VisualState); #else return false; #endif } protected virtual void InjectModules() { Manager.Inject(Regions.MainWindow, AppModules.Main); keyNames.ForEach(key => Manager.Inject(Regions.Navigation, key)); // key = ModuleViewModel //Manager.Inject(Regions.Navigation, keyNames.Where(key => key == "ModuleViewModel").FirstOrDefault()); //Manager.Inject(Regions.Navigation, keyNames.Where(key => key == "ModuleViewModel").FirstOrDefault()); //Manager.Inject(Regions.Navigation, AppModules.Module1); //Manager.Inject(Regions.Navigation, AppModules.Module2); } protected virtual void ConfigureNavigation() { Manager.GetEvents(Regions.Navigation).Navigation += OnNavigation; Manager.GetEvents(Regions.Documents).Navigation += OnDocumentsNavigation; } protected virtual void ShowMainWindow() { App.Current.MainWindow = new MainWindow(); App.Current.MainWindow.Show(); App.Current.MainWindow.Closing += OnClosing; } void OnNavigation(object sender, NavigationEventArgs e) { if (e.NewViewModelKey == null) return; Manager.InjectOrNavigate(Regions.Documents, e.NewViewModelKey); } void OnDocumentsNavigation(object sender, NavigationEventArgs e) { Manager.Navigate(Regions.Navigation, e.NewViewModelKey); } void OnClosing(object sender, CancelEventArgs e) { string logicalState; string visualState; Manager.Save(out logicalState, out visualState); Settings.Default.StateVersion = StateVersion; Settings.Default.LogicalState = logicalState; Settings.Default.VisualState = visualState; Settings.Default.Save(); } } }
MainViewModel.cs
using System; using System.Collections.Generic; using System.Linq; using DevExpress.Mvvm; using DevExpress.Mvvm.ModuleInjection; using DevExpress.Mvvm.POCO; using DXApplication1.Common; namespace DXApplication1.Main.ViewModels { public class MainViewModel { protected IModuleManager Manager { get { return ModuleManager.DefaultManager; } } //private List<DevExpress.Mvvm.ModuleInjection.Module> modules = new List<DevExpress.Mvvm.ModuleInjection.Module>(); public List<DevExpress.Mvvm.ModuleInjection.Module> modules { get; private set; } public string Caption { get; private set; } public static MainViewModel Create(string caption = null) { return ViewModelSource.Create(() => new MainViewModel() { Caption = caption }); } private DelegateCommand testButtonCommand; public DelegateCommand TestButtonCommand => testButtonCommand ?? (testButtonCommand = new DelegateCommand(ExecuteTestButtonCommand)); void ExecuteTestButtonCommand() { //Manager.RegisterOrInjectOrNavigate(Regions.Documents, modules.Where(x=>x.Key == "ModuleViewModel").FirstOrDefault()); var key = Guid.NewGuid().ToString().Replace("-", ""); var weakRef = new WeakReference(Bootstrapper.Default.modules.Where(module => module.Key == "ModuleViewModel").FirstOrDefault().ViewModelFactory.Invoke()); var module = new DevExpress.Mvvm.ModuleInjection.Module( key, //Bootstrapper.Default.modules.Where(module => module.Key == "ModuleViewModel").FirstOrDefault().ViewModelFactory, () => weakRef.Target, Bootstrapper.Default.modules.Where(module => module.Key == "ModuleViewModel").FirstOrDefault().ViewName); Manager.Register(Regions.Navigation, module); Manager.Inject(Regions.Navigation, key); Manager.RegisterOrInjectOrNavigate(Regions.Documents, module); } } }
ModuleViewModel.cs
using DevExpress.Mvvm; using DevExpress.Mvvm.POCO; using DXApplication1.Common; using System; using System.Collections.ObjectModel; using System.Linq; using DXApplication1.Modules.Views; namespace DXApplication1.Modules.ViewModels { public class ModuleViewModel : IDocumentModule, ISupportState<ModuleViewModel.Info> { public static string Key => nameof(ModuleViewModel); public static string ViewModelName => nameof(ModuleViewModel); public static string ViewName => nameof(ModuleView); public static Type ViewType => typeof(ModuleView); public string Caption { get; private set; } public virtual bool IsActive { get; set; } public ObservableCollection<DataItem> Items { get; private set; } public static ModuleViewModel Create(string caption = "module") { return ViewModelSource.Create(() => new ModuleViewModel() { Caption = caption, }); } //public static ModuleViewModel Create(string caption = "module") //{ // return ViewModelSource.Create(() => new ModuleViewModel() // { // Caption = caption, // }); //} protected ModuleViewModel() { Items = new ObservableCollection<DataItem>(); Enumerable.Range(0, 100) .Select(x => new DataItem() { Id = x, Value = "Item #" + x.ToString() }) .ToList() .ForEach(x => Items.Add(x)); } #region Serialization [Serializable] public class Info { public string Caption { get; set; } } Info ISupportState<Info>.SaveState() { return new Info() { Caption = this.Caption, }; } void ISupportState<Info>.RestoreState(Info state) { this.Caption = state.Caption; } #endregion } public class DataItem { public int Id { get; set; } public string Value { get; set; } } }
https://supportcenter.devexpress.com/ticket/details/t868054/mif-and-dynamically-loaded-dlls
MIF and dynamically loaded DLLs
You have yet to view any tickets. Your search criteria do not match any tickets. A server error occurred while processing your request. Please try again at a later time.
supportcenter.devexpress.com
MIF - creating Module with ViewModel instance (instead of ViewModelFactory)
You have yet to view any tickets. Your search criteria do not match any tickets. A server error occurred while processing your request. Please try again at a later time.
supportcenter.devexpress.com
DevExpress MVVM for WPF - New Module Injection Framework Coming Soon in v16.2
Wait, what? What’s a Module Injection Framework – or MIF – and how is it used? The mile-high overview is that a MIF makes it easier to develop, test, maintain, and deploy applications built with loosely-coupled modules. Such a modular application is
community.devexpress.com
https://docs.devexpress.com/WPF/118614/mvvm-framework/mif
MIF | WPF Controls | DevExpress Documentation
Module Injection Framework (MIF) is a set of classes that help organize an MVVM application. It provides the following functionality: Connecting View Models to Views Navigating among different screens or pages in an application Saving and restoring an appl
docs.devexpress.com
728x90'DevExpress > DX_WPF' 카테고리의 다른 글
[DX_WPF] DevExpress Create a Custom Service (0) 2023.11.29 [DX_WPF] xpf ~ Reference (1) 2023.11.28 [DX_WPF] PropertyGridControl (0) 2023.06.20 [DX_WPF] ToolTip, SuperTip (0) 2023.06.07 [DX_WPF] dxmvvm:Interaction.Behaviors (0) 2023.05.19 댓글