依赖注入并不意味着参数化的构造函数。实际上,如果您查看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));
...
}
。注意,[依赖]属性可以被声明为一个DependencyProperty或纯CLR属性,如上所示。这听起来像命名混淆,但实际上它非常简单。
要指定XAML的UnityContainer并获得自动配置,只需要创建一个继承附加属性“UnityHelper.Container”,其PropertyChangedCallback简单地调用指定的容器上积聚并通过在对象的类型和对象:
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);
}
}
});
}
现在你可以指定一个UnityContainer到你的根窗口,整个应用程序将使用它,举例如下,你可以做你的窗口的构造函数:
UnityHelper.SetContainer(this, new UnityContainer() ...);
或者你可以分配使用XAML在树的任何所需水平的统一容器:
<UserControl ...
my:UnityHelper.Container="{DynamicResource MainUnityContainer}" />
说了这么多,我想你会会发现WPF先进的数据绑定功能和资源字典一起消灭的原因,98%为什么人可能想要首先使用Unity。从长远来看,您可能会发现离开Unity并使用简单的MVVM更好。至少我会尝试在测试应用程序上使用纯MVVM,以便在开发依赖Unity进行依赖注入的大量代码之前查看它是如何工作的。
它的工作原理,但是当我从其中一个文本框中打开标签按钮时,它会抛出异常 解析依赖失败,type =“System.Windows.Input.KeyboardNavigation + FocusVisualAdorner”,name =“”。异常消息是:当前的构建操作(构建键构建键[System.Windows.Input.KeyboardNavigation + FocusVisualAdorner,null])失败:无法从程序集'PresentationFramework,Version = 3.0中加载类型'System.Windows.Input.KeyboardNavigation' .0.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35'。 (策略类型BuildPlanStrategy,索引5) – Miral 2010-05-24 14:09:31
这个答案帮了我很大的忙。我希望我可以给+1。我已经将此线程添加到“我的收藏夹”中,但只是将这个问题归功于提出原始问题的人。所以谢谢! – Tormod 2011-03-02 09:05:27
如果您创建一个接口(称为IUnityElement),并将其应用于所有UserControl或控件,则需要在'if(container!= null)'行中运行,然后在该行中运行,则可以检查obj参数是否为该接口例如'if(container!= null && obj is IUnityInject)'。这消除了Miral上面评论的错误(我从一个不同的对象中得到了类似的结果,ZeePrime的回答也是性能问题,因为BuildUp只能在您需要的FrameworkElements上运行。 – 2011-11-05 23:28:46