-
-
Notifications
You must be signed in to change notification settings - Fork 839
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 #940 from eugbaranov/feature/source-registrar
Registration source registration consistent with module registration
- Loading branch information
Showing
5 changed files
with
298 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,42 @@ | ||
// This software is part of the Autofac IoC container | ||
// Copyright © 2018 Autofac Contributors | ||
// http://autofac.org | ||
// | ||
// Permission is hereby granted, free of charge, to any person | ||
// obtaining a copy of this software and associated documentation | ||
// files (the "Software"), to deal in the Software without | ||
// restriction, including without limitation the rights to use, | ||
// copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the | ||
// Software is furnished to do so, subject to the following | ||
// conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be | ||
// included in all copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
// OTHER DEALINGS IN THE SOFTWARE. | ||
|
||
namespace Autofac.Core.Registration | ||
{ | ||
/// <summary> | ||
/// Interface providing fluent syntax for chaining registration source registrations. | ||
/// </summary> | ||
public interface ISourceRegistrar | ||
{ | ||
/// <summary> | ||
/// Add a registration source to the container. | ||
/// </summary> | ||
/// <param name="registrationSource">The registration source to add.</param> | ||
/// <returns> | ||
/// The <see cref="ISourceRegistrar"/> to allow additional chained registration source registrations. | ||
/// </returns> | ||
ISourceRegistrar RegisterSource(IRegistrationSource registrationSource); | ||
} | ||
} |
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,74 @@ | ||
// This software is part of the Autofac IoC container | ||
// Copyright © 2018 Autofac Contributors | ||
// http://autofac.org | ||
// | ||
// Permission is hereby granted, free of charge, to any person | ||
// obtaining a copy of this software and associated documentation | ||
// files (the "Software"), to deal in the Software without | ||
// restriction, including without limitation the rights to use, | ||
// copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the | ||
// Software is furnished to do so, subject to the following | ||
// conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be | ||
// included in all copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
// OTHER DEALINGS IN THE SOFTWARE. | ||
|
||
using System; | ||
|
||
namespace Autofac.Core.Registration | ||
{ | ||
/// <summary> | ||
/// Basic implementation of the <see cref="ISourceRegistrar"/> | ||
/// interface allowing registration of registration sources into a <see cref="ContainerBuilder"/> | ||
/// in a fluent format. | ||
/// </summary> | ||
internal sealed class SourceRegistrar : ISourceRegistrar | ||
{ | ||
/// <summary> | ||
/// The <see cref="ContainerBuilder"/> into which registrations will be made. | ||
/// </summary> | ||
private readonly ContainerBuilder _builder; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="SourceRegistrar"/> class. | ||
/// </summary> | ||
/// <param name="builder"> | ||
/// The <see cref="ContainerBuilder"/> into which registrations will be made. | ||
/// </param> | ||
/// <exception cref="ArgumentNullException"> | ||
/// Thrown if <paramref name="builder" /> is <see langword="null" />. | ||
/// </exception> | ||
public SourceRegistrar(ContainerBuilder builder) | ||
{ | ||
_builder = builder ?? throw new ArgumentNullException(nameof(builder)); | ||
} | ||
|
||
/// <summary> | ||
/// Add a registration source to the container. | ||
/// </summary> | ||
/// <param name="registrationSource">The registration source to add.</param> | ||
/// <returns> | ||
/// The <see cref="ISourceRegistrar"/> to allow additional chained registration source registrations. | ||
/// </returns> | ||
/// <exception cref="ArgumentNullException"> | ||
/// Thrown if <paramref name="registrationSource" /> is <see langword="null" />. | ||
/// </exception> | ||
public ISourceRegistrar RegisterSource(IRegistrationSource registrationSource) | ||
{ | ||
if (registrationSource == null) throw new ArgumentNullException(nameof(registrationSource)); | ||
|
||
_builder.RegisterCallback(cr => cr.AddRegistrationSource(registrationSource)); | ||
return this; | ||
} | ||
} | ||
} |
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 @@ | ||
// This software is part of the Autofac IoC container | ||
// Copyright © 2018 Autofac Contributors | ||
// http://autofac.org | ||
// | ||
// Permission is hereby granted, free of charge, to any person | ||
// obtaining a copy of this software and associated documentation | ||
// files (the "Software"), to deal in the Software without | ||
// restriction, including without limitation the rights to use, | ||
// copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the | ||
// Software is furnished to do so, subject to the following | ||
// conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be | ||
// included in all copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
// OTHER DEALINGS IN THE SOFTWARE. | ||
|
||
using System; | ||
using Autofac.Core; | ||
using Autofac.Core.Registration; | ||
|
||
namespace Autofac | ||
{ | ||
/// <summary> | ||
/// Extension methods for registering <see cref="IRegistrationSource"/> instances with a container. | ||
/// </summary> | ||
public static class SourceRegistrationExtensions | ||
{ | ||
/// <summary> | ||
/// Add a registration source to the container. | ||
/// </summary> | ||
/// <param name="builder">The builder to register the registration source with.</param> | ||
/// <typeparam name="TRegistrationSource">The registration source to add.</typeparam> | ||
/// <exception cref="ArgumentNullException"> | ||
/// Thrown if <paramref name="builder"/> is <see langword="null"/>. | ||
/// </exception> | ||
/// <returns> | ||
/// The <see cref="ISourceRegistrar"/> to allow additional chained registration source registrations. | ||
/// </returns> | ||
public static ISourceRegistrar RegisterSource<TRegistrationSource>(this ContainerBuilder builder) | ||
where TRegistrationSource : IRegistrationSource, new() | ||
{ | ||
if (builder == null) throw new ArgumentNullException(nameof(builder)); | ||
|
||
var registrar = new SourceRegistrar(builder); | ||
return registrar.RegisterSource<TRegistrationSource>(); | ||
} | ||
|
||
/// <summary> | ||
/// Add a registration source to the container. | ||
/// </summary> | ||
/// <param name="registrar">The source registrar that will make the registration into the container.</param> | ||
/// <typeparam name="TRegistrationSource">The registration source to add.</typeparam> | ||
/// <exception cref="ArgumentNullException"> | ||
/// Thrown if <paramref name="registrar"/> is <see langword="null"/>. | ||
/// </exception> | ||
/// <returns> | ||
/// The <see cref="ISourceRegistrar"/> to allow additional chained registration source registrations. | ||
/// </returns> | ||
public static ISourceRegistrar RegisterSource<TRegistrationSource>(this ISourceRegistrar registrar) | ||
where TRegistrationSource : IRegistrationSource, new() | ||
{ | ||
if (registrar == null) throw new ArgumentNullException(nameof(registrar)); | ||
|
||
return registrar.RegisterSource(new TRegistrationSource()); | ||
} | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
test/Autofac.Test/Core/Registration/SourceRegistrarTests.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,50 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using Autofac.Core.Registration; | ||
using Autofac.Test.Scenarios.RegistrationSources; | ||
using Xunit; | ||
|
||
namespace Autofac.Test.Core.Registration | ||
{ | ||
public sealed class SourceRegistrarTests | ||
{ | ||
private static readonly object O1 = new object(); | ||
private static readonly object O2 = new object(); | ||
|
||
[Fact] | ||
public void Ctor_RequiresContainerBuilder() | ||
{ | ||
Assert.Throws<ArgumentNullException>(() => new SourceRegistrar(null)); | ||
} | ||
|
||
[Fact] | ||
public void RegisterSource_ChainsSourceRegistrations() | ||
{ | ||
var builder = new ContainerBuilder(); | ||
var registrar = new SourceRegistrar(builder); | ||
|
||
registrar.RegisterSource<SourceA>() | ||
.RegisterSource(new ObjectRegistrationSource(O2)); | ||
|
||
var container = builder.Build(); | ||
var objects = container.Resolve<IEnumerable<object>>(); | ||
Assert.Contains(O1, objects); | ||
Assert.Contains(O2, objects); | ||
} | ||
|
||
[Fact] | ||
public void RegisterSource_RequiresRegistrationSource() | ||
{ | ||
var registrar = new SourceRegistrar(new ContainerBuilder()); | ||
Assert.Throws<ArgumentNullException>(() => registrar.RegisterSource(null)); | ||
} | ||
|
||
private class SourceA : ObjectRegistrationSource | ||
{ | ||
public SourceA() | ||
: base(O1) | ||
{ | ||
} | ||
} | ||
} | ||
} |
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,56 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Autofac.Core; | ||
using Autofac.Test.Scenarios.RegistrationSources; | ||
using Xunit; | ||
|
||
namespace Autofac.Test | ||
{ | ||
public sealed class SourceRegistrationExtensionsTests | ||
{ | ||
[Fact] | ||
public void RegisterSource() | ||
{ | ||
var source = new EmptyRegistrationSource(); | ||
var builder = new ContainerBuilder(); | ||
|
||
builder.RegisterSource(source); | ||
|
||
Assert.False(source.RegistrationsForCalled); | ||
using (var container = builder.Build()) | ||
{ | ||
Assert.True(source.RegistrationsForCalled); | ||
} | ||
|
||
new ObjectRegistrationSource(); | ||
} | ||
|
||
[Fact] | ||
public void RegisterObjectSource() | ||
{ | ||
var builder = new ContainerBuilder(); | ||
|
||
builder.RegisterSource<ObjectRegistrationSource>(); | ||
|
||
using (var container = builder.Build()) | ||
{ | ||
var service = container.Resolve<object>(); | ||
Assert.NotNull(service); | ||
} | ||
} | ||
|
||
private sealed class EmptyRegistrationSource : IRegistrationSource | ||
{ | ||
public bool RegistrationsForCalled { get; private set; } | ||
|
||
public bool IsAdapterForIndividualComponents => false; | ||
|
||
public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor) | ||
{ | ||
RegistrationsForCalled = true; | ||
return Enumerable.Empty<IComponentRegistration>(); | ||
} | ||
} | ||
} | ||
} |