如何在 XAML 中使用 DI
How to use DI in XAML
我希望我不是在想象,但我想我在 Prism 和 XF 的某个地方看到了一种方法,可以在 XAML:
中使用依赖注入的行为
<ContentPage.Behaviors>
<helpers:MyPageBehavior>
<x:Arguments>
Have a type here maybe?
</x:Arguments>
</helpers:MyPageBehavior>
</ContentPage.Behaviors>
我的页面行为:
class MyPageBehavior : Behavior<ContentPage>
{
public MyPageBehavior(ISomeService someService)
{
}
}
假设我们有 class SomeService
实现 ISomeService
,如下所示:
namespace YOURAPPNAME.Services
{
public class SomeService : ISomeService
{
public SomeService()
{
Debug.WriteLine("Some Service Constructor Called");
}
}
}
然后在您的 Xaml 页面中
<ContentPage ......
xmlns:services="clr-namespace:YOURAPPNAME.Services;assembly=YOURAPPNAME"
.....>
<ContentPage.Behaviors>
<helpers:MyPageBehavior>
<x:Arguments>
<services:SomeService />
</x:Arguments>
</helpers:MyPageBehavior>
</ContentPage.Behaviors>
您需要使用 ContainerProvider
。您可以从下面取自 Prism Unit Tests 的示例中看到如何使用它。您会注意到 Mock Converter 需要通过 DI 注入 IEventAggregator。在 XAML 中,您可以使用 ContainerProvider 并传入转换器的类型参数,将转换器添加到 ResourceDictionary。
模拟转换器
using System;
using System.Globalization;
using Xamarin.Forms;
using Prism.Forms.Tests.Mocks.Events;
using Prism.Events;
namespace Prism.Forms.Tests.Mocks.Converters
{
public class MockValueConverter : IValueConverter
{
private IEventAggregator _eventAggreator { get; }
public MockValueConverter(IEventAggregator eventAggreator)
{
_eventAggreator = eventAggreator;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
_eventAggreator.GetEvent<TestActionEvent>().Publish("Convert");
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
_eventAggreator.GetEvent<TestActionEvent>().Publish("ConvertBack");
return value;
}
}
}
模拟视图
<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Ioc;assembly=Prism.Forms"
xmlns:converters="using:Prism.Forms.Tests.Mocks.Converters"
Title="{Binding Title}"
x:Class="Prism.DI.Forms.Tests.Mocks.Views.XamlViewMock">
<ContentPage.Resources>
<ResourceDictionary>
<prism:ContainerProvider x:TypeArguments="converters:MockValueConverter" x:Key="mockValueConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<Entry x:Name="testEntry"
Text="{Binding Test,Converter={StaticResource mockValueConverter}}" />
</ContentPage>
我希望我不是在想象,但我想我在 Prism 和 XF 的某个地方看到了一种方法,可以在 XAML:
中使用依赖注入的行为 <ContentPage.Behaviors>
<helpers:MyPageBehavior>
<x:Arguments>
Have a type here maybe?
</x:Arguments>
</helpers:MyPageBehavior>
</ContentPage.Behaviors>
我的页面行为:
class MyPageBehavior : Behavior<ContentPage>
{
public MyPageBehavior(ISomeService someService)
{
}
}
假设我们有 class SomeService
实现 ISomeService
,如下所示:
namespace YOURAPPNAME.Services
{
public class SomeService : ISomeService
{
public SomeService()
{
Debug.WriteLine("Some Service Constructor Called");
}
}
}
然后在您的 Xaml 页面中
<ContentPage ......
xmlns:services="clr-namespace:YOURAPPNAME.Services;assembly=YOURAPPNAME"
.....>
<ContentPage.Behaviors>
<helpers:MyPageBehavior>
<x:Arguments>
<services:SomeService />
</x:Arguments>
</helpers:MyPageBehavior>
</ContentPage.Behaviors>
您需要使用 ContainerProvider
。您可以从下面取自 Prism Unit Tests 的示例中看到如何使用它。您会注意到 Mock Converter 需要通过 DI 注入 IEventAggregator。在 XAML 中,您可以使用 ContainerProvider 并传入转换器的类型参数,将转换器添加到 ResourceDictionary。
模拟转换器
using System;
using System.Globalization;
using Xamarin.Forms;
using Prism.Forms.Tests.Mocks.Events;
using Prism.Events;
namespace Prism.Forms.Tests.Mocks.Converters
{
public class MockValueConverter : IValueConverter
{
private IEventAggregator _eventAggreator { get; }
public MockValueConverter(IEventAggregator eventAggreator)
{
_eventAggreator = eventAggreator;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
_eventAggreator.GetEvent<TestActionEvent>().Publish("Convert");
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
_eventAggreator.GetEvent<TestActionEvent>().Publish("ConvertBack");
return value;
}
}
}
模拟视图
<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Ioc;assembly=Prism.Forms"
xmlns:converters="using:Prism.Forms.Tests.Mocks.Converters"
Title="{Binding Title}"
x:Class="Prism.DI.Forms.Tests.Mocks.Views.XamlViewMock">
<ContentPage.Resources>
<ResourceDictionary>
<prism:ContainerProvider x:TypeArguments="converters:MockValueConverter" x:Key="mockValueConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<Entry x:Name="testEntry"
Text="{Binding Test,Converter={StaticResource mockValueConverter}}" />
</ContentPage>