-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3239 from chowarth/feature/containerprovider
Add ContainerProvider for resolving dependencies in XAML
- Loading branch information
Showing
8 changed files
with
229 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#nullable enable | ||
namespace Prism.IoC; | ||
|
||
/// <summary> | ||
/// Provides Types and Services registered with the Container | ||
/// </summary> | ||
/// <typeparam name="T">The type to Resolve</typeparam> | ||
/// <example> | ||
/// We can use this to build better types such as ValueConverters with full dependency injection | ||
/// <code> | ||
/// public class MyValueConverter : IValueConverter | ||
/// { | ||
/// private readonly ILogger _logger { get; } | ||
/// | ||
/// public MyValueConverter(ILogger logger) | ||
/// { | ||
/// _logger = logger; | ||
/// } | ||
/// | ||
/// public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
/// { | ||
/// _logger.Log($"Converting {value.GetType().Name} to {targetType.Name}", Category.Debug, Priority.None); | ||
/// // do stuff | ||
/// } | ||
/// | ||
/// public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
/// { | ||
/// _logger.Log($"Converting back from {value.GetType().Name} to {targetType.Name}", Category.Debug, Priority.None); | ||
/// return null; | ||
/// } | ||
/// } | ||
/// </code> | ||
/// We can then simply use our ValueConverter or other class directly in XAML | ||
/// <![CDATA[ | ||
/// <ContentPage xmlns:prism="clr-namespace:Prism.Ioc;assembly=Prism.Maui"> | ||
/// <ContentPage.Resources> | ||
/// <ResourceDictionary> | ||
/// <prism:ContainerProvider x:TypeArguments="MyValueConverter" x:Key="myValueConverter" /> | ||
/// <ResourceDictionary> | ||
/// <ContentPage.Resources> | ||
/// <Label Text="{Binding SomeProp, Converter={StaticResource myValueConverter}}" /> | ||
/// </ContentPage> | ||
/// ]]> | ||
/// </example> | ||
public class ContainerProvider<T> | ||
{ | ||
/// <summary> | ||
/// The Name used to register the type with the Container | ||
/// </summary> | ||
public string? Name { get; set; } | ||
|
||
/// <summary> | ||
/// Resolves the specified type from the Application's Container | ||
/// </summary> | ||
/// <param name="containerProvider"></param> | ||
public static implicit operator T(ContainerProvider<T> containerProvider) | ||
{ | ||
var container = ContainerLocator.Container; | ||
if (container == null) return default(T); | ||
if (string.IsNullOrWhiteSpace(containerProvider.Name)) | ||
{ | ||
return container.Resolve<T>(); | ||
} | ||
|
||
return container.Resolve<T>(containerProvider.Name); | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/IoC/ContainerProviderTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using Prism.DryIoc.Maui.Tests.Mocks; | ||
using Prism.DryIoc.Maui.Tests.Mocks.Events; | ||
using Prism.DryIoc.Maui.Tests.Mocks.ViewModels; | ||
using Prism.DryIoc.Maui.Tests.Mocks.Views; | ||
using Prism.Events; | ||
using Prism.IoC; | ||
|
||
namespace Prism.DryIoc.Maui.Tests.Fixtures.IoC; | ||
|
||
public class ContainerProviderTests(ITestOutputHelper testOutputHelper) : TestBase(testOutputHelper) | ||
{ | ||
[Fact] | ||
public void CanResolveUnamedType() | ||
{ | ||
var builder = CreateBuilder(prism => { }); | ||
var app = builder.Build(); | ||
var containerProvider = new ContainerProvider<ConcreteTypeMock>(); | ||
|
||
ConcreteTypeMock type = (ConcreteTypeMock)containerProvider; | ||
|
||
Assert.NotNull(type); | ||
Assert.IsType<ConcreteTypeMock>(type); | ||
} | ||
|
||
[Fact] | ||
public void CanResolvedNamedType() | ||
{ | ||
var builder = CreateBuilder(prism => { }); | ||
var app = builder.Build(); | ||
var containerProvider = new ContainerProvider<ConcreteTypeMock> | ||
{ | ||
Name = ConcreteTypeMock.Key | ||
}; | ||
|
||
ConcreteTypeMock vm = (ConcreteTypeMock)containerProvider; | ||
|
||
Assert.NotNull(vm); | ||
Assert.IsType<ConcreteTypeMock>(vm); | ||
} | ||
|
||
[Fact] | ||
public async Task ProvidesValueFromResourceDictionary() | ||
{ | ||
var builder = CreateBuilder(prism => | ||
{ | ||
prism.RegisterTypes(containerRegistry => | ||
{ | ||
containerRegistry.RegisterForNavigation<MockXamlView, MockXamlViewViewModel>(); | ||
}) | ||
.CreateWindow(n => | ||
n.CreateBuilder() | ||
.AddSegment<MockViewAViewModel>() | ||
.NavigateAsync()); | ||
}); | ||
var app = builder.Build(); | ||
|
||
var ea = app.Services.GetService<IEventAggregator>(); | ||
var events = new List<string>(); | ||
ea.GetEvent<TestActionEvent>().Subscribe((m) => events.Add(m)); | ||
|
||
var navigation = app.Services.GetService<INavigationService>(); | ||
await navigation.CreateBuilder() | ||
.AddSegment<MockXamlViewViewModel>() | ||
.NavigateAsync(); | ||
|
||
Assert.Contains(events, e => e == "Convert"); | ||
var window = GetWindow(app); | ||
Assert.NotNull(window.Page); | ||
|
||
var xamlView = window.Page as MockXamlView; | ||
var viewModel = xamlView.BindingContext as MockXamlViewViewModel; | ||
|
||
xamlView.TestEntry.Text = "Foo Bar"; | ||
Assert.Contains(events, e => e == "ConvertBack"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Prism.DryIoc.Maui.Tests.Mocks; | ||
|
||
internal class ConcreteTypeMock | ||
{ | ||
public const string Key = "ConcreteTypeMock"; | ||
} |
27 changes: 27 additions & 0 deletions
27
tests/Maui/Prism.DryIoc.Maui.Tests/Mocks/Converters/MockValueConverter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
using System.Globalization; | ||
using Prism.DryIoc.Maui.Tests.Mocks.Events; | ||
using Prism.Events; | ||
|
||
namespace Prism.DryIoc.Maui.Tests.Mocks.Converters; | ||
|
||
internal 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; | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
tests/Maui/Prism.DryIoc.Maui.Tests/Mocks/Events/TestActionEvent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
using Prism.Events; | ||
|
||
namespace Prism.DryIoc.Maui.Tests.Mocks.Events; | ||
|
||
internal class TestActionEvent : PubSubEvent<string> | ||
{ | ||
} |
11 changes: 11 additions & 0 deletions
11
tests/Maui/Prism.DryIoc.Maui.Tests/Mocks/ViewModels/MockXamlViewViewModel.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
namespace Prism.DryIoc.Maui.Tests.Mocks.ViewModels; | ||
|
||
internal class MockXamlViewViewModel : BindableBase | ||
{ | ||
private string _test = "Initial Value"; | ||
public string Test | ||
{ | ||
get => _test; | ||
set => SetProperty(ref _test, value); | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
tests/Maui/Prism.DryIoc.Maui.Tests/Mocks/Views/MockXamlView.xaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<ContentPage | ||
xmlns="http://schemas.microsoft.com/dotnet/2021/maui" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | ||
xmlns:prism="clr-namespace:Prism.IoC;assembly=Prism.Maui" | ||
xmlns:converters="clr-namespace:Prism.DryIoc.Maui.Tests.Mocks.Converters" | ||
x:Class="Prism.DryIoc.Maui.Tests.Mocks.Views.MockXamlView" | ||
Title="MockXamlView"> | ||
|
||
<ContentPage.Resources> | ||
<ResourceDictionary> | ||
<prism:ContainerProvider | ||
x:TypeArguments="converters:MockValueConverter" | ||
x:Key="mockValueConverter" /> | ||
</ResourceDictionary> | ||
</ContentPage.Resources> | ||
|
||
<StackLayout> | ||
<Entry x:Name="testEntry" | ||
Text="{Binding Test,Converter={StaticResource mockValueConverter}}" /> | ||
</StackLayout> | ||
|
||
</ContentPage> |
12 changes: 12 additions & 0 deletions
12
tests/Maui/Prism.DryIoc.Maui.Tests/Mocks/Views/MockXamlView.xaml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
namespace Prism.DryIoc.Maui.Tests.Mocks.Views; | ||
|
||
[XamlCompilation(XamlCompilationOptions.Compile)] | ||
public partial class MockXamlView : ContentPage | ||
{ | ||
public MockXamlView() | ||
{ | ||
InitializeComponent(); | ||
} | ||
|
||
public Entry TestEntry => testEntry; | ||
} |