Don Box
Don Box

Reputation: 3336

How to use DI in XAML

I hope I'm not imagining but I think I saw somewhere a way in Prism and XF to have a behavior use dependency injection in XAML:

 <ContentPage.Behaviors>
   <helpers:MyPageBehavior>
      <x:Arguments>
             Have a type here maybe?
      </x:Arguments>             
   </helpers:MyPageBehavior>        
  </ContentPage.Behaviors>

MyPageBehavior:

class MyPageBehavior : Behavior<ContentPage>
{
      public MyPageBehavior(ISomeService someService)
      {
      }
}

Upvotes: 0

Views: 577

Answers (2)

Dan Siegel
Dan Siegel

Reputation: 5799

You'll want to use the ContainerProvider. You can see from the sample below taken from the Prism Unit Tests how to use this. You'll notice the Mock Converter requires the IEventAggregator be injected via DI. In XAML you are able to then add the converter to the ResourceDictionary by using the ContainerProvider and passing in the Type Argument for the Converter.

MockConverter

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;
        }
    }
}

Mock View

<?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>

Upvotes: 2

Khaled Gaber
Khaled Gaber

Reputation: 121

Assume we have class SomeService that implements ISomeService, like below:

namespace YOURAPPNAME.Services
{
     public class SomeService : ISomeService
     {
          public SomeService()
          {
              Debug.WriteLine("Some Service Constructor Called");
          }
     }
}

then in your Xaml page

<ContentPage ......
         xmlns:services="clr-namespace:YOURAPPNAME.Services;assembly=YOURAPPNAME"
         .....>

<ContentPage.Behaviors>
   <helpers:MyPageBehavior>
      <x:Arguments>
         <services:SomeService />
      </x:Arguments>             
   </helpers:MyPageBehavior>        
</ContentPage.Behaviors>

Upvotes: 2

Related Questions