diff --git a/src/Autofac/Autofac.csproj b/src/Autofac/Autofac.csproj
index a1d521c9c..1040687dd 100644
--- a/src/Autofac/Autofac.csproj
+++ b/src/Autofac/Autofac.csproj
@@ -4,7 +4,7 @@
Autofac is an IoC container for Microsoft .NET. It manages the dependencies between classes so that applications stay easy to change as they grow in size and complexity.
4.8.1
netstandard1.1;net45
- $(NoWarn);CS1591
+ $(NoWarn);CS1591;CA1819
true
true
Autofac
diff --git a/src/Autofac/Builder/ContainerBuildOptions.cs b/src/Autofac/Builder/ContainerBuildOptions.cs
index 5db5df1d8..ae930c1f6 100644
--- a/src/Autofac/Builder/ContainerBuildOptions.cs
+++ b/src/Autofac/Builder/ContainerBuildOptions.cs
@@ -39,12 +39,6 @@ public enum ContainerBuildOptions
///
None = 0,
- ///
- /// Prevents inclusion of standard modules like support for
- /// relationship types including etc.
- ///
- ExcludeDefaultModules = 2,
-
///
/// Does not call on components implementing
/// this interface (useful for module testing.)
diff --git a/src/Autofac/Builder/IRegistrationBuilder.cs b/src/Autofac/Builder/IRegistrationBuilder.cs
index 6734f4871..e1babdc36 100644
--- a/src/Autofac/Builder/IRegistrationBuilder.cs
+++ b/src/Autofac/Builder/IRegistrationBuilder.cs
@@ -278,5 +278,19 @@ public interface IRegistrationBuilder
/// A registration builder allowing further configuration of the component.
IRegistrationBuilder WithMetadata(Action> configurationAction);
+
+ ///
+ /// Configure the services that the component will provide.
+ ///
+ /// Service types to expose.
+ /// A registration builder allowing further configuration of the component.
+ IRegistrationBuilder As(Type service);
+
+ ///
+ /// Configure the services that the component will provide.
+ ///
+ /// Services to expose.
+ /// A registration builder allowing further configuration of the component.
+ IRegistrationBuilder As(Service service);
}
}
diff --git a/src/Autofac/Builder/ReflectionActivatorData.cs b/src/Autofac/Builder/ReflectionActivatorData.cs
index 0efbd539f..34e8e7224 100644
--- a/src/Autofac/Builder/ReflectionActivatorData.cs
+++ b/src/Autofac/Builder/ReflectionActivatorData.cs
@@ -108,11 +108,11 @@ public IConstructorSelector ConstructorSelector
///
/// Gets the explicitly bound constructor parameters.
///
- public IList ConfiguredParameters { get; } = new List();
+ public List ConfiguredParameters { get; } = new List();
///
/// Gets the explicitly bound properties.
///
- public IList ConfiguredProperties { get; } = new List();
+ public List ConfiguredProperties { get; } = new List();
}
}
diff --git a/src/Autofac/Builder/RegistrationBuilder.cs b/src/Autofac/Builder/RegistrationBuilder.cs
index 39e3129ee..e9ca8f67e 100644
--- a/src/Autofac/Builder/RegistrationBuilder.cs
+++ b/src/Autofac/Builder/RegistrationBuilder.cs
@@ -133,7 +133,7 @@ public static class RegistrationBuilder
builder.RegistrationStyle.Id,
builder.RegistrationData,
builder.ActivatorData.Activator,
- builder.RegistrationData.Services,
+ builder.RegistrationData.Services.ToArray(),
builder.RegistrationStyle.Target);
}
@@ -149,7 +149,7 @@ public static class RegistrationBuilder
Guid id,
RegistrationData data,
IInstanceActivator activator,
- IEnumerable services)
+ Service[] services)
{
return CreateRegistration(id, data, activator, services, null);
}
@@ -170,7 +170,7 @@ public static class RegistrationBuilder
Guid id,
RegistrationData data,
IInstanceActivator activator,
- IEnumerable services,
+ Service[] services,
IComponentRegistration target)
{
if (activator == null) throw new ArgumentNullException(nameof(activator));
@@ -179,11 +179,15 @@ public static class RegistrationBuilder
var limitType = activator.LimitType;
if (limitType != typeof(object))
{
- foreach (var ts in services.OfType())
+ foreach (var ts in services)
{
- if (!ts.ServiceType.GetTypeInfo().IsAssignableFrom(limitType.GetTypeInfo()))
+ var asServiceWithType = ts as IServiceWithType;
+ if (asServiceWithType != null)
{
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, RegistrationBuilderResources.ComponentDoesNotSupportService, limitType, ts));
+ if (!asServiceWithType.ServiceType.GetTypeInfo().IsAssignableFrom(limitType.GetTypeInfo()))
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, RegistrationBuilderResources.ComponentDoesNotSupportService, limitType, ts));
+ }
}
}
}
diff --git a/src/Autofac/Builder/RegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.cs b/src/Autofac/Builder/RegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.cs
index cf2ed5f15..22729e692 100644
--- a/src/Autofac/Builder/RegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.cs
+++ b/src/Autofac/Builder/RegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.cs
@@ -241,11 +241,27 @@ public RegistrationBuilder(Service defaultService, TActivatorData activatorData,
/// A registration builder allowing further configuration of the component.
public IRegistrationBuilder As(params Type[] services)
{
- return As(services.Select(t =>
- t.FullName != null
- ? new TypedService(t)
- : new TypedService(t.GetGenericTypeDefinition()))
- .Cast().ToArray());
+ Service[] argArray = new Service[services.Length];
+
+ for (int i = 0; i < services.Length; i++)
+ {
+ if (services[i].FullName != null)
+ argArray[i] = new TypedService(services[i]);
+ else
+ argArray[i] = new TypedService(services[i].GetGenericTypeDefinition());
+ }
+
+ return As(argArray);
+ }
+
+ ///
+ /// Configure the services that the component will provide.
+ ///
+ /// Service types to expose.
+ /// A registration builder allowing further configuration of the component.
+ public IRegistrationBuilder As(Type service)
+ {
+ return As(new TypedService(service));
}
///
@@ -262,6 +278,20 @@ public RegistrationBuilder(Service defaultService, TActivatorData activatorData,
return this;
}
+ ///
+ /// Configure the services that the component will provide.
+ ///
+ /// Services to expose.
+ /// A registration builder allowing further configuration of the component.
+ public IRegistrationBuilder As(Service service)
+ {
+ if (service == null) throw new ArgumentNullException(nameof(service));
+
+ RegistrationData.AddService(service);
+
+ return this;
+ }
+
///
/// Provide a textual name that can be used to retrieve the component.
///
diff --git a/src/Autofac/Builder/RegistrationData.cs b/src/Autofac/Builder/RegistrationData.cs
index 5f1b8f2cb..ad0fd2a4e 100644
--- a/src/Autofac/Builder/RegistrationData.cs
+++ b/src/Autofac/Builder/RegistrationData.cs
@@ -41,7 +41,7 @@ public class RegistrationData
private bool _defaultServiceOverridden;
private Service _defaultService;
- private readonly ICollection _services = new HashSet();
+ private readonly HashSet _services = new HashSet();
private IComponentLifetime _lifetime = new CurrentScopeLifetime();
@@ -56,7 +56,7 @@ public RegistrationData(Service defaultService)
_defaultService = defaultService;
- Metadata = new Dictionary
+ Metadata = new Dictionary(1)
{
{ MetadataKeys.RegistrationOrderMetadataKey, SequenceGenerator.GetNextUniqueSequence() },
};
@@ -147,17 +147,17 @@ public IComponentLifetime Lifetime
///
/// Gets the handlers for the Preparing event.
///
- public ICollection> PreparingHandlers { get; } = new List>();
+ public List> PreparingHandlers { get; } = new List>();
///
/// Gets the handlers for the Activating event.
///
- public ICollection>> ActivatingHandlers { get; } = new List>>();
+ public List>> ActivatingHandlers { get; } = new List>>();
///
/// Gets the handlers for the Activated event.
///
- public ICollection>> ActivatedHandlers { get; } = new List>>();
+ public List>> ActivatedHandlers { get; } = new List>>();
///
/// Copies the contents of another RegistrationData object into this one.
diff --git a/src/Autofac/Builder/SingleRegistrationStyle.cs b/src/Autofac/Builder/SingleRegistrationStyle.cs
index 7bd3593a7..90df3f376 100644
--- a/src/Autofac/Builder/SingleRegistrationStyle.cs
+++ b/src/Autofac/Builder/SingleRegistrationStyle.cs
@@ -42,7 +42,7 @@ public class SingleRegistrationStyle
///
/// Gets the handlers to notify of the component registration event.
///
- public ICollection> RegisteredHandlers { get; } = new List>();
+ public List> RegisteredHandlers { get; } = new List>();
///
/// Gets or sets a value indicating whether default registrations should be preserved.
diff --git a/src/Autofac/ContainerBuilder.cs b/src/Autofac/ContainerBuilder.cs
index 388dfbc80..8f0f5b81a 100644
--- a/src/Autofac/ContainerBuilder.cs
+++ b/src/Autofac/ContainerBuilder.cs
@@ -131,6 +131,7 @@ public ContainerBuilder RegisterBuildCallback(Action buildCallback)
/// Create a new container with the component registrations that have been made.
///
/// Options that influence the way the container is initialised.
+ /// Defines which default services should be enabled.
///
/// Build can only be called once per
/// - this prevents ownership issues for provided instances.
@@ -139,11 +140,11 @@ public ContainerBuilder RegisterBuildCallback(Action buildCallback)
/// first create the container, then call Update() on the builder.
///
/// A new container with the configured component registrations.
- public IContainer Build(ContainerBuildOptions options = ContainerBuildOptions.None)
+ public IContainer Build(ContainerBuildOptions options = ContainerBuildOptions.None, DefaultServiceFlags flags = DefaultServiceFlags.All)
{
var result = new Container(Properties);
result.ComponentRegistry.Properties[MetadataKeys.ContainerBuildOptions] = options;
- Build(result.ComponentRegistry, (options & ContainerBuildOptions.ExcludeDefaultModules) != ContainerBuildOptions.None);
+ Build(result.ComponentRegistry, flags);
if ((options & ContainerBuildOptions.IgnoreStartableComponents) == ContainerBuildOptions.None)
StartableManager.StartStartableComponents(result);
@@ -206,7 +207,7 @@ public void Update(IContainer container, ContainerBuildOptions options)
[Obsolete("Containers should generally be considered immutable. Register all of your dependencies before building/resolving. If you need to change the contents of a container, you technically should rebuild the container. This method may be removed in a future major release.")]
public void Update(IComponentRegistry componentRegistry)
{
- this.UpdateRegistry(componentRegistry);
+ UpdateRegistry(componentRegistry);
}
///
@@ -222,10 +223,10 @@ public void Update(IComponentRegistry componentRegistry)
internal void UpdateRegistry(IComponentRegistry componentRegistry)
{
if (componentRegistry == null) throw new ArgumentNullException(nameof(componentRegistry));
- Build(componentRegistry, true);
+ Build(componentRegistry, DefaultServiceFlags.None);
}
- private void Build(IComponentRegistry componentRegistry, bool excludeDefaultModules)
+ private void Build(IComponentRegistry componentRegistry, DefaultServiceFlags flags = DefaultServiceFlags.None)
{
if (componentRegistry == null) throw new ArgumentNullException(nameof(componentRegistry));
@@ -234,23 +235,30 @@ private void Build(IComponentRegistry componentRegistry, bool excludeDefaultModu
_wasBuilt = true;
- if (!excludeDefaultModules)
- RegisterDefaultAdapters(componentRegistry);
+ RegisterDefaultAdapters(componentRegistry, flags);
foreach (var callback in _configurationCallbacks)
callback.Callback(componentRegistry);
}
- private void RegisterDefaultAdapters(IComponentRegistry componentRegistry)
+ private void RegisterDefaultAdapters(IComponentRegistry componentRegistry, DefaultServiceFlags flags)
{
- this.RegisterGeneric(typeof(KeyedServiceIndex<,>)).As(typeof(IIndex<,>)).InstancePerLifetimeScope();
- componentRegistry.AddRegistrationSource(new CollectionRegistrationSource());
- componentRegistry.AddRegistrationSource(new OwnedInstanceRegistrationSource());
- componentRegistry.AddRegistrationSource(new MetaRegistrationSource());
- componentRegistry.AddRegistrationSource(new LazyRegistrationSource());
- componentRegistry.AddRegistrationSource(new LazyWithMetadataRegistrationSource());
- componentRegistry.AddRegistrationSource(new StronglyTypedMetaRegistrationSource());
- componentRegistry.AddRegistrationSource(new GeneratedFactoryRegistrationSource());
+ if ((flags & DefaultServiceFlags.Index) == DefaultServiceFlags.Index)
+ this.RegisterGeneric(typeof(KeyedServiceIndex<,>)).As(new[] { typeof(IIndex<,>) }).InstancePerLifetimeScope();
+ if ((flags & DefaultServiceFlags.Collections) == DefaultServiceFlags.Collections)
+ componentRegistry.AddRegistrationSource(new CollectionRegistrationSource());
+ if ((flags & DefaultServiceFlags.Owned) == DefaultServiceFlags.Owned)
+ componentRegistry.AddRegistrationSource(new OwnedInstanceRegistrationSource());
+ if ((flags & DefaultServiceFlags.Meta) == DefaultServiceFlags.Meta)
+ componentRegistry.AddRegistrationSource(new MetaRegistrationSource());
+ if ((flags & DefaultServiceFlags.Lazy) == DefaultServiceFlags.Lazy)
+ componentRegistry.AddRegistrationSource(new LazyRegistrationSource());
+ if ((flags & DefaultServiceFlags.LazyWithMeta) == DefaultServiceFlags.LazyWithMeta)
+ componentRegistry.AddRegistrationSource(new LazyWithMetadataRegistrationSource());
+ if ((flags & DefaultServiceFlags.StronglyTypedMeta) == DefaultServiceFlags.StronglyTypedMeta)
+ componentRegistry.AddRegistrationSource(new StronglyTypedMetaRegistrationSource());
+ if ((flags & DefaultServiceFlags.GeneratedFactory) == DefaultServiceFlags.GeneratedFactory)
+ componentRegistry.AddRegistrationSource(new GeneratedFactoryRegistrationSource());
}
private List> GetBuildCallbacks()
@@ -258,4 +266,58 @@ private List> GetBuildCallbacks()
return (List>)Properties[BuildCallbackPropertyKey];
}
}
+
+ [Flags]
+ public enum DefaultServiceFlags
+ {
+ ///
+ /// None
+ ///
+ None = 0,
+
+ ///
+ /// Index
+ ///
+ Index = 1,
+
+ ///
+ /// Collection
+ ///
+ Collections = 2,
+
+ ///
+ /// Owned
+ ///
+ Owned = 4,
+
+ ///
+ /// Meta
+ ///
+ Meta = 8,
+
+ ///
+ /// Lazy
+ ///
+ Lazy = 16,
+
+ ///
+ /// LazyWithMeta
+ ///
+ LazyWithMeta = 32,
+
+ ///
+ /// StronglyTypedMeta
+ ///
+ StronglyTypedMeta = 64,
+
+ ///
+ /// GeneratedFactory
+ ///
+ GeneratedFactory = 128,
+
+ ///
+ /// All
+ ///
+ All = Index | Collections | Owned | Meta | Lazy | LazyWithMeta | StronglyTypedMeta | GeneratedFactory
+ }
}
\ No newline at end of file
diff --git a/src/Autofac/Core/Activators/Reflection/ConstructorParameterBinding.cs b/src/Autofac/Core/Activators/Reflection/ConstructorParameterBinding.cs
index 92c052b20..98de71e10 100644
--- a/src/Autofac/Core/Activators/Reflection/ConstructorParameterBinding.cs
+++ b/src/Autofac/Core/Activators/Reflection/ConstructorParameterBinding.cs
@@ -66,7 +66,7 @@ public class ConstructorParameterBinding
/// Context in which to construct instance.
public ConstructorParameterBinding(
ConstructorInfo ci,
- IEnumerable availableParameters,
+ Parameter[] availableParameters,
IComponentContext context)
{
if (ci == null) throw new ArgumentNullException(nameof(ci));
diff --git a/src/Autofac/Core/Activators/Reflection/ReflectionActivator.cs b/src/Autofac/Core/Activators/Reflection/ReflectionActivator.cs
index d97efaff7..d9f24c3be 100644
--- a/src/Autofac/Core/Activators/Reflection/ReflectionActivator.cs
+++ b/src/Autofac/Core/Activators/Reflection/ReflectionActivator.cs
@@ -57,8 +57,8 @@ public class ReflectionActivator : InstanceActivator, IInstanceActivator
Type implementationType,
IConstructorFinder constructorFinder,
IConstructorSelector constructorSelector,
- IEnumerable configuredParameters,
- IEnumerable configuredProperties)
+ IList configuredParameters,
+ IList configuredProperties)
: base(implementationType)
{
if (constructorFinder == null) throw new ArgumentNullException(nameof(constructorFinder));
@@ -70,7 +70,14 @@ public class ReflectionActivator : InstanceActivator, IInstanceActivator
ConstructorFinder = constructorFinder;
ConstructorSelector = constructorSelector;
_configuredProperties = configuredProperties.ToArray();
- _defaultParameters = configuredParameters.Concat(new Parameter[] { new AutowiringParameter(), new DefaultValueParameter() }).ToArray();
+
+ _defaultParameters = new Parameter[configuredParameters.Count + 2];
+
+ for (int i = 0; i < configuredParameters.Count; i++)
+ _defaultParameters[i] = configuredParameters[i];
+
+ _defaultParameters[_defaultParameters.Length - 2] = new AutowiringParameter();
+ _defaultParameters[_defaultParameters.Length - 1] = new DefaultValueParameter();
}
///
@@ -128,10 +135,25 @@ public object ActivateInstance(IComponentContext context, IEnumerable
private ConstructorParameterBinding[] GetValidConstructorBindings(IComponentContext context, IEnumerable parameters)
{
- // Most often, there will be no `parameters` and/or no `_defaultParameters`; in both of those cases we can avoid allocating.
- var prioritisedParameters = parameters.Any() ?
- (_defaultParameters.Length == 0 ? parameters : parameters.Concat(_defaultParameters)) :
- _defaultParameters;
+ // Most often, there will be no `parameters`we can avoid allocating.
+ Parameter[] prioritisedParameters;
+ if (parameters is Parameter[] parametersArray)
+ {
+ if (parametersArray.Length == 0)
+ {
+ prioritisedParameters = _defaultParameters;
+ }
+ else
+ {
+ prioritisedParameters = new Parameter[_defaultParameters.Length + parametersArray.Length];
+ Array.Copy(parametersArray, 0, prioritisedParameters, 0, parametersArray.Length);
+ Array.Copy(_defaultParameters, 0, prioritisedParameters, parametersArray.Length, _defaultParameters.Length);
+ }
+ }
+ else
+ {
+ prioritisedParameters = parameters.Concat(_defaultParameters).ToArray();
+ }
var constructorBindings = new ConstructorParameterBinding[_availableConstructors.Length];
for (var i = 0; i < _availableConstructors.Length; ++i)
diff --git a/src/Autofac/Core/IComponentRegistration.cs b/src/Autofac/Core/IComponentRegistration.cs
index 763db0e76..fb00d83af 100644
--- a/src/Autofac/Core/IComponentRegistration.cs
+++ b/src/Autofac/Core/IComponentRegistration.cs
@@ -63,7 +63,7 @@ public interface IComponentRegistration : IDisposable
///
/// Gets the services provided by the component.
///
- IEnumerable Services { get; }
+ Service[] Services { get; }
///
/// Gets additional data associated with the component.
diff --git a/src/Autofac/Core/Registration/ComponentRegistration.cs b/src/Autofac/Core/Registration/ComponentRegistration.cs
index 8df7e41d4..cc908198c 100644
--- a/src/Autofac/Core/Registration/ComponentRegistration.cs
+++ b/src/Autofac/Core/Registration/ComponentRegistration.cs
@@ -56,20 +56,21 @@ public class ComponentRegistration : Disposable, IComponentRegistration
IComponentLifetime lifetime,
InstanceSharing sharing,
InstanceOwnership ownership,
- IEnumerable services,
+ Service[] services,
IDictionary metadata)
{
if (activator == null) throw new ArgumentNullException(nameof(activator));
if (lifetime == null) throw new ArgumentNullException(nameof(lifetime));
if (services == null) throw new ArgumentNullException(nameof(services));
if (metadata == null) throw new ArgumentNullException(nameof(metadata));
+ Enforce.ArgumentElementNotNull(services, nameof(services));
Id = id;
Activator = activator;
Lifetime = lifetime;
Sharing = sharing;
Ownership = ownership;
- Services = Enforce.ArgumentElementNotNull(services, nameof(services));
+ Services = services;
Metadata = metadata;
}
@@ -90,7 +91,7 @@ public class ComponentRegistration : Disposable, IComponentRegistration
IComponentLifetime lifetime,
InstanceSharing sharing,
InstanceOwnership ownership,
- IEnumerable services,
+ Service[] services,
IDictionary metadata,
IComponentRegistration target)
: this(id, activator, lifetime, sharing, ownership, services, metadata)
@@ -135,7 +136,7 @@ public class ComponentRegistration : Disposable, IComponentRegistration
///
/// Gets the services provided by the component.
///
- public IEnumerable Services { get; }
+ public Service[] Services { get; }
///
/// Gets additional data associated with the component.
diff --git a/src/Autofac/Core/Registration/ComponentRegistrationLifetimeDecorator.cs b/src/Autofac/Core/Registration/ComponentRegistrationLifetimeDecorator.cs
index bd9b2cb50..0632135f4 100644
--- a/src/Autofac/Core/Registration/ComponentRegistrationLifetimeDecorator.cs
+++ b/src/Autofac/Core/Registration/ComponentRegistrationLifetimeDecorator.cs
@@ -54,7 +54,7 @@ public ComponentRegistrationLifetimeDecorator(IComponentRegistration inner, ICom
public InstanceOwnership Ownership => _inner.Ownership;
- public IEnumerable Services => _inner.Services;
+ public Service[] Services => _inner.Services;
public IDictionary Metadata => _inner.Metadata;
diff --git a/src/Autofac/Core/Registration/ComponentRegistry.cs b/src/Autofac/Core/Registration/ComponentRegistry.cs
index 4baf220c9..1148517a2 100644
--- a/src/Autofac/Core/Registration/ComponentRegistry.cs
+++ b/src/Autofac/Core/Registration/ComponentRegistry.cs
@@ -52,17 +52,17 @@ public class ComponentRegistry : Disposable, IComponentRegistry
///
/// External registration sources.
///
- private readonly IList _dynamicRegistrationSources = new List();
+ private readonly List _dynamicRegistrationSources = new List();
///
/// All registrations.
///
- private readonly ICollection _registrations = new List();
+ private readonly List _registrations = new List();
///
/// Keeps track of the status of registered services.
///
- private readonly IDictionary _serviceInfo = new Dictionary();
+ private readonly Dictionary _serviceInfo = new Dictionary();
///
/// Initializes a new instance of the class.
@@ -162,12 +162,17 @@ public void Register(IComponentRegistration registration, bool preserveDefaults)
private void UpdateInitialisedAdapters(IComponentRegistration registration)
{
- var adapterServices = _serviceInfo
- .Where(si => si.Value.ShouldRecalculateAdaptersOn(registration))
- .Select(si => si.Key)
- .ToArray();
+ List adapterServices = new List();
- if (adapterServices.Length == 0)
+ foreach (var serviceInfo in _serviceInfo)
+ {
+ if (serviceInfo.Value.ShouldRecalculateAdaptersOn(registration))
+ {
+ adapterServices.Add(serviceInfo.Key);
+ }
+ }
+
+ if (adapterServices.Count == 0)
return;
Debug.WriteLine(
diff --git a/src/Autofac/Core/Registration/ExternalRegistrySource.cs b/src/Autofac/Core/Registration/ExternalRegistrySource.cs
index 6543aa737..53da9af39 100644
--- a/src/Autofac/Core/Registration/ExternalRegistrySource.cs
+++ b/src/Autofac/Core/Registration/ExternalRegistrySource.cs
@@ -105,7 +105,7 @@ public IEnumerable RegistrationsFor(Service service, Fun
///
private class ExternalComponentRegistration : ComponentRegistration
{
- public ExternalComponentRegistration(Guid id, IInstanceActivator activator, IComponentLifetime lifetime, InstanceSharing sharing, InstanceOwnership ownership, IEnumerable services, IDictionary metadata, IComponentRegistration target)
+ public ExternalComponentRegistration(Guid id, IInstanceActivator activator, IComponentLifetime lifetime, InstanceSharing sharing, InstanceOwnership ownership, Service[] services, IDictionary metadata, IComponentRegistration target)
: base(id, activator, lifetime, sharing, ownership, services, metadata, target)
{
}
diff --git a/src/Autofac/Core/Registration/ServiceRegistrationInfo.cs b/src/Autofac/Core/Registration/ServiceRegistrationInfo.cs
index 7688ee77f..f4af257a9 100644
--- a/src/Autofac/Core/Registration/ServiceRegistrationInfo.cs
+++ b/src/Autofac/Core/Registration/ServiceRegistrationInfo.cs
@@ -48,13 +48,13 @@ internal class ServiceRegistrationInfo
/// List of service implementations coming from sources. Sources have priority over preserve-default implementations.
/// Implementations from sources are enumerated in preserve-default order, so the most default implementation comes first.
///
- private readonly List _sourceImplementations = new List();
+ private List _sourceImplementations;
///
/// List of explicit service implementations specified with the PreserveExistingDefaults option.
/// Enumerated in preserve-defaults order, so the most default implementation comes first.
///
- private readonly List _preserveDefaultImplementations = new List();
+ private List _preserveDefaultImplementations;
[SuppressMessage("Microsoft.ApiDesignGuidelines", "CA2213", Justification = "The creator of the compponent registration is responsible for disposal.")]
private IComponentRegistration _defaultImplementation;
@@ -88,10 +88,16 @@ public IEnumerable Implementations
get
{
RequiresInitialization();
- return Enumerable
- .Reverse(_defaultImplementations)
- .Concat(_sourceImplementations)
- .Concat(_preserveDefaultImplementations);
+
+ var resultingCollection = Enumerable.Reverse(_defaultImplementations);
+
+ if (_sourceImplementations != null)
+ resultingCollection = resultingCollection.Concat(_sourceImplementations);
+
+ if (_preserveDefaultImplementations != null)
+ resultingCollection = resultingCollection.Concat(_preserveDefaultImplementations);
+
+ return resultingCollection;
}
}
@@ -114,18 +120,28 @@ public bool IsRegistered
}
private bool Any =>
- _defaultImplementations.Any() ||
- _sourceImplementations.Any() ||
- _preserveDefaultImplementations.Any();
+ _defaultImplementations.Count > 0 ||
+ _sourceImplementations != null ||
+ _preserveDefaultImplementations != null;
public void AddImplementation(IComponentRegistration registration, bool preserveDefaults, bool originatedFromSource)
{
if (preserveDefaults)
{
if (originatedFromSource)
+ {
+ if (_sourceImplementations == null)
+ _sourceImplementations = new List();
+
_sourceImplementations.Add(registration);
+ }
else
+ {
+ if (_preserveDefaultImplementations == null)
+ _preserveDefaultImplementations = new List();
+
_preserveDefaultImplementations.Add(registration);
+ }
}
else
{
@@ -144,8 +160,8 @@ public bool TryGetRegistration(out IComponentRegistration registration)
registration = _defaultImplementation ?? (_defaultImplementation =
_defaultImplementations.LastOrDefault() ??
- _sourceImplementations.FirstOrDefault() ??
- _preserveDefaultImplementations.FirstOrDefault());
+ _sourceImplementations?.First() ??
+ _preserveDefaultImplementations?.First());
return registration != null;
}
@@ -214,7 +230,9 @@ public bool ShouldRecalculateAdaptersOn(IComponentRegistration registration)
// - Have already been initialized
// - Were created via a registration source (because we might be adding an equivalent explicit registration such as Func)
// - Don't contain any registrations (because a registration source was added when no adaptee was present)
- return IsInitialized && (_sourceImplementations.Any() || !Any);
+ bool result = IsInitialized && (_sourceImplementations != null || !Any);
+
+ return result;
}
}
}
\ No newline at end of file
diff --git a/src/Autofac/Core/Resolving/CircularDependencyDetector.cs b/src/Autofac/Core/Resolving/CircularDependencyDetector.cs
index b5980c818..d751a39a4 100644
--- a/src/Autofac/Core/Resolving/CircularDependencyDetector.cs
+++ b/src/Autofac/Core/Resolving/CircularDependencyDetector.cs
@@ -61,8 +61,11 @@ public static void CheckForCircularDependency(IComponentRegistration registratio
throw new DependencyResolutionException(string.Format(CultureInfo.CurrentCulture, CircularDependencyDetectorResources.MaxDepthExceeded, registration));
// Checks for circular dependency
- if (activationStack.Any(a => a.ComponentRegistration == registration))
- throw new DependencyResolutionException(string.Format(CultureInfo.CurrentCulture, CircularDependencyDetectorResources.CircularDependency, CreateDependencyGraphTo(registration, activationStack)));
+ foreach (var a in activationStack)
+ {
+ if (a.ComponentRegistration == registration)
+ throw new DependencyResolutionException(string.Format(CultureInfo.CurrentCulture, CircularDependencyDetectorResources.CircularDependency, CreateDependencyGraphTo(registration, activationStack)));
+ }
}
}
}
diff --git a/src/Autofac/Features/OpenGenerics/OpenGenericDecoratorRegistrationSource.cs b/src/Autofac/Features/OpenGenerics/OpenGenericDecoratorRegistrationSource.cs
index 094e8702b..8198dddd4 100644
--- a/src/Autofac/Features/OpenGenerics/OpenGenericDecoratorRegistrationSource.cs
+++ b/src/Autofac/Features/OpenGenerics/OpenGenericDecoratorRegistrationSource.cs
@@ -60,7 +60,7 @@ public IEnumerable RegistrationsFor(Service service, Fun
if (registrationAccessor == null) throw new ArgumentNullException(nameof(registrationAccessor));
Type constructedImplementationType;
- IEnumerable services;
+ Service[] services;
if (OpenGenericServiceBinder.TryBindServiceType(service, _registrationData.Services, _activatorData.ImplementationType, out constructedImplementationType, out services))
{
var swt = (IServiceWithType)service;
@@ -77,13 +77,19 @@ public IEnumerable RegistrationsFor(Service service, Fun
return Enumerable.Empty();
}
- private static IEnumerable AddDecoratedComponentParameter(Type decoratedParameterType, IComponentRegistration decoratedComponent, IEnumerable configuredParameters)
+ private static IList AddDecoratedComponentParameter(Type decoratedParameterType, IComponentRegistration decoratedComponent, IList configuredParameters)
{
var parameter = new ResolvedParameter(
(pi, c) => pi.ParameterType == decoratedParameterType,
(pi, c) => c.ResolveComponent(decoratedComponent, Enumerable.Empty()));
- return new[] { parameter }.Concat(configuredParameters);
+ var resultArray = new Parameter[configuredParameters.Count + 1];
+ resultArray[0] = parameter;
+
+ for (int i = 0; i < configuredParameters.Count; i++)
+ resultArray[i + 1] = configuredParameters[i];
+
+ return resultArray;
}
public bool IsAdapterForIndividualComponents => true;
diff --git a/src/Autofac/Features/OpenGenerics/OpenGenericRegistrationSource.cs b/src/Autofac/Features/OpenGenerics/OpenGenericRegistrationSource.cs
index 92cd9302e..3447fc478 100644
--- a/src/Autofac/Features/OpenGenerics/OpenGenericRegistrationSource.cs
+++ b/src/Autofac/Features/OpenGenerics/OpenGenericRegistrationSource.cs
@@ -60,7 +60,7 @@ public IEnumerable RegistrationsFor(Service service, Fun
if (registrationAccessor == null) throw new ArgumentNullException(nameof(registrationAccessor));
Type constructedImplementationType;
- IEnumerable services;
+ Service[] services;
if (OpenGenericServiceBinder.TryBindServiceType(service, _registrationData.Services, _activatorData.ImplementationType, out constructedImplementationType, out services))
{
yield return RegistrationBuilder.CreateRegistration(
diff --git a/src/Autofac/Features/OpenGenerics/OpenGenericServiceBinder.cs b/src/Autofac/Features/OpenGenerics/OpenGenericServiceBinder.cs
index 93b4ec1ac..4d96f61b9 100644
--- a/src/Autofac/Features/OpenGenerics/OpenGenericServiceBinder.cs
+++ b/src/Autofac/Features/OpenGenerics/OpenGenericServiceBinder.cs
@@ -41,7 +41,7 @@ internal static class OpenGenericServiceBinder
IEnumerable configuredOpenGenericServices,
Type openGenericImplementationType,
out Type constructedImplementationType,
- out IEnumerable constructedServices)
+ out Service[] constructedServices)
{
var swt = service as IServiceWithType;
if (swt != null && swt.ServiceType.GetTypeInfo().IsGenericType)
diff --git a/src/Autofac/ModuleRegistrationExtensions.cs b/src/Autofac/ModuleRegistrationExtensions.cs
index d2e2b0ecd..7808ee023 100644
--- a/src/Autofac/ModuleRegistrationExtensions.cs
+++ b/src/Autofac/ModuleRegistrationExtensions.cs
@@ -26,6 +26,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
+using Autofac.Builder;
using Autofac.Core;
using Autofac.Core.Registration;
@@ -164,7 +165,7 @@ public static IModuleRegistrar RegisterAssemblyModules(this IModuleRegistrar reg
.Where(t => moduleType.GetTypeInfo().IsAssignableFrom(t.GetTypeInfo()))
.As();
- using (var moduleContainer = moduleFinder.Build())
+ using (var moduleContainer = moduleFinder.Build(ContainerBuildOptions.None))
{
foreach (var module in moduleContainer.Resolve>())
{
diff --git a/test/Autofac.Test/ContainerBuilderTests.cs b/test/Autofac.Test/ContainerBuilderTests.cs
index ca4de293e..3b4499e42 100644
--- a/test/Autofac.Test/ContainerBuilderTests.cs
+++ b/test/Autofac.Test/ContainerBuilderTests.cs
@@ -369,7 +369,7 @@ public void WhenUpdating_DefaultModulesAreExcluded()
public void WhenBuildingWithDefaultsExcluded_DefaultModulesAreExcluded()
{
var builder = new ContainerBuilder();
- var container = builder.Build(ContainerBuildOptions.ExcludeDefaultModules);
+ var container = builder.Build(ContainerBuildOptions.None, DefaultServiceFlags.None);
Assert.False(container.IsRegistered>());
}
diff --git a/test/Autofac.Test/Factory.cs b/test/Autofac.Test/Factory.cs
index 53a2be374..004541762 100644
--- a/test/Autofac.Test/Factory.cs
+++ b/test/Autofac.Test/Factory.cs
@@ -33,7 +33,7 @@ public static IComponentRegistration CreateRegistration(IEnumerable ser
lifetime,
sharing,
InstanceOwnership.OwnedByLifetimeScope,
- services,
+ services.ToArray(),
GetDefaultMetadata());
}
@@ -78,8 +78,8 @@ public static ReflectionActivator CreateReflectionActivator(Type implementation,
implementation,
new DefaultConstructorFinder(),
new MostParametersConstructorSelector(),
- parameters,
- properties);
+ parameters.ToArray(),
+ properties.ToArray());
}
public static ProvidedInstanceActivator CreateProvidedInstanceActivator(object instance)
@@ -99,8 +99,8 @@ public static ProvidedInstanceActivator CreateProvidedInstanceActivator(object i
public static readonly IComponentContext EmptyContext = new Container();
- public static readonly IEnumerable NoParameters = Enumerable.Empty();
+ public static readonly Parameter[] NoParameters = new Parameter[0];
- public static readonly IEnumerable NoProperties = Enumerable.Empty();
+ public static readonly Parameter[] NoProperties = new Parameter[0];
}
}
diff --git a/test/Autofac.Test/Mocks.cs b/test/Autofac.Test/Mocks.cs
index 2cf9b18b7..4f551c018 100644
--- a/test/Autofac.Test/Mocks.cs
+++ b/test/Autofac.Test/Mocks.cs
@@ -73,7 +73,7 @@ public void Dispose()
public InstanceOwnership Ownership { get; }
- public IEnumerable Services { get; } = new Service[0];
+ public Service[] Services { get; } = new Service[0];
public IDictionary Metadata { get; }