피드백이 좋을 지 모르지만 이것은 질문보다 많은 논평입니다. 우리가하고있는 새로운 프로젝트를위한 사용자 인터페이스를 만드는 임무가 주어졌습니다. 우리는 WPF를 사용하기를 원하며 모든 현대적인 UI 디자인 기술을 배우고 싶었습니다. 저는 WPF에 대해 처음으로 익숙해 졌기 때문에 사용할 수있는 것을 조사하고 있습니다. MVVM Light Toolkit을 사용할 때 (주로 "Blendability"및 EventToCommand 동작 때문에!) 정착했다고 생각하지만 IoC도 통합하려고했습니다. 그래서, 여기 제가 생각해내는 것이 있습니다. MVC 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 문서에 구멍이있는 곳을 알고 싶습니다. 거기에 없었던 게 더 있었 니? –
Unity 문서는 꽤 좋았습니다. 2.0 용 샘플 코드 스 니펫을 찾는 데 어려움을 겪었습니다. 1.x에 대한 예제 코드가 많았지 만 많은 부분이 구식이었습니다 (확장을 사용하여 사용할 수있는 새로운 구문이 있었기 때문에이 구문을 사용하지 않는 메시지를 계속 받았습니다). – acordner
처음 게시 한 후 거의 1 년이 지났습니다. 나는 그 당시의 아이디어에 고투하기 시작했습니다. MVVM Light/Unity가 어디까지 갈지 알고 있습니다. – Rod