【问题标题】:Dependency Injection with XAML, is it possible?使用 XAML 进行依赖注入,有可能吗?
【发布时间】:2019-11-24 13:38:51
【问题描述】:

我有一个利用新的 Xamarin Forms Shell Search 的类来填充搜索栏的项目源我想使用我的存储库来获取项目列表。

使用 Prism MVVM 框架我宁愿使用 DI 而不是自己创建一个新实例。但是,这样做时,我的代码无法编译,因为 XAML 代码中引用的搜索处理程序抱怨没有无参数构造函数。有解决办法吗?或者,还有更好的方法?请告诉我

搜索处理程序类(我想要的)

public class IngredientsSearchHandler : SearchHandler
    {
        private readonly IUnitOfWork _unitOfWork;

        public IngredientsSearchHandler(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        protected override void OnQueryChanged(string oldValue, string newValue)
        {
            base.OnQueryChanged(oldValue, newValue);

            if (string.IsNullOrWhiteSpace(newValue))
            {
                ItemsSource = null;
            }
            else
            {
                ItemsSource = _unitOfWork.IngredientRepository.GetAll().Where(x => x.Name.ToLower().Contains(newValue.ToLower())).ToList();
            }
        }
    }

查看哪些引用搜索处理程序

错误是:“没有给定的参数对应于'IngredientsSearchHandler.IngredientsSearchHandler(IUnitOfWork)'的所需形式参数'unitOfWork'

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:controls="clr-namespace:TestApp.Controls"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             mc:Ignorable="d"
             x:Class="TestApp.Views.IngredientsView">

    <Shell.SearchHandler>
        <controls:IngredientsSearchHandler Placeholder="Enter ingredient.."
                                           ShowsResults="true"
                                           DisplayMemberName="Name"
                                           Keyboard="Text">
            <controls:IngredientsSearchHandler.ItemTemplate>
                <DataTemplate>
                    <Grid Padding="10">
                        <Label Text="{Binding Name}"
                               FontAttributes="Bold"/>
                    </Grid>
                </DataTemplate>
            </controls:IngredientsSearchHandler.ItemTemplate>
        </controls:IngredientsSearchHandler>
    </Shell.SearchHandler>

    <ContentPage.Content>
            <Label Text="Test"/>
    </ContentPage.Content>
</ContentPage>

【问题讨论】:

    标签: c# xaml xamarin xamarin.forms prism


    【解决方案1】:

    我要做的是完全删除 IngredientsSearchHandler 并将常规 QueryQueryItemsSource 绑定到视图模型上的属性,并对查询的更改做出反应那里(通过更新ItemsSource)。

    视图模型自动注入其依赖项(因为您使用ViewModelLocator),我不知道有任何方法可以拦截 xaml 中定义的控件的创建以使用容器。

    【讨论】:

    • 很好的建议!工作就像一个魅力,我现在把所有东西都封装在我的 ViewModel 中了!!!我希望这对其他人有帮助!
    【解决方案2】:

    简短的回答是肯定的,您可以在 XAML 中将 DependencyInjection 与 ContainerProvider 一起使用。

    <ContentPage xmlns:prism="http://prismlibrary.com"
                 xmlns:converters="using:MyProject.Converters">
      <ContentPage.Resources>
        <prism:ContainerProvider x:TypeArguments="converters:SomeConverter" x:Key="someConverter" />
      </ContentPage.Resources>
    </ContentPage>
    

    【讨论】:

    • 谢谢,这是有道理的!我不明白的是如何消除错误?我复制了你所做的,但错误仍然存​​在,强调了我对搜索处理程序的引用。我错过了什么吗?谢谢!
    • 您需要将此转换器作为 x:Arguments 传递给controls:IngredientsSearchHandler。这就是使用参数化构造函数初始化控件的方式
    • @shanranm 您在使用 ContainerProvider 时不需要使用 x:Arguments,因为它使用 DI Container 来解析类型。您只需要指定 TypeArguments,因为它是泛型类型 ContainerProvider&lt;T&gt; 它将自动返回类型 T
    猜你喜欢
    • 2015-06-01
    • 2015-09-26
    • 2014-01-19
    • 2014-03-25
    • 2019-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多