gpt4 book ai didi

wpf - 结合 MVVM Light Toolkit 和 Unity 2.0

转载 作者:行者123 更新时间:2023-12-04 12:56:20 26 4
gpt4 key购买 nike

这更像是一个评论而不是一个问题,尽管反馈会很好。我的任务是为我们正在做的一个新项目创建用户界面。我们想使用 WPF,我想学习所有可用的现代 UI 设计技术。由于我对 WPF 相当陌生,因此我一直在研究可用的内容。我想我已经决定使用 MVVM Light Toolkit(主要是因为它的“可混合性”和 EventToCommand 行为!),但我也想合并 IoC。所以,这就是我想出的。我已经修改了 MVVM Light 项目中的默认 ViewModelLocator 类,以使用 UnityContainer 来处理依赖项注入(inject)。考虑到 3 个月前我不知道这些术语中的 90% 是什么意思,我认为我走在正确的轨道上。

// Example of MVVM Light Toolkit ViewModelLocator class that implements Microsoft 
// Unity 2.0 Inversion of Control container to resolve ViewModel dependencies.

using Microsoft.Practices.Unity;

namespace MVVMLightUnityExample
{
public class ViewModelLocator
{
public static UnityContainer Container { get; set; }

#region Constructors
static ViewModelLocator()
{
if (Container == null)
{
Container = new UnityContainer();

// register all dependencies required by view models
Container
.RegisterType<IDialogService, ModalDialogService>(new ContainerControlledLifetimeManager())
.RegisterType<ILoggerService, LogFileService>(new ContainerControlledLifetimeManager())
;
}
}

/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
////if (ViewModelBase.IsInDesignModeStatic)
////{
//// // Create design time view models
////}
////else
////{
//// // Create run time view models
////}

CreateMain();
}

#endregion

#region MainViewModel

private static MainViewModel _main;

/// <summary>
/// Gets the Main property.
/// </summary>
public static MainViewModel MainStatic
{
get
{
if (_main == null)
{
CreateMain();
}
return _main;
}
}

/// <summary>
/// Gets the Main property.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public MainViewModel Main
{
get
{
return MainStatic;
}
}

/// <summary>
/// Provides a deterministic way to delete the Main property.
/// </summary>
public static void ClearMain()
{
_main.Cleanup();
_main = null;
}

/// <summary>
/// Provides a deterministic way to create the Main property.
/// </summary>
public static void CreateMain()
{
if (_main == null)
{
// allow Unity to resolve the view model and hold onto reference
_main = Container.Resolve<MainViewModel>();
}
}

#endregion

#region OrderViewModel

// property to hold the order number (injected into OrderViewModel() constructor when resolved)
public static string OrderToView { get; set; }

/// <summary>
/// Gets the OrderViewModel property.
/// </summary>
public static OrderViewModel OrderViewModelStatic
{
get
{
// allow Unity to resolve the view model
// do not keep local reference to the instance resolved because we need a new instance
// each time - the corresponding View is a UserControl that can be used multiple times
// within a single window/view
// pass current value of OrderToView parameter to constructor!
return Container.Resolve<OrderViewModel>(new ParameterOverride("orderNumber", OrderToView));
}
}

/// <summary>
/// Gets the OrderViewModel property.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public OrderViewModel Order
{
get
{
return OrderViewModelStatic;
}
}
#endregion

/// <summary>
/// Cleans up all the resources.
/// </summary>
public static void Cleanup()
{
ClearMain();
Container = null;
}
}
}

MainViewModel 类显示依赖注入(inject)用法:
using GalaSoft.MvvmLight;
using Microsoft.Practices.Unity;

namespace MVVMLightUnityExample
{
public class MainViewModel : ViewModelBase
{
private IDialogService _dialogs;
private ILoggerService _logger;

/// <summary>
/// Initializes a new instance of the MainViewModel class. This default constructor calls the
/// non-default constructor resolving the interfaces used by this view model.
/// </summary>
public MainViewModel()
: this(ViewModelLocator.Container.Resolve<IDialogService>(), ViewModelLocator.Container.Resolve<ILoggerService>())
{
if (IsInDesignMode)
{
// Code runs in Blend --> create design time data.
}
else
{
// Code runs "for real"
}
}

/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// Interfaces are automatically resolved by the IoC container.
/// </summary>
/// <param name="dialogs">Interface to dialog service</param>
/// <param name="logger">Interface to logger service</param>
public MainViewModel(IDialogService dialogs, ILoggerService logger)
{
_dialogs = dialogs;
_logger = logger;

if (IsInDesignMode)
{
// Code runs in Blend --> create design time data.
_dialogs.ShowMessage("Running in design-time mode!", "Injection Constructor", DialogButton.OK, DialogImage.Information);
_logger.WriteLine("Running in design-time mode!");
}
else
{
// Code runs "for real"
_dialogs.ShowMessage("Running in run-time mode!", "Injection Constructor", DialogButton.OK, DialogImage.Information);
_logger.WriteLine("Running in run-time mode!");
}
}

public override void Cleanup()
{
// Clean up if needed
_dialogs = null;
_logger = null;

base.Cleanup();
}
}
}

和 OrderViewModel 类:
using GalaSoft.MvvmLight;
using Microsoft.Practices.Unity;

namespace MVVMLightUnityExample
{
/// <summary>
/// This class contains properties that a View can data bind to.
/// <para>
/// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
/// </para>
/// <para>
/// You can also use Blend to data bind with the tool's support.
/// </para>
/// <para>
/// See http://www.galasoft.ch/mvvm/getstarted
/// </para>
/// </summary>
public class OrderViewModel : ViewModelBase
{

private const string testOrderNumber = "123456";
private Order _order;

/// <summary>
/// Initializes a new instance of the OrderViewModel class.
/// </summary>
public OrderViewModel()
: this(testOrderNumber)
{

}

/// <summary>
/// Initializes a new instance of the OrderViewModel class.
/// </summary>
public OrderViewModel(string orderNumber)
{
if (IsInDesignMode)
{
// Code runs in Blend --> create design time data.
_order = new Order(orderNumber, "My Company", "Our Address");
}
else
{
_order = GetOrder(orderNumber);
}
}

public override void Cleanup()
{
// Clean own resources if needed
_order = null;

base.Cleanup();
}
}
}

以及可用于显示特定订单的订单 View 的代码:
public void ShowOrder(string orderNumber)
{
// pass the order number to show to ViewModelLocator to be injected
//into the constructor of the OrderViewModel instance
ViewModelLocator.OrderToShow = orderNumber;

View.OrderView orderView = new View.OrderView();
}

这些示例已被精简,仅显示 IoC 的想法。经过大量试验和错误,在 Internet 上搜索示例,并发现缺少 Unity 2.0 文档(在扩展示例代码中)来提出此解决方案。如果您认为可以改进,请告诉我。

最佳答案

首先,您应该避免服务定位器反模式。

第二,每次要获取OrderView都要设置一个静态变量?这是一个非常丑陋的设计。

关于wpf - 结合 MVVM Light Toolkit 和 Unity 2.0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4512828/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com