清除方式注入依赖于wpf行为

RAJ*_*RAJ 2 c# wpf xaml dependency-injection mef

我需要创建自定义WPF行为,并在custructor中注入一些依赖项,我不能使用构造函数注入,因为我需要在XAML中应用它,WPF使用默认构造函数创建实例.我可以做的一种方法是在默认构造函数或服务定位器中使用Container,但我不想这些方法.我可以在属性上使用[Improt]并使用Container.SatisfyImportOnce但不是很整洁,因为我仍然会在构造函数中使用容器.有什么建议吗?

我在我的WPF项目中使用MEF进行依赖注入.

整洁的方式:它应该是可测试的,我应该能够注入依赖项并且应该在WPF XAML中实例化.

quj*_*jck 5

如您所知,您无法使用Wpf进行构造函数注入,但您可以在Xaml中定义属性注入.我认为是一个"整洁"的解决方案是使用MarkupExtension如下:

public sealed class Resolver : MarkupExtension
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var provideValueTarget = (IProvideValueTarget)serviceProvider
            .GetService(typeof(IProvideValueTarget));

        // Find the type of the property we are resolving
        var targetProperty = provideValueTarget.TargetProperty as PropertyInfo;

        if (targetProperty == null)
        {
            throw new InvalidProgramException();
        }

        // Find the implementation of the type in the container
        return BootStrapper.Container.Resolve(targetProperty.PropertyType);
    }
}
Run Code Online (Sandbox Code Playgroud)

并且有这样的行为:

public sealed class InitialiseWebBrowser : Behavior<MyVM>
{
    public IQueryHandler<Query.Html, string> HtmlQueryHandler { private get; set; }

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

我们可以在Xaml中配置属性注入,如下所示:

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    xmlns:inf="clr-namespace:abc"
    xmlns:behaviours="clr-namespace:def"
    x:Class="MyVM">
    <i:Interaction.Behaviors>
        <behaviours:InitialiseWebBrowser HtmlQueryHandler="{inf:Resolver}"/>
    </i:Interaction.Behaviors>
Run Code Online (Sandbox Code Playgroud)

Resolver的MarkupExtension将:

  • 分析它定义的属性的类型(在示例中HtmlQueryHandler是一个IQueryHandler<Query.Html, string>)
  • 从您正在使用的任何底层容器/解析器中解析类型
  • 将它注入行为.