带参数化构造函数的wpf usercontrol

Mir*_*ral 5 wpf user-controls unity-container

我们正在使用Microsoft Unity和依赖注入,因此我们为usercontrol提供了参数化构造函数.如何使用XAML将此依赖项注入usercontrol?

我在XAML中添加了usercontrol,如下所示.

xmlns:usrRefundArrivalProcessor="Ttl.Refunds.Wpf.Dashboad.Application.Usercontrols;assembly=Ttl.Refunds.Wpf.Dashboad.Application"
Run Code Online (Sandbox Code Playgroud)

Ray*_*rns 10

依赖注入并不意味着参数化构造函数.实际上,如果查看Unity附带的示例,大多数依赖项注入都是由具有[​​Dependency]属性的属性完成的.

Unity与XAML非常兼容,但前提是您不使用参数化构造函数.转换UserControl以使用具有[Dependency]属性的属性获取其依赖项,并且您可以轻松使用XAML.

public class MyUserControl : UserControl
{
  [Dependency]
  public ISomething Something { get; set; }

  [Dependency]
  public IWhatever Whatever { get { return (IWhatever)GetValue(WhateverProperty); } set { SetValue(WhateverProperty, value); }
  public readonly DependencyProperty WhateverProperty = DependencyProperty.Register("Whatever", typeof(IWhatever), typeof(MyUserControl));

  ...
}
Run Code Online (Sandbox Code Playgroud)

请注意,[Dependency]属性可以声明为DependencyProperty或纯CLR属性,如上所示.这听起来像是令人困惑的命名法,但在实践中它非常简单.

要在XAML中指定UnityContainer并获得自动配置,只需创建一个继承的附加属性"UnityHelper.Container",其PropertyChangedCallback只是在指定的容器上调用BuildUp并传入对象的类型和对象:

public class UnityHelper
{
  public static IUnityContainer GetContainer(DependencyObject obj) { return (IUnityContainer)obj.GetValue(ContainerProperty); }
  public static void SetContainer(DependencyObject obj, IUnityContainer value) { obj.SetValue(ContainerProperty, value); }
  public static readonly DependencyProperty ContainerProperty = DependencyProperty.RegisterAttached("Container", typeof(IUnityContainer), typeof(UnityHelper), new FrameworkPropertyMetadata
  {
    Inherits = true,
    PropertyChangedCallback = (obj, e) =>
    {
      var container = e.NewValue as IUnityContainer;
      if(container!=null)
      {
        var element = obj as FrameworkElement;
        container.BuildUp(obj.GetType(), obj, element==null ? null : element.Name);
      }
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

现在您可以将UnityContainer分配给根窗口,整个应用程序将使用它,例如您可以在窗口的构造函数中执行此操作,如下所示:

UnityHelper.SetContainer(this, new UnityContainer() ...);
Run Code Online (Sandbox Code Playgroud)

或者,您可以在树的任何所需级别使用XAML分配统一容器:

<UserControl ...
  my:UnityHelper.Container="{DynamicResource MainUnityContainer}" />
Run Code Online (Sandbox Code Playgroud)

说了这么多,我想你会发现WPF的高级数据绑定功能和资源词典一起消除了一个人可能想要首先使用Unity的98%的原因.从长远来看,你可能会发现它更好地远离Unity并使用简单的MVVM.至少我会在测试应用程序上尝试纯MVVM,看看它在开发依赖Unity依赖注入的代码之前是如何工作的.