Skip to content

Commit

Permalink
Throw exception when unable to resolve service.
Browse files Browse the repository at this point in the history
  • Loading branch information
mayuki committed Feb 4, 2020
1 parent 5eecf52 commit 494484a
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/Cocona.Lite/Lite/CoconaLiteInstanceActivator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class CoconaLiteInstanceActivator : ICoconaInstanceActivator

public object? CreateInstance(IServiceProvider serviceProvider, Type instanceType, object[]? parameters)
{
if (parameters != null && parameters.Length > 0) throw new ArgumentException("SimpleCoconaInstanceActivator doesn't support extra arguments.", nameof(parameters));
if (parameters != null && parameters.Length > 0) throw new NotSupportedException("SimpleCoconaInstanceActivator doesn't support extra arguments.");
return SimpleActivator.CreateInstance(serviceProvider, instanceType);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/Cocona.Lite/Lite/SimpleActivator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ public static object CreateInstance(IServiceProvider serviceProvider, Type type)

for (var i = 0; i < bestMatchCtorParameters.Length; i++)
{
parameterValues[i] = serviceProvider.GetService(bestMatchCtorParameters[i].ParameterType);
var value = serviceProvider.GetService(bestMatchCtorParameters[i].ParameterType);
parameterValues[i] = value ?? throw new InvalidOperationException($"Unable to resolve service for type '{bestMatchCtorParameters[i].ParameterType.FullName}' while attempting to activate '{type.FullName}'");
}

return bestMatchCtor.Invoke(parameterValues);
Expand Down
91 changes: 91 additions & 0 deletions test/Cocona.Lite.Test/CoconaLiteInstanceActivatorTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Text;
using FluentAssertions;
using Xunit;

namespace Cocona.Lite.Test
{
public class CoconaLiteInstanceActivatorTest
{
[Fact]
public void GetServiceOrCreateInstance_FromService()
{
var serviceProvider = new FakeServiceProvider();
serviceProvider.ValueByType[typeof(GetServiceOrCreateInstance_FromService_Target)] = new GetServiceOrCreateInstance_FromService_Target();

var activator = new CoconaLiteInstanceActivator();
var obj = activator.GetServiceOrCreateInstance(serviceProvider, typeof(GetServiceOrCreateInstance_FromService_Target));
obj.Should().Be(serviceProvider.ValueByType[typeof(GetServiceOrCreateInstance_FromService_Target)]);
}
class GetServiceOrCreateInstance_FromService_Target
{ }

[Fact]
public void GetServiceOrCreateInstance_CreateInstance()
{
var serviceProvider = new FakeServiceProvider();

var activator = new CoconaLiteInstanceActivator();
var obj = activator.GetServiceOrCreateInstance(serviceProvider, typeof(GetServiceOrCreateInstance_CreateInstance_Target));
obj.Should().NotBeNull();
}
class GetServiceOrCreateInstance_CreateInstance_Target
{ }

[Fact]
public void CreateInstance_Insufficient()
{
var serviceProvider = new FakeServiceProvider();

var activator = new CoconaLiteInstanceActivator();
var ex = Assert.Throws<InvalidOperationException>(() => activator.CreateInstance(serviceProvider, typeof(CreateInstance_NoAdditionalParameter_Target), Array.Empty<object>()));
ex.Message.Should().Be("Unable to resolve service for type 'System.String' while attempting to activate 'Cocona.Lite.Test.CoconaLiteInstanceActivatorTest+CreateInstance_NoAdditionalParameter_Target'");
}

[Fact]
public void CreateInstance_NoAdditionalParameter()
{
var serviceProvider = new FakeServiceProvider();
serviceProvider.ValueByType[typeof(int)] = 123;
serviceProvider.ValueByType[typeof(string)] = "Hello Konnichiwa!";

var activator = new CoconaLiteInstanceActivator();
var obj = activator.CreateInstance(serviceProvider, typeof(CreateInstance_NoAdditionalParameter_Target), Array.Empty<object>());
obj.Should().BeOfType<CreateInstance_NoAdditionalParameter_Target>();
((CreateInstance_NoAdditionalParameter_Target)obj).Value0.Should().Be("Hello Konnichiwa!");
((CreateInstance_NoAdditionalParameter_Target)obj).Value1.Should().Be(123);
}

[Fact]
public void CreateInstance_AdditionalParameter_NotSupported()
{
var serviceProvider = new FakeServiceProvider();

var activator = new CoconaLiteInstanceActivator();
var ex = Assert.Throws<NotSupportedException>(() => activator.CreateInstance(serviceProvider, typeof(CreateInstance_NoAdditionalParameter_Target), new object[] { 123, "Hello Konnichiwa!" }));
}

class CreateInstance_NoAdditionalParameter_Target
{
public string Value0;
public int Value1;

public CreateInstance_NoAdditionalParameter_Target(string value0, int value1)
{
Value0 = value0;
Value1 = value1;
}
}

class FakeServiceProvider : IServiceProvider
{
public Dictionary<Type, object> ValueByType { get; } = new Dictionary<Type, object>();

public object GetService(Type serviceType)
{
return ValueByType.TryGetValue(serviceType, out var value) ? value : default;
}
}
}
}

0 comments on commit 494484a

Please sign in to comment.