Skip to content

Commit

Permalink
Merge pull request #547 from seesharper/bugfix/initializer
Browse files Browse the repository at this point in the history
Bugfix/initializer
  • Loading branch information
seesharper authored Oct 19, 2020
2 parents 4714d1b + 15be522 commit 751db2a
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 23 deletions.
31 changes: 31 additions & 0 deletions src/LightInject.Tests/ServiceContainerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1686,6 +1686,37 @@ public void GetInstance_UsingInitializer_ReturnsInstance()
Assert.IsAssignableFrom<Bar>(foo.Bar);
}

[Fact]
public void GetInstance_UsingInitializerWithDecoratedService_PassesDecoratorAsInstance()
{
var container = CreateContainer();
container.Register<IFoo, Foo>();
container.Decorate<IFoo, FooDecorator>();
container.Initialize<IFoo>((factory, instance) =>
{
Assert.IsType<FooDecorator>(instance);
});

container.GetInstance<IFoo>();
}

[Fact]
public void GetInstance_UsingInitializer_PassesScopeAsServiceFactory()
{
var container = CreateContainer();
container.Register<IFoo, Foo>();
IServiceFactory passedFactory = null;
container.Initialize<IFoo>((factory, instance) => { passedFactory = factory; });

using (var scope = container.BeginScope())
{
scope.GetInstance<IFoo>();
Assert.Same(scope, passedFactory);
}
}




#if NET452 || NET40 || NET46 || NETCOREAPP2_0
[Fact]
Expand Down
59 changes: 37 additions & 22 deletions src/LightInject/LightInject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1607,6 +1607,16 @@ public static IServiceRegistry Override<TService, TImplementation>(this IService
return registration;
});
}

/// <summary>
/// Allows post-processing of a service instance.
/// </summary>
/// <param name="serviceRegistry">The target <see cref="IServiceRegistry"/>.</param>
/// <param name="processor">An action delegate that exposes the created service instance.</param>
/// <typeparam name="TService">The type of service to initialize.</typeparam>
/// <returns>The <see cref="IServiceRegistry"/>, for chaining calls.</returns>
public static IServiceRegistry Initialize<TService>(this IServiceRegistry serviceRegistry, Action<IServiceFactory, TService> processor)
=> serviceRegistry.Initialize(sr => sr.ServiceType == typeof(TService), (factory, instance) => processor(factory, (TService)instance));
}

/// <summary>
Expand Down Expand Up @@ -3865,28 +3875,6 @@ private void EmitNewInstance(ServiceRegistration serviceRegistration, IEmitter e
EmitNewInstanceUsingImplementingType(emitter, constructionInfo, null);
}
}

var processors = initializers.Items.Where(i => i.Predicate(serviceRegistration)).ToArray();
if (processors.Length == 0)
{
return;
}

LocalBuilder instanceVariable = emitter.DeclareLocal(serviceRegistration.ServiceType);
emitter.Store(instanceVariable);
foreach (var postProcessor in processors)
{
Type delegateType = postProcessor.Initialize.GetType();
var delegateIndex = constants.Add(postProcessor.Initialize);
emitter.PushConstant(delegateIndex, delegateType);
var serviceFactoryIndex = constants.Add(this);
emitter.PushConstant(serviceFactoryIndex, typeof(IServiceFactory));
emitter.Push(instanceVariable);
MethodInfo invokeMethod = delegateType.GetTypeInfo().GetDeclaredMethod("Invoke");
emitter.Call(invokeMethod);
}

emitter.Push(instanceVariable);
}

private void EmitDecorators(ServiceRegistration serviceRegistration, IEnumerable<DecoratorRegistration> serviceDecorators, IEmitter emitter, Action<IEmitter> decoratorTargetEmitMethod)
Expand Down Expand Up @@ -4670,6 +4658,33 @@ private void EmitNewInstanceWithDecorators(ServiceRegistration serviceRegistrati
{
EmitNewInstance(serviceRegistration, emitter);
}

var processors = initializers.Items.Where(i => i.Predicate(serviceRegistration)).ToArray();
if (processors.Length == 0)
{
return;
}

LocalBuilder instanceVariable = emitter.DeclareLocal(serviceRegistration.ServiceType);
emitter.Store(instanceVariable);
foreach (var postProcessor in processors)
{
Type delegateType = postProcessor.Initialize.GetType();
var delegateIndex = constants.Add(postProcessor.Initialize);
emitter.PushConstant(delegateIndex, delegateType);

var serviceFactoryIndex = constants.Add(this);
emitter.PushConstant(serviceFactoryIndex, typeof(IServiceFactory));
var scopeManagerIndex = CreateScopeManagerIndex();
emitter.PushConstant(scopeManagerIndex, typeof(IScopeManager));
emitter.PushArgument(1);
emitter.Emit(OpCodes.Call, ServiceFactoryLoader.LoadServiceFactoryMethod);
emitter.Push(instanceVariable);
MethodInfo invokeMethod = delegateType.GetTypeInfo().GetDeclaredMethod("Invoke");
emitter.Call(invokeMethod);
}

emitter.Push(instanceVariable);
}

private void EmitLifetime(ServiceRegistration serviceRegistration, Action<IEmitter> emitMethod, IEmitter emitter)
Expand Down
2 changes: 1 addition & 1 deletion src/LightInject/LightInject.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0;netstandard2.0;netstandard1.6;netstandard1.3;netstandard1.1;net46;net452</TargetFrameworks>
<!-- <TargetFrameworks>netstandard2.0;netcoreapp2.0;netstandard1.6;netstandard1.3;netstandard1.1;net46;net452</TargetFrameworks> -->
<Version>6.3.6</Version>
<Version>6.4.0</Version>
<Authors>Bernhard Richter</Authors>
<PackageProjectUrl>https://www.lightinject.net</PackageProjectUrl>
<RepositoryType>git</RepositoryType>
Expand Down

0 comments on commit 751db2a

Please sign in to comment.