Skip to content

Commit

Permalink
- Fix isues #148 #117
Browse files Browse the repository at this point in the history
  • Loading branch information
Oleksandr Tolstikov authored and khellang committed Jan 28, 2022
1 parent 4b7ff01 commit 39a690a
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
11 changes: 9 additions & 2 deletions src/Scrutor/ServiceCollectionExtensions.Decoration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,16 @@ private static object GetInstance(this IServiceProvider provider, ServiceDescrip
return descriptor.ImplementationInstance;
}

if (descriptor.ImplementationType != null)
// Not suppose to be abstract.
Type implementationType = descriptor.ImplementationType;
if (implementationType != null)
{
return provider.GetServiceOrCreateInstance(descriptor.ImplementationType);
if (implementationType != descriptor.ServiceType)
return provider.GetServiceOrCreateInstance(descriptor.ImplementationType);

// Since implementationType is equal to ServiceType we need explicitly create an implementation type through reflections in order to avoid infinite recursion.
// Should not cause issue with singletons, since singleton will be a decorator and after this fact we can don't care about lifecycle of decorable service (for sure, if IDisposable of decorator disposes underlying type:))
return provider.CreateInstance(implementationType);
}

if (descriptor.ImplementationFactory != null)
Expand Down
40 changes: 40 additions & 0 deletions test/Scrutor.Tests/DecorationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.Extensions.DependencyInjection;
using Xunit;
using System.Linq;
using static Scrutor.Tests.DecorationTests;

namespace Scrutor.Tests
{
Expand Down Expand Up @@ -217,8 +218,47 @@ public void DecoratingNonRegisteredServiceThrows()
Assert.Throws<MissingTypeRegistrationException>(() => ConfigureProvider(services => services.Decorate<IDecoratedService, Decorator>()));
}

[Fact]
public void Issue148_Decorate_IsAbleToDecorateConcreateTypes()
{
var sp = ConfigureProvider(sc =>
{
sc
.AddTransient<IService, SomeRandomService>()
.AddTransient<DecoratedService>()
.Decorate<DecoratedService, Decorator2>();
});

var result = sp.GetService<DecoratedService>() as Decorator2;

Assert.NotNull(result);
Assert.NotNull(result.Inner);
Assert.NotNull(result.Inner.Dependency);
}

public interface IDecoratedService { }

public class DecoratedService
{
public DecoratedService(IService dependency)
{
Dependency = dependency;
}

public IService Dependency { get; }
}

public class Decorator2 : DecoratedService
{
public Decorator2(DecoratedService decoratedService)
: base(null)
{
Inner = decoratedService;
}

public DecoratedService Inner { get; }
}

public interface IService { }

private class SomeRandomService : IService { }
Expand Down

0 comments on commit 39a690a

Please sign in to comment.