Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature resolvers changed to allow registration of null with a value type #721

Merged
merged 15 commits into from
Jul 25, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Splat.Autofac.Tests/Splat.Autofac.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<IsPackable>false</IsPackable>
<NoWarn>$(NoWarn);1591;CA1707;SA1633;CA2000</NoWarn>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
22 changes: 11 additions & 11 deletions src/Splat.Autofac/AutofacDependencyResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public AutofacDependencyResolver(ContainerBuilder builder)
}

/// <inheritdoc />
public virtual object? GetService(Type serviceType, string? contract = null)
public virtual object GetService(Type serviceType, string? contract = null)
ChrisPulman marked this conversation as resolved.
Show resolved Hide resolved
{
lock (_lockObject)
{
Expand Down Expand Up @@ -126,14 +126,14 @@ public bool HasRegistration(Type serviceType, string? contract = null)
/// Register a function with the resolver which will generate a object
/// for the specified service type.
/// Optionally a contract can be registered which will indicate
/// that that registration will only work with that contract.
/// that registration will only work with that contract.
/// Most implementations will use a stack based approach to allow for multiple items to be registered.
/// </summary>
/// <param name="factory">The factory function which generates our object.</param>
/// <param name="serviceType">The type which is used for the registration.</param>
/// <param name="contract">A optional contract value which will indicates to only generate the value if this contract is specified.</param>
[Obsolete("Because Autofac 5+ containers are immutable, this method should not be used by the end-user.")]
public virtual void Register(Func<object> factory, Type serviceType, string? contract = null)
public virtual void Register(Func<object?> factory, Type serviceType, string? contract = null)
{
lock (_lockObject)
{
Expand All @@ -147,21 +147,21 @@ public virtual void Register(Func<object> factory, Type serviceType, string? con
// Second to child lifetimes in a temporary container, that is used only to satisfy ReactiveUI dependencies.
if (contract is null || string.IsNullOrWhiteSpace(contract))
{
_builder.Register(_ => factory())
_builder.Register(_ => factory()!)
.As(serviceType)
.AsImplementedInterfaces();
_internalLifetimeScope = _internalLifetimeScope.BeginLifetimeScope(internalBuilder =>
internalBuilder.Register(_ => factory())
internalBuilder.Register(_ => factory()!)
.As(serviceType)
.AsImplementedInterfaces());
}
else
{
_builder.Register(_ => factory())
_builder.Register(_ => factory()!)
.Named(contract, serviceType)
.AsImplementedInterfaces();
_internalLifetimeScope = _internalLifetimeScope.BeginLifetimeScope(internalBuilder =>
internalBuilder.Register(_ => factory())
internalBuilder.Register(_ => factory()!)
.Named(contract, serviceType)
.AsImplementedInterfaces());
}
Expand Down Expand Up @@ -225,19 +225,19 @@ protected virtual void Dispose(bool disposing)
}
}

private object? Resolve(Type serviceType, string? contract)
private object Resolve(Type serviceType, string? contract)
{
object? serviceInstance;
object serviceInstance;

var lifeTimeScope = _lifetimeScope ?? _internalLifetimeScope;

if (contract is null || string.IsNullOrWhiteSpace(contract))
{
lifeTimeScope.TryResolve(serviceType, out serviceInstance);
lifeTimeScope.TryResolve(serviceType, out serviceInstance!);
}
else
{
lifeTimeScope.TryResolveNamed(contract, serviceType, out serviceInstance);
lifeTimeScope.TryResolveNamed(contract, serviceType, out serviceInstance!);
}

return serviceInstance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Splat.Tests.Mocks
/// <summary>
/// A dummy class used during Locator testing.
/// </summary>
internal class DummyObjectClass1 : IDummyInterface
public class DummyObjectClass1 : IDummyInterface
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Splat.Tests.Mocks
/// <summary>
/// A dummy class used during Locator testing.
/// </summary>
internal class DummyObjectClass2 : IDummyInterface
public class DummyObjectClass2 : IDummyInterface
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Splat.Tests.Mocks
/// <summary>
/// A dummy class used during Locator testing.
/// </summary>
internal class DummyObjectClass3 : IDummyInterface
public class DummyObjectClass3 : IDummyInterface
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Splat.Tests.Mocks
/// <summary>
/// A dummy interface used during Locator testing.
/// </summary>
internal interface IDummyInterface
public interface IDummyInterface
ChrisPulman marked this conversation as resolved.
Show resolved Hide resolved
{
}
}
7 changes: 5 additions & 2 deletions src/Splat.Common.Test/IViewFor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@
namespace Splat.Common.Test
{
#pragma warning disable SA1402 // File may only contain a single type

/// <summary>
/// Represents a view bound to a view model.
/// </summary>
/// <typeparam name="T">The view model type.</typeparam>
/// <seealso cref="Splat.Common.Test.IViewFor" />
public interface IViewFor<T> : IViewFor
where T : class
{
/// <summary>
/// Gets or sets the view model.
/// </summary>
new T ViewModel { get; set; }
new T? ViewModel { get; set; }
}

/// <summary>
Expand All @@ -28,7 +30,8 @@ public interface IViewFor
/// <summary>
/// Gets or sets the view model.
/// </summary>
object ViewModel { get; set; }
object? ViewModel { get; set; }
}

#pragma warning restore SA1402 // File may only contain a single type
}
1 change: 1 addition & 0 deletions src/Splat.Common.Test/Splat.Common.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>
<NoWarn>$(NoWarn);CA2000</NoWarn>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
6 changes: 3 additions & 3 deletions src/Splat.Common.Test/ViewOne.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ namespace Splat.Common.Test
public class ViewOne : IViewFor<ViewModelOne>
{
/// <inheritdoc />
object IViewFor.ViewModel
object? IViewFor.ViewModel
{
get => ViewModel;
set => ViewModel = (ViewModelOne)value;
set => ViewModel = (ViewModelOne?)value;
}

/// <inheritdoc />
public ViewModelOne ViewModel { get; set; }
public ViewModelOne? ViewModel { get; set; }
}
}
6 changes: 3 additions & 3 deletions src/Splat.Common.Test/ViewTwo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ namespace Splat.Common.Test
public class ViewTwo : IViewFor<ViewModelTwo>
{
/// <inheritdoc />
object IViewFor.ViewModel
object? IViewFor.ViewModel
{
get => ViewModel;
set => ViewModel = (ViewModelTwo)value;
set => ViewModel = (ViewModelTwo?)value;
}

/// <inheritdoc />
public ViewModelTwo ViewModel { get; set; }
public ViewModelTwo? ViewModel { get; set; }
}
}
4 changes: 3 additions & 1 deletion src/Splat.Drawing.Tests/BitmapLoaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Xunit;

#if !NETSTANDARD2_0

namespace Splat.Tests
{
/// <summary>
Expand Down Expand Up @@ -100,9 +101,10 @@ private static Stream GetStream(string imageName)
return Android.App.Application.Context.Assets.Open(imageName);
#else
var assembly = Assembly.GetExecutingAssembly();
return assembly.GetManifestResourceStream(imageName);
return assembly.GetManifestResourceStream(imageName)!;
#endif
}
}
}

#endif
2 changes: 1 addition & 1 deletion src/Splat.Drawing.Tests/Colors/SplatColorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ private static IEnumerable<object[]> GetEnumAsTestTheory()
var results = new List<object[]>(values.Length);
foreach (var value in values)
{
results.Add(new[] { value });
results.Add(new[] { value! });
}

return results;
Expand Down
1 change: 1 addition & 0 deletions src/Splat.Drawing.Tests/Splat.Drawing.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<IsPackable>false</IsPackable>
<NoWarn>$(NoWarn);1591;CA1707;SA1633;CA2000;CA1034</NoWarn>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>

<PropertyGroup Condition="'$(OS)' == 'Windows_NT' ">
Expand Down
1 change: 1 addition & 0 deletions src/Splat.DryIoc.Tests/Splat.DryIoc.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFrameworks>net5.0;netcoreapp3.1</TargetFrameworks>
<NoWarn>$(NoWarn);1591;CA1707;SA1633;CA2000</NoWarn>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
8 changes: 4 additions & 4 deletions src/Splat.DryIoc/DryIocDependencyResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ public DryIocDependencyResolver(IContainer? container = null)
}

/// <inheritdoc />
public virtual object? GetService(Type serviceType, string? contract = null) =>
public virtual object GetService(Type serviceType, string? contract = null) =>
string.IsNullOrEmpty(contract)
? _container.ResolveMany(serviceType).LastOrDefault()
: _container.ResolveMany(serviceType, serviceKey: contract).LastOrDefault();
? _container.ResolveMany(serviceType).LastOrDefault()!
: _container.ResolveMany(serviceType, serviceKey: contract).LastOrDefault()!;

/// <inheritdoc />
public virtual IEnumerable<object> GetServices(Type serviceType, string? contract = null) =>
Expand Down Expand Up @@ -61,7 +61,7 @@ public bool HasRegistration(Type serviceType, string? contract = null)
}

/// <inheritdoc />
public virtual void Register(Func<object> factory, Type serviceType, string? contract = null)
public virtual void Register(Func<object?> factory, Type serviceType, string? contract = null)
{
if (factory is null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,17 @@ internal class ContainerWrapper
{
private IServiceProvider _serviceProvider;

#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.

public ContainerWrapper()
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
{
ServiceCollection.UseMicrosoftDependencyResolver();
}

public IServiceCollection ServiceCollection { get; } = new ServiceCollection();

public IServiceProvider ServiceProvider
{
get
{
if (_serviceProvider is null)
{
_serviceProvider = ServiceCollection.BuildServiceProvider();
}

return _serviceProvider;
}
}
public IServiceProvider ServiceProvider => _serviceProvider ??= ServiceCollection.BuildServiceProvider();

public void BuildAndUse() => ServiceProvider.UseMicrosoftDependencyResolver();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
using Microsoft.Extensions.DependencyInjection;

using Splat.Common.Test;

using Splat.NLog;
using Xunit;

namespace Splat.Microsoft.Extensions.DependencyInjection.Tests
Expand Down Expand Up @@ -147,5 +147,28 @@ public void MicrosoftDependencyResolver_Should_Throw_If_Attempt_Registration_Aft

result.Should().BeOfType<InvalidOperationException>();
}

/// <summary>
/// Tests to ensure NLog registers correctly with different service locators.
/// Based on issue reported in #553.
/// </summary>
[Fact]
public void ILogManager_Resolvable()
{
var wrapper = new ContainerWrapper();
var services = wrapper.ServiceCollection;

// Setup NLog for Logging (doesn't matter if I actually configure NLog or not)
var funcLogManager = new FuncLogManager(type => new NLogLogger(LogResolver.Resolve(type)));
services.AddSingleton<ILogManager>(funcLogManager);

wrapper.BuildAndUse();

// Get the ILogManager instance.
ILogManager lm = Locator.Current.GetService<ILogManager>();

var mgr = lm.GetLogger<NLogLogger>();
Assert.NotNull(mgr);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Extensions.DependencyInjection;
using Splat.Microsoft.Extensions.DependencyInjection;
using Xunit;

Expand All @@ -21,16 +22,16 @@ public void Can_Register_And_Resolve_Null_Types()
{
var resolver = GetDependencyResolver();
var foo = 5;
resolver.Register(() => foo, null);
resolver.Register(() => foo, null!);

var value = resolver.GetService(null);
var value = resolver.GetService(null!);
Assert.Equal(foo, value);

var bar = 4;
var contract = "foo";
resolver.Register(() => bar, null, contract);
resolver.Register(() => bar, null!, contract);

value = resolver.GetService(null, contract);
value = resolver.GetService(null!, contract);
Assert.Equal(bar, value);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
<NoWarn>$(NoWarn);1591;CA1707;SA1633;CA2000</NoWarn>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<Compile Include="..\Splat.NLog\LogResolver.cs" Link="LogResolver.cs" />
<Compile Include="..\Splat.Tests\ServiceLocation\BaseDependencyResolverTests.cs" Link="BaseDependencyResolverTests.cs" />
</ItemGroup>

Expand Down
Loading