/// <summary> /// Initializes a new instance of the <see cref="T:CSF.FlexDi.Container"/> class. /// </summary> /// <remarks> /// <para> /// All of the parameters to this method are optional. Any which are not provided will be fulfilled using /// default implementations. /// </para> /// <para> /// Of the parameters which might be used, the most useful is likely to be <paramref name="options"/> and /// <paramref name="parentContainer"/>. /// </para> /// </remarks> /// <param name="registry">An optional service registry instance.</param> /// <param name="cache">An optional service cache instance.</param> /// <param name="resolver">An optional resolver instance.</param> /// <param name="disposer">An optional service disposer instance.</param> /// <param name="options">A set of container options.</param> /// <param name="parentContainer">An optional parent container - indicating that this container is the child of another.</param> /// <param name="resolverFactory">An optional resolver factory instance.</param> public Container(IRegistersServices registry = null, ICachesResolvedServiceInstances cache = null, IFulfilsResolutionRequests resolver = null, IDisposesOfResolvedInstances disposer = null, ContainerOptions options = null, IContainer parentContainer = null, ICreatesResolvers resolverFactory = null) { disposedValue = false; this.parentContainer = parentContainer; this.options = GetContainerOptions(options, parentContainer); constructorSelector = new ConstructorWithMostParametersSelector(this.options.UseNonPublicConstructors); this.registry = registry ?? new Registry(); this.cache = cache ?? new ResolvedServiceCache(); this.disposer = disposer ?? new ServiceInstanceDisposer(); this.registryStack = new RegistryStackFactory().CreateRegistryStack(this); this.resolver = resolver ?? GetResolver(resolverFactory); this.resolver.ServiceResolved += InvokeServiceResolved; PerformSelfRegistrations(); }
/// <summary> /// Sets the given <paramref name="parent"/> as this instance's /// <see cref="IServiceRegistrationProvider.ParentServiceProvider"/>. /// Requests for types HERE will /// first check this container itself; and if not registered /// here, they will then check this parent. Additionally, /// dependencies needed for services constructed HERE will first /// check this container, and if not resolved here, WILL check /// this <paramref name="parent"/>. Note that dependencies needed /// for Types registered on the <paramref name="parent"/> will NOT /// come from this or any other child containers --- and at the same /// time, ALL parents WILL be checked up the hierarchy. /// NOTICE that this means that the <paramref name="parent"/> /// container MUST live at least as long as THIS container, /// AND all parents up the hierarchy must also --- otherwise dependencies /// resolved from a parent container could be disposed before /// a service that is using them. /// </summary> /// <param name="parent">Not null.</param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException">The <paramref name="parent"/> /// cannot be cyclically scoped, AND THIS /// <see cref="IServiceRegistrationProvider.ParentServiceProvider"/> /// must be null at this time.</exception> internal void Scope(IServiceProvider parent) { if (parent == null) { throw new ArgumentNullException(nameof(parent)); } if (object.ReferenceEquals(this, parent)) { throw new ArgumentException($"Requested parent container is THIS: {parent}", nameof(parent)); } lock (registrations) { if (parentServiceProvider != null) { throw new ArgumentException($"Container cannot be scoped twice: {this}", nameof(parent)); } IServiceProvider checkParent = (parent as IServiceRegistrationProvider)?.ParentServiceProvider; while (checkParent != null) { if (object.ReferenceEquals(checkParent, parent) || object.ReferenceEquals(checkParent, this)) { throw new ArgumentException($"Container cannot be scoped twice: {parent}", nameof(parent)); } checkParent = (checkParent as IServiceRegistrationProvider)?.ParentServiceProvider; } parentServiceProvider = parent; parentServiceRegistrationProvider = parent as IServiceRegistrationProvider; } }
public void Resolve_using_request_can_get_registered_service_without_name(IServiceRegistrationProvider provider, [Registration] IServiceRegistration registration, ResolutionRequest request) { // Arrange var sut = GetSut(provider); var instance = new SampleServiceImplementationOne(); Mock.Get(provider) .Setup(x => x.CanFulfilRequest(request)) .Returns(false); Mock.Get(provider) .Setup(x => x.Get(request)) .Returns((IServiceRegistration)null); Mock.Get(provider) .Setup(x => x.CanFulfilRequest(It.Is <ResolutionRequest>(r => r.ServiceType == request.ServiceType && r.Name == null))) .Returns(true); Mock.Get(provider) .Setup(x => x.Get(It.Is <ResolutionRequest>(r => r.ServiceType == request.ServiceType && r.Name == null))) .Returns(registration); Mock.Get(registration) .Setup(x => x.GetFactoryAdapter(request)) .Returns(new InstanceFactory(instance)); // Act var result = sut.Resolve(request); // Assert Assert.That(result.ResolvedObject, Is.SameAs(instance)); }
public static bool TryInject( IServiceRegistrationProvider serviceProvider, object target, Type attributeType, ITrace logger = null, Func <Type, object> instanceProvider = null, bool tryConstructArguments = false, bool?requireConstructorAttributes = null, IReadOnlyCollection <Type> constructorAttributeTypes = null) { if (serviceProvider == null) { throw new ArgumentNullException(nameof(serviceProvider)); } if (target == null) { throw new ArgumentNullException(nameof(target)); } if (attributeType == null) { throw new ArgumentNullException(nameof(attributeType)); } if ((constructorAttributeTypes == null) || (constructorAttributeTypes.Count == 0)) { constructorAttributeTypes = new[] { typeof(ServiceProviderConstructorAttribute) } } ; ServiceConstructorRequest request = new ServiceConstructorRequest(logger ?? TraceSources.For(typeof(ServiceConstructorMethods))); request.Logger.Verbose( "Injecting '{0}' on '{1}'.", attributeType.GetFriendlyFullName(), target.GetType().GetFriendlyFullName()); if (ServiceConstructorMethods.invokeMember( ServiceConstructorMethods.findMethods(target, attributeType, request.TraceStack), true, target, out _, request, serviceProvider, instanceProvider, tryConstructArguments, requireConstructorAttributes, constructorAttributeTypes, false)) { request.Logger.Verbose( "Inject result for '{0}' on '{1}' is true.", attributeType.GetFriendlyFullName(), target.GetType().GetFriendlyFullName()); return(true); } request.Logger.Info( "Inject result for '{0}' on '{1}' is false.", attributeType.GetFriendlyFullName(), target.GetType().GetFriendlyFullName()); return(false); }
/// <summary> /// Constructor. NOTICE that the <paramref name="serviceProvider"/> /// MUST NOT implement <see cref="IServiceRegistrationProvider"/>. /// </summary> /// <param name="serviceProvider">Required; and MUST NOT implement /// <see cref="IServiceRegistrationProvider"/>.</param> /// <param name="parentServiceProvider">Optional parent for the /// <see cref="IServiceRegistrationProvider.ParentServiceProvider"/>.</param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> public ServiceRegistrationProviderWrapper( IServiceProvider serviceProvider, IServiceProvider parentServiceProvider = null) { if (serviceProvider is IServiceRegistrationProvider) { throw new ArgumentException( $"{nameof(ServiceRegistrationProviderWrapper)} {nameof(serviceProvider)}" + $" must not implement {nameof(IServiceRegistrationProvider)}" + $": '{serviceProvider.GetType().GetFriendlyFullName()}'."); } this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); ParentServiceProvider = parentServiceProvider; parentServiceRegistrationProvider = parentServiceProvider as IServiceRegistrationProvider; if (object.ReferenceEquals(serviceProvider, parentServiceProvider)) { throw new ArgumentException( $"Requested parent container is THIS: {parentServiceProvider}", nameof(parentServiceProvider)); } IServiceProvider checkParent = parentServiceRegistrationProvider?.ParentServiceProvider; while (checkParent != null) { if (object.ReferenceEquals(checkParent, parentServiceProvider) || object.ReferenceEquals(checkParent, serviceProvider)) { throw new ArgumentException( $"Container cannot be scoped twice: {parentServiceProvider}", nameof(parentServiceProvider)); } checkParent = (checkParent as IServiceRegistrationProvider)?.ParentServiceProvider; } }
/// <summary> /// Initializes a new instance of the <see cref="T:CSF.FlexDi.Resolution.Proxies.UnregisteredServiceResolverProxy"/> class. /// </summary> /// <param name="proxiedResolver">Proxied resolver.</param> /// <param name="registrationResolver">Registration resolver.</param> /// <param name="unregisteredRegistrationProvider">Unregistered registration provider.</param> /// <param name="cache">The service cache.</param> /// <param name="registry">The service registry</param> public UnregisteredServiceResolverProxy(IResolver proxiedResolver, IResolvesRegistrations registrationResolver, IServiceRegistrationProvider unregisteredRegistrationProvider, ICachesResolvedServiceInstances cache, IRegistersServices registry) : base(proxiedResolver) { if (registry == null) { throw new ArgumentNullException(nameof(registry)); } if (unregisteredRegistrationProvider == null) { throw new ArgumentNullException(nameof(unregisteredRegistrationProvider)); } if (registrationResolver == null) { throw new ArgumentNullException(nameof(registrationResolver)); } this.cache = cache; this.registrationResolver = registrationResolver; this.unregisteredRegistrationProvider = unregisteredRegistrationProvider; this.registry = registry; }
/// <summary> /// Utility method resolves the type and logs and returns success. /// </summary> private static bool tryResolve( Type targetType, out object result, ServiceConstructorRequest request, IServiceRegistrationProvider serviceProvider, Func <Type, object> instanceProvider, bool logMustResolve) { bool CheckResult(object service, string sourceName, out object successResult) { if (targetType.IsInstanceOfType(service)) { request.TraceStack.Add($"{sourceName} resolved '{targetType.GetFriendlyFullName()}'."); successResult = service; return(true); } successResult = null; return(false); } if (instanceProvider != null) { if (CheckResult(instanceProvider(targetType), "InstanceProvider Func", out result)) { return(true); } } if (CheckResult(serviceProvider.GetService(targetType, request), nameof(IServiceProvider), out result)) { return(true); } if (serviceProvider.ParentServiceProvider is IServiceRegistrationProvider parentServiceRegistrationProvider) { if (CheckResult( parentServiceRegistrationProvider.GetService(targetType, request), nameof(IServiceRegistrationProvider.ParentServiceProvider), out result)) { return(true); } } else { if (CheckResult( serviceProvider.ParentServiceProvider?.GetService(targetType), nameof(IServiceRegistrationProvider.ParentServiceProvider), out result)) { return(true); } } if (logMustResolve) { request.TraceStack.Add($"Did not resolve '{targetType.GetFriendlyFullName()}'."); } return(false); }
public void Resolve_can_create_dictionary_of_instances_by_enum_values([Frozen, ResolvesToFailure] IResolver proxiedResolver, [Frozen] IDictionaryFactory dictionaryFactory, [Frozen] IServiceRegistrationProvider registrationProvider, NamedInstanceDictionaryResolverProxy sut, ResolutionRequest request, SampleEnum[] names, ResolutionPath path) { // Arrange var serviceType = request.ServiceType; var keyType = typeof(SampleEnum); var valueType = typeof(ISampleService); Mock.Get(dictionaryFactory) .Setup(x => x.IsGenericDictionaryType(serviceType)) .Returns(true); Mock.Get(dictionaryFactory) .Setup(x => x.GetKeyType(serviceType)) .Returns(keyType); Mock.Get(dictionaryFactory) .Setup(x => x.GetValueType(serviceType)) .Returns(valueType); Mock.Get(dictionaryFactory) .Setup(x => x.Create(keyType, valueType)) .Returns(() => new Dictionary <SampleEnum, ISampleService>()); var registrations = names .Select(x => x.ToString()) .Select(x => Mock.Of <IServiceRegistration>(r => r.Name == x && r.ServiceType == valueType)) .ToArray(); Mock.Get(registrationProvider) .Setup(x => x.GetAll(valueType)) .Returns(registrations); Mock.Get(proxiedResolver) .Setup(x => x.Resolve(It.Is <ResolutionRequest>(r => r.ServiceType == valueType))) .Returns((ResolutionRequest r) => ResolutionResult.Success(path, new SampleServiceImplementationOne())); // Act var result = sut.Resolve(request); // Assert Mock.Get(proxiedResolver) .Verify(x => x.Resolve(It.Is <ResolutionRequest>(r => r.ServiceType == valueType)), Times.Exactly(names.Length)); foreach (var name in names.Select(x => x.ToString()).ToArray()) { Mock.Get(proxiedResolver) .Verify(x => x.Resolve(It.Is <ResolutionRequest>(r => r.Name == name)), Times.Once); } Assert.That(result.IsSuccess, Is.True); Assert.That(result.ResolvedObject, Is.InstanceOf <IDictionary <SampleEnum, ISampleService> >()); var resolvedObject = (IDictionary <SampleEnum, ISampleService>)result.ResolvedObject; Assert.That(resolvedObject, Has.Count.EqualTo(names.Length)); }
/// <summary> /// Initializes a new instance of the /// <see cref="T:CSF.FlexDi.Resolution.Proxies.UnregisteredServiceResolverProxyFactory"/> class. /// </summary> /// <param name="registrationResolver">Registration resolver.</param> /// <param name="unregisteredRegistrationProvider">Unregistered registration provider.</param> public UnregisteredServiceResolverProxyFactory(IResolvesRegistrations registrationResolver, IServiceRegistrationProvider unregisteredRegistrationProvider = null) { if (registrationResolver == null) { throw new ArgumentNullException(nameof(registrationResolver)); } this.registrationResolver = registrationResolver; this.unregisteredRegistrationProvider = unregisteredRegistrationProvider; }
Resolver GetSut(IServiceRegistrationProvider provider, IServiceRegistrationProvider unregisteredProvider = null) { var instanceCreator = new Mock <ICreatesObjectInstances>(); instanceCreator .Setup(x => x.CreateFromFactory(It.IsAny <IFactoryAdapter>(), It.IsAny <ResolutionPath>(), It.IsAny <IServiceRegistration>())) .Returns((IFactoryAdapter a, ResolutionPath p, IServiceRegistration r) => CreateInstance(a, p, r)); return(new Resolver(provider, instanceCreator.Object)); }
public DefaultServiceRegister( IServiceRegistrationProvider registrationProvider, IServiceProvider serviceProvider, IOptions <RpcServerOptions> options, ILogger <DefaultServiceRegister> logger) { this._registrationProvider = registrationProvider; this._serviceProvider = serviceProvider; this._logger = logger; this._optionValues = options.Value; this._localBindAddress = new IPEndPoint(GetBindAddress(), this._optionValues.Port); }
/// <summary> /// Initializes a new instance of the <see cref="T:CSF.FlexDi.Resolution.Resolver"/> class. /// </summary> /// <param name="registrationProvider">Registration provider.</param> /// <param name="instanceCreator">Instance creator.</param> public Resolver(IServiceRegistrationProvider registrationProvider, ICreatesObjectInstances instanceCreator) { if (instanceCreator == null) { throw new ArgumentNullException(nameof(instanceCreator)); } if (registrationProvider == null) { throw new ArgumentNullException(nameof(registrationProvider)); } this.registrationProvider = registrationProvider; this.instanceCreator = instanceCreator; }
/// <summary> /// Initializes a new instance of the /// <see cref="T:CSF.FlexDi.Resolution.Proxies.NamedInstanceDictionaryResolverProxy"/> class. /// </summary> /// <param name="proxiedResolver">Proxied resolver.</param> /// <param name="registrationAccessor">Registration accessor.</param> /// <param name="dictionaryFactory">Dictionary factory.</param> public NamedInstanceDictionaryResolverProxy(IResolver proxiedResolver, IServiceRegistrationProvider registrationAccessor, IDictionaryFactory dictionaryFactory) : base(proxiedResolver) { if (dictionaryFactory == null) { throw new ArgumentNullException(nameof(dictionaryFactory)); } if (registrationAccessor == null) { throw new ArgumentNullException(nameof(registrationAccessor)); } this.registrationAccessor = registrationAccessor; this.dictionaryFactory = dictionaryFactory; }
/// <summary> /// Coordinates the disposal of all disposable service/component instances within the given cache. /// </summary> /// <param name="registrationProvider">Registration provider.</param> /// <param name="instanceCache">A cache which provides access to the component instances.</param> public void DisposeInstances(IServiceRegistrationProvider registrationProvider, ICachesResolvedServiceInstances instanceCache) { if (registrationProvider == null) { throw new ArgumentNullException(nameof(registrationProvider)); } if (instanceCache == null) { throw new ArgumentNullException(nameof(instanceCache)); } var registrationsToDispose = GetRegistrationsToDispose(registrationProvider); Dispose(registrationsToDispose, instanceCache); }
public void DisposeInstances_does_not_dispose_non_disposable_objects(IServiceRegistrationProvider registrations, ICachesResolvedServiceInstances cache, ServiceInstanceDisposer sut, IServiceRegistration registration, object nonDisposable) { // Arrange Mock.Get(registration).SetupGet(x => x.DisposeWithContainer).Returns(false); Mock.Get(registration).SetupGet(x => x.Cacheable).Returns(true); Mock.Get(registrations).Setup(x => x.GetAll()).Returns(new [] { registration }); object obj = nonDisposable; Mock.Get(cache) .Setup(x => x.TryGet(registration, out obj)) .Callback(() => obj = nonDisposable) .Returns(true); // Act Assert.That(() => sut.DisposeInstances(registrations, cache), Throws.Nothing); }
public void DisposeInstances_does_not_dispose_non_cached_instances(IServiceRegistrationProvider registrations, ICachesResolvedServiceInstances cache, ServiceInstanceDisposer sut, IServiceRegistration registration, IDisposable disposable) { // Arrange Mock.Get(registration).SetupGet(x => x.DisposeWithContainer).Returns(true); Mock.Get(registration).SetupGet(x => x.Cacheable).Returns(true); Mock.Get(registrations).Setup(x => x.GetAll()).Returns(new [] { registration }); object obj = disposable; Mock.Get(cache) .Setup(x => x.TryGet(registration, out obj)) .Returns(false); // Act sut.DisposeInstances(registrations, cache); // Assert Mock.Get(disposable).Verify(x => x.Dispose(), Times.Never); }
/// <summary> /// Constructor. Notice that the <paramref name="factory"/> is optional: /// <see cref="IsImplementationContainerCreated"/> is /// set based on this argument by default. /// </summary> /// <param name="serviceProvider">Required.</param> /// <param name="serviceType">Required.</param> /// <param name="implementationType">Required.</param> /// <param name="isSingleton">Required.</param> /// <param name="factory">OPTIONAL: if null, the <see cref="ServiceConstructorMethods"/> /// constructs the object. Note also that <see cref="IsImplementationContainerCreated"/> /// is set true by default if this is null; and is set false by default /// if this is not null.</param> /// <param name="isImplementationContainerCreated">Specifies the value /// for <see cref="IsImplementationContainerCreated"/>; /// which determines the disposal policy: this class ONLY disposes singletons /// marked as <c>IsImplementationContainerCreated</c> (and always disposes /// such instances). This value is nullable: if null, it will be set true /// if the <c>factory</c> is null; and otherwise false.</param> /// <exception cref="ArgumentNullException"/> /// <exception cref="ArgumentException">If the <paramref name="implementationType"/> /// does not extend the <paramref name="serviceType"/></exception> public ServiceRegistration( IServiceRegistrationProvider serviceProvider, Type serviceType, Type implementationType, bool isSingleton, Func <IServiceProvider, object> factory = null, bool?isImplementationContainerCreated = null) { this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); ServiceType = serviceType ?? throw new ArgumentNullException(nameof(serviceType)); ImplementationType = implementationType ?? throw new ArgumentNullException(nameof(implementationType)); if (!serviceType.IsAssignableFrom(implementationType)) { throw new ArgumentException( $"Implementation type '{implementationType.GetFriendlyFullName()}'" + $" is not assignable to service type '{serviceType.GetFriendlyFullName()}'", nameof(implementationType)); } IsSingleton = isSingleton; this.factory = factory; IsImplementationContainerCreated = isImplementationContainerCreated ?? (factory == null); }
public void Dispose() { List <ServiceRegistration> disposeRegistrations; lock (registrations) { disposeRegistrations = DisposeRegistrationsWithContainer ? registrations.Values.ToList() : null; registrations.Clear(); parentServiceRegistrationProvider = null; parentServiceProvider = null; } if (disposeRegistrations == null) { return; } disposeRegistrations.Sort(DateComparer); disposeRegistrations.Sort(DependencyComparer); disposeRegistrations.Sort(DependantComparer); foreach (ServiceRegistration disposeRegistration in disposeRegistrations) { disposeRegistration.Dispose(); }
public static bool TryConstruct( this IServiceProvider serviceProvider, Type targetType, out object service, ITrace logger = null, Func <Type, object> instanceProvider = null, bool tryConstructArguments = false, bool?requireAttributes = null, params Type[] attributeTypes) { IServiceRegistrationProvider serviceRegistrationProvider = serviceProvider as IServiceRegistrationProvider ?? new ServiceRegistrationProviderWrapper(serviceProvider); return(ServiceConstructorMethods.TryConstruct( targetType, out service, new ServiceConstructorRequest(logger), serviceRegistrationProvider, instanceProvider, tryConstructArguments, requireAttributes, attributeTypes)); }
IDictionary <ServiceRegistrationKey, IServiceRegistration> GetNonConflictingRegistrations(IEnumerable <ServiceRegistrationKey> alreadyFound, IServiceRegistrationProvider provider, Type serviceTypeFilter) { if (alreadyFound == null) { throw new ArgumentNullException(nameof(alreadyFound)); } if (provider == null) { throw new ArgumentNullException(nameof(provider)); } var candidates = (serviceTypeFilter != null)? provider.GetAll(serviceTypeFilter) : provider.GetAll(); if (candidates == null) { candidates = new IServiceRegistration[0]; } return((from registration in candidates let key = ServiceRegistrationKey.ForRegistration(registration) where !alreadyFound.Contains(key) select new { Registration = registration, Key = key }) .ToDictionary(k => k.Key, v => v.Registration)); }
public static bool TryConstruct( Type targetType, out object service, ServiceConstructorRequest request, IServiceRegistrationProvider serviceProvider, Func <Type, object> instanceProvider = null, bool tryConstructArguments = false, bool?requireConstructorAttributes = null, IReadOnlyCollection <Type> constructorAttributeTypes = null) { if (targetType == null) { throw new ArgumentNullException(nameof(targetType)); } if (request == null) { throw new ArgumentNullException(nameof(request)); } if (serviceProvider == null) { throw new ArgumentNullException(nameof(serviceProvider)); } if ((constructorAttributeTypes == null) || (constructorAttributeTypes.Count == 0)) { constructorAttributeTypes = new[] { typeof(ServiceProviderConstructorAttribute) } } ; if (request.ConstructingTypes.Contains(targetType)) { request.TraceStack.Add( "Found a recursive constructor dependency" + $": '{targetType.GetFriendlyFullName()}'" + " ... cannot continue."); service = null; return(false); } request.ConstructingTypes.Add(targetType); request.Logger.Verbose("Constructing {0}.", targetType.GetFriendlyFullName()); if (ServiceConstructorMethods.invokeMember( ServiceConstructorMethods.findConstructors( targetType, requireConstructorAttributes, constructorAttributeTypes, request.TraceStack), false, null, out service, request, serviceProvider, instanceProvider, tryConstructArguments, requireConstructorAttributes, constructorAttributeTypes, false)) { request.Logger.Verbose( "Construct result for '{0}' is true: '{1}'.", targetType.GetFriendlyFullName(), service.GetType().GetFriendlyFullName()); request.ConstructingTypes.Remove(targetType); return(true); } request.Logger.Warning("Construct result for '{0}' is false.", targetType.GetFriendlyFullName()); request.ConstructingTypes.Remove(targetType); return(false); }
private static bool invokeMember( IEnumerable <MethodBase> members, bool isMethod, object methodTarget, out object newInstance, ServiceConstructorRequest request, IServiceRegistrationProvider serviceProvider, Func <Type, object> instanceProvider, bool tryConstructArguments, bool?requireConstructorAttributes, IReadOnlyCollection <Type> constructorAttributeTypes, bool isRecursed) { newInstance = null; bool success = false; foreach (MethodBase methodBase in members) { ParameterInfo[] parameters = methodBase.GetParameters(); if (parameters.Length == 0) { success = isMethod ? ServiceConstructorMethods.tryInvokeMethod( methodTarget, (MethodInfo)methodBase, new object[0], request.TraceStack) : ServiceConstructorMethods.tryInvokeConstructor( (ConstructorInfo)methodBase, new object[0], out newInstance, request.TraceStack); break; } List <object> arguments = new List <object>(parameters.Length); foreach (ParameterInfo parameterInfo in parameters) { if (ServiceConstructorMethods.tryResolve( parameterInfo.ParameterType, out object parameterResult, request, serviceProvider, instanceProvider, !tryConstructArguments)) { arguments.Add(parameterResult); continue; } if (tryConstructArguments) { if (request.ConstructingTypes.Contains(parameterInfo.ParameterType)) { request.TraceStack.Add( "Found a recursive constructor dependency" + $": '{parameterInfo.ParameterType.GetFriendlyFullName()}'" + " ... cannot continue."); break; } request.ConstructingTypes.Add(parameterInfo.ParameterType); bool argumentSuccess = ServiceConstructorMethods.invokeMember( ServiceConstructorMethods.findConstructors( parameterInfo.ParameterType, requireConstructorAttributes, constructorAttributeTypes, request.TraceStack), false, null, out object argumentResult, request, serviceProvider, instanceProvider, true, requireConstructorAttributes, constructorAttributeTypes, true); request.ConstructingTypes.Remove(parameterInfo.ParameterType); if (argumentSuccess) { arguments.Add(argumentResult); continue; } } if (parameterInfo.HasDefaultValue) { request.TraceStack.Add( $"Parameter '{parameterInfo.ParameterType.GetFriendlyFullName()}' has default value."); arguments.Add(parameterInfo.DefaultValue); } else { break; } } if ((arguments.Count != parameters.Length) || (isMethod ? !ServiceConstructorMethods.tryInvokeMethod( methodTarget, (MethodInfo)methodBase, arguments.ToArray(), request.TraceStack) : !ServiceConstructorMethods.tryInvokeConstructor( (ConstructorInfo)methodBase, arguments.ToArray(), out newInstance, request.TraceStack))) { continue; } request.Dependencies.TryAddRange( methodBase.DeclaringType, parameters.Select(parameter => parameter.ParameterType)); success = true; break; } if (isRecursed) { return(success); } if (success) { if (request.Logger.IsVerbose()) { request.Logger.Verbose(GetTraceMessage()); } } else { if (request.Logger.IsInfo()) { request.Logger.Info(GetTraceMessage()); } } string GetTraceMessage() { string separator = $"{Environment.NewLine} "; StringBuilder sb = request.TraceStack.ToConcatenatedString(null, separator); if (sb.Length != 0) { sb.Insert(0, " "); } return(sb.ToString()); } return(success); }
/// <summary> /// Gets a collection of the service/component registrations which are eligible for disposal. /// </summary> /// <returns>The registrations to dispose.</returns> /// <param name="registrationProvider">Registration provider.</param> protected virtual IReadOnlyCollection <IServiceRegistration> GetRegistrationsToDispose(IServiceRegistrationProvider registrationProvider) { if (registrationProvider == null) { throw new ArgumentNullException(nameof(registrationProvider)); } return(registrationProvider .GetAll() .Where(x => x.Cacheable && x.DisposeWithContainer) .ToArray()); }
public void Resolve_resolves_unregistered_service_when_resolution_is_unsuccesful([Frozen, ResolvesToFailure] IResolver proxiedResolver, [Frozen] IResolvesRegistrations registrationResolver, [Frozen] IServiceRegistrationProvider unregisteredRegistrationProvider, UnregisteredServiceResolverProxy sut, ResolutionPath path, ResolutionRequest request, ResolutionResult resolutionResult, IServiceRegistration registration) { // Arrange Mock.Get(proxiedResolver) .Setup(x => x.Resolve(request)) .Returns(ResolutionResult.Failure(path)); Mock.Get(unregisteredRegistrationProvider) .Setup(x => x.Get(request)) .Returns(registration); Mock.Get(registrationResolver) .Setup(x => x.Resolve(request, registration)) .Returns(resolutionResult); // Act var result = sut.Resolve(request); // Assert Assert.That(result, Is.SameAs(resolutionResult)); }