這不僅僅是一個問題的評論,儘管反饋會很好。我的任務是爲我們正在進行的新項目創建用戶界面。我們想要使用WPF,並且我想了解所有現有的可用UI設計技術。由於我對WPF相當陌生,我一直在研究可用的東西。我想我使用MVVM Light Toolkit的主要原因在於它的「Blendability」和EventToCommand行爲!),但我也希望將IoC也納入其中。所以,這就是我所提出的。我修改了MVVM Light項目中的默認ViewModelLocator類,以使用UnityContainer處理依賴注入。考慮到3個月前我不知道這些術語的90%是什麼意思,我想我正走在正確的軌道上。結合MVVM Light Toolkit和Unity 2.0
// 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類表示依賴注入用法:
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();
}
}
}
這可以用於爲特定顯示的順序視圖的代碼順序:
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創意。它耗費了大量的試驗和錯誤,在互聯網上搜索示例,並發現Unity 2.0文檔缺乏(在示例代碼中用於擴展)以提出該解決方案。如果您認爲可以改進,請告訴我。
我很想知道你覺得Unity文檔中有什麼漏洞。你還需要什麼呢? – 2010-12-23 04:46:31
Unity文檔非常好,我只是很難找到2.0版的任何示例代碼片段,尤其是使用擴展。 1.x有很多示例代碼,但很多都是過時的(我不斷收到消息,不使用該語法來做事情,因爲使用擴展可以使用新的語法)。 – acordner 2010-12-30 17:27:01