RegisterCollection <T>(ContainerBuilder builder, string collectionName, Type elementType) { if (builder == null) { throw new ArgumentNullException("builder"); } if (elementType == null) { throw new ArgumentNullException("elementType"); } Enforce.ArgumentNotNullOrEmpty(collectionName, "collectionName"); var arrayType = elementType.MakeArrayType(); var ts = new TypedService(elementType); var activator = new DelegateActivator(arrayType, (c, p) => { var elements = GetElementRegistrations(collectionName, c.ComponentRegistry); var items = elements.Select(e => c.ResolveComponent(ts, e, p)).ToArray(); var result = Array.CreateInstance(elementType, items.Length); items.CopyTo(result, 0); return(result); }); var rb = new RegistrationBuilder <T[], SimpleActivatorData, SingleRegistrationStyle>( new TypedService(typeof(T[])), new SimpleActivatorData(activator), new SingleRegistrationStyle()); builder.RegisterCallback(cr => RegistrationBuilder.RegisterSingleComponent(cr, rb)); return(rb); }
public void WhenActivationDelegateReturnsNull_ExceptionDescribesLimitType() { var target = new DelegateActivator(typeof(string), (c, p) => null); var ex = Assert.Throws <DependencyResolutionException>( () => target.ActivateInstance(new ContainerBuilder().Build(), Enumerable.Empty <Parameter>())); Assert.Contains(typeof(string).ToString(), ex.Message); }
public void ActivateInstance_ReturnsResultOfInvokingSuppliedDelegate() { var instance = new object(); var target = new DelegateActivator(typeof(object), (c, p) => instance); Assert.Same(instance, target.ActivateInstance(new ContainerBuilder().Build(), Enumerable.Empty <Parameter>())); }
public void WhenActivationDelegateReturnsNull_ExceptionDescribesLimitType() { var target = new DelegateActivator(typeof(string), (c, p) => null); var container = Factory.CreateEmptyContainer(); var invoker = target.GetPipelineInvoker(container.ComponentRegistry); var ex = Assert.Throws <DependencyResolutionException>( () => invoker(container, Factory.NoParameters)); Assert.Contains(typeof(string).ToString(), ex.Message); }
public void Pipeline_ReturnsResultOfInvokingSuppliedDelegate() { var instance = new object(); var target = new DelegateActivator(typeof(object), (c, p) => instance); var container = Factory.CreateEmptyContainer(); var invoker = target.GetPipelineInvoker(container.ComponentRegistry); Assert.Same(instance, invoker(container, Factory.NoParameters)); }
public IEnumerable <IComponentRegistration> RegistrationsFor(Service service, Func <Service, IEnumerable <IComponentRegistration> > registrationAccessor) { if (!(service is IServiceWithType swt) || !IsGenericSingleType(swt.ServiceType)) { return(Enumerable.Empty <IComponentRegistration>()); } var serviceType = swt.ServiceType; var elementType = serviceType.GetTypeInfo().GenericTypeArguments.First(); var singleResolverType = typeof(SingleResolver <>).MakeGenericType(elementType); var elementTypeService = swt.ChangeType(elementType); var activator = new DelegateActivator( serviceType, (c, p) => { var elements = c.ComponentRegistry.RegistrationsFor(elementTypeService).ToList(); if (elements.IsNullOrEmpty()) { return(Activator.CreateInstance(singleResolverType, false, null)); } var item = elements.Select(cr => c.ResolveComponent(cr, p)).Single(); return(Activator.CreateInstance(singleResolverType, true, item)); }); var registration = new ComponentRegistration( Guid.NewGuid(), activator, new CurrentScopeLifetime(), InstanceSharing.None, InstanceOwnership.ExternallyOwned, new[] { service }, new Dictionary <string, object>()); return(new IComponentRegistration[] { registration }); }
public static IRegistrationBuilder <T[], SimpleActivatorData, SingleRegistrationStyle> RegisterCollection <T>(ContainerBuilder builder, string collectionName, Type elementType) { if (builder == null) { throw new ArgumentNullException("builder"); } if (elementType == null) { throw new ArgumentNullException("elementType"); } Enforce.ArgumentNotNullOrEmpty(collectionName, "collectionName"); DelegateActivator activator = new DelegateActivator(elementType.MakeArrayType(), delegate(IComponentContext c, IEnumerable <Parameter> p) { object[] objArray = (from e in GetElementRegistrations(collectionName, c.ComponentRegistry) select c.ResolveComponent(e, p)).ToArray <object>(); Array array = Array.CreateInstance(elementType, objArray.Length); objArray.CopyTo(array, 0); return(array); }); RegistrationBuilder <T[], SimpleActivatorData, SingleRegistrationStyle> rb = new RegistrationBuilder <T[], SimpleActivatorData, SingleRegistrationStyle>(new TypedService(typeof(T[])), new SimpleActivatorData(activator), new SingleRegistrationStyle()); builder.RegisterCallback(delegate(IComponentRegistry cr) { RegistrationBuilder.RegisterSingleComponent <T[], SimpleActivatorData, SingleRegistrationStyle>(cr, rb); }); return(rb); }
/// <summary> /// Retrieve registrations for an unregistered service, to be used /// by the container. /// </summary> /// <param name="service">The service that was requested.</param> /// <param name="registrationAccessor">A function that will return existing registrations for a service.</param> /// <returns>Registrations providing the service.</returns> public IEnumerable <IComponentRegistration> RegistrationsFor(Service service, Func <Service, IEnumerable <IComponentRegistration> > registrationAccessor) { if (service == null) { throw new ArgumentNullException(nameof(service)); } if (registrationAccessor == null) { throw new ArgumentNullException(nameof(registrationAccessor)); } if (!(service is IServiceWithType swt) || service is DecoratorService) { return(Enumerable.Empty <IComponentRegistration>()); } var serviceType = swt.ServiceType; Type elementType = null; Type limitType = null; Func <IEnumerable <object>, object> generator = null; if (serviceType.IsGenericTypeDefinedBy(typeof(IEnumerable <>))) { elementType = serviceType.GetTypeInfo().GenericTypeArguments.First(); limitType = elementType.MakeArrayType(); generator = BuildGenerator(elementType, nameof(Enumerable.ToArray)); } else if (serviceType.IsArray) { elementType = serviceType.GetElementType(); limitType = serviceType; generator = BuildGenerator(elementType, nameof(Enumerable.ToArray)); } else if (serviceType.IsGenericListOrCollectionInterfaceType()) { elementType = serviceType.GetTypeInfo().GenericTypeArguments.First(); limitType = typeof(List <>).MakeGenericType(elementType); generator = BuildGenerator(elementType, nameof(Enumerable.ToList)); } if (elementType == null || limitType == null || generator == null) { return(Enumerable.Empty <IComponentRegistration>()); } var elementTypeService = swt.ChangeType(elementType); var activator = new DelegateActivator( limitType, (c, p) => { var elements = c.ComponentRegistry.RegistrationsFor(elementTypeService).OrderBy(cr => cr.GetRegistrationOrder()); var items = elements.Select(cr => c.ResolveComponent(cr, p)); return(generator(items)); }); var registration = new ComponentRegistration( Guid.NewGuid(), activator, new CurrentScopeLifetime(), InstanceSharing.None, InstanceOwnership.ExternallyOwned, new[] { service }, new Dictionary <string, object>()); return(new IComponentRegistration[] { registration }); }
/// <summary> /// Retrieve registrations for an unregistered service, to be used /// by the container. /// </summary> /// <param name="service">The service that was requested.</param> /// <param name="registrationAccessor">A function that will return existing registrations for a service.</param> /// <returns>Registrations providing the service.</returns> public IEnumerable <IComponentRegistration> RegistrationsFor(Service service, Func <Service, IEnumerable <IComponentRegistration> > registrationAccessor) { if (service == null) { throw new ArgumentNullException(nameof(service)); } if (registrationAccessor == null) { throw new ArgumentNullException(nameof(registrationAccessor)); } var swt = service as IServiceWithType; if (swt == null) { return(Enumerable.Empty <IComponentRegistration>()); } var serviceType = swt.ServiceType; Type elementType = null; if (serviceType.IsGenericEnumerableInterfaceType()) { elementType = serviceType.GetTypeInfo().GenericTypeArguments.First(); } else if (serviceType.IsArray) { elementType = serviceType.GetElementType(); } if (elementType == null) { return(Enumerable.Empty <IComponentRegistration>()); } var elementTypeService = swt.ChangeType(elementType); var elementArrayType = elementType.MakeArrayType(); var listType = typeof(List <>).MakeGenericType(elementType); var serviceTypeIsList = serviceType.IsGenericListOrCollectionInterfaceType(); var activator = new DelegateActivator( elementArrayType, (c, p) => { var elements = c.ComponentRegistry.RegistrationsFor(elementTypeService).OrderBy(cr => cr.GetRegistrationOrder()); var items = elements.Select(cr => c.ResolveComponent(cr, p)).ToArray(); var result = Array.CreateInstance(elementType, items.Length); items.CopyTo(result, 0); return(serviceTypeIsList ? Activator.CreateInstance(listType, result) : result); }); var registration = new ComponentRegistration( Guid.NewGuid(), activator, new CurrentScopeLifetime(), InstanceSharing.None, InstanceOwnership.ExternallyOwned, new[] { service }, new Dictionary <string, object>()); return(new IComponentRegistration[] { registration }); }
public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<ServiceRegistration>> registrationAccessor) { if (service == null) { throw new ArgumentNullException(nameof(service)); } if (registrationAccessor == null) { throw new ArgumentNullException(nameof(registrationAccessor)); } if (!(service is IServiceWithType swt) || service is DecoratorService) { return Enumerable.Empty<IComponentRegistration>(); } var serviceType = swt.ServiceType; Type? elementType = null; Type? limitType = null; Func<int, IList>? factory = null; if (serviceType.IsGenericTypeDefinedBy(typeof(IEnumerable<>))) { elementType = serviceType.GenericTypeArguments[0]; limitType = elementType.MakeArrayType(); factory = GenerateArrayFactory(elementType); } else if (serviceType.IsArray) { elementType = serviceType.GetElementType(); limitType = serviceType; factory = GenerateArrayFactory(elementType); } else if (serviceType.IsGenericListOrCollectionInterfaceType()) { elementType = serviceType.GenericTypeArguments[0]; limitType = typeof(List<>).MakeGenericType(elementType); factory = GenerateListFactory(elementType); } if (elementType == null || factory == null || limitType == null) { return Enumerable.Empty<IComponentRegistration>(); } var elementTypeService = swt.ChangeType(elementType); var activator = new DelegateActivator( limitType, (c, p) => { var itemRegistrations = c.ComponentRegistry .ServiceRegistrationsFor(elementTypeService) .Where(cr => !cr.Registration.Options.HasOption(RegistrationOptions.ExcludeFromCollections)) .OrderBy(cr => cr.Registration.GetRegistrationOrder()) .ToList(); var output = factory(itemRegistrations.Count); var isFixedSize = output.IsFixedSize; for (var i = 0; i < itemRegistrations.Count; i++) { var itemRegistration = itemRegistrations[i]; var resolveRequest = new ResolveRequest(elementTypeService, itemRegistration, p); var component = c.ResolveComponent(resolveRequest); if (isFixedSize) { output[i] = component; } else { output.Add(component); } } return output; }); var registration = new ComponentRegistration( Guid.NewGuid(), activator, CurrentScopeLifetime.Instance, InstanceSharing.None, InstanceOwnership.ExternallyOwned, new[] { service }, new Dictionary<string, object?>()); return new IComponentRegistration[] { registration }; }
private static void CreateChildLifetimeContext(IComponentRegistryBuilder componentRegistryBuilder) { // var setupContainer = componentRegistry ; #if USEHANDLER setupContainer.ResolveOperationBeginning += (sender, args) => { args.ResolveOperation.InstanceLookupBeginning += (o, eventArgs) => { eventArgs.InstanceLookup.InstanceLookupEnding += (sender1, endingEventArgs) => { if (endingEventArgs.NewInstanceActivated) { Logger.Debug("New instance activated"); } }; }; }; #endif var registry = componentRegistry; foreach (var componentRegistryRegistration in registry.Registrations) { if (IsMyRegistration(componentRegistryRegistration)) { Logger.Warn("is my registration"); } else { Logger.Error("is not my registration"); } var seen = new HashSet <object> ( ); Dump(componentRegistryRegistration, seen); if (componentRegistryRegistration.Activator is ReflectionActivator rf) { Logger.Debug(rf.LimitType.ToString( )); var x = new DelegateActivator( rf.LimitType , (context, parameters) => { Logger.Debug( "delegate activation of reflection component success." ); var r = rf.ActivateInstance( context , parameters ); Logger.Debug("got " + r); if (r is IHaveLogger haveLogger) { Logger.Debug( "has IHaveLogger interface." ); if (haveLogger.Logger == null) { Logger.Debug( "logger is null, resolving" ); haveLogger.Logger = context.Resolve <ILogger> ( new TypedParameter( typeof (Type ) , r .GetType( ) ) ); } } return(r); } ); IComponentRegistration componentRegistration = new ComponentRegistration( Guid .NewGuid( ) , x , componentRegistryRegistration .Lifetime , componentRegistryRegistration .Sharing , componentRegistryRegistration .Ownership , componentRegistryRegistration .Services , componentRegistryRegistration .Metadata , componentRegistryRegistration ); Logger.Debug("wrapping reflection with delegate"); try { registry.Register(componentRegistration); } catch (Exception ex) { Logger.Debug(ex, "failure is " + ex.Message); } } else if (componentRegistryRegistration.Activator is DelegateActivator d) { if (!(d is MyActivator)) { if (componentRegistryRegistration.Ownership == InstanceOwnership.ExternallyOwned) { Logger.Debug("Externally owned component registration."); } else { var x = new DelegateActivator( d.LimitType , (context, parameters) => { Logger.Debug("activating !!"); var r = d.ActivateInstance( context , parameters ); Logger.Debug("got " + r); return(r); } ); IComponentRegistration componentRegistration = new ComponentRegistration( Guid.NewGuid( ) , x , componentRegistryRegistration.Lifetime , componentRegistryRegistration.Sharing , componentRegistryRegistration.Ownership , componentRegistryRegistration.Services , componentRegistryRegistration.Metadata , componentRegistryRegistration ); Logger.Debug("wrapping delegate activator"); try { registry.Register(componentRegistration); } catch (Exception ex) { Logger.Debug(ex, "failure is " + ex.Message); } } } } componentRegistryRegistration.Preparing += (sender, args) => { }; componentRegistryRegistration.Activated += (sender, args) => { Logger.Debug($"Activated {args.Instance}"); }; } }
public IEnumerable <IComponentRegistration> RegistrationsFor( Autofac.Core.Service service, Func <Autofac.Core.Service, IEnumerable <IComponentRegistration> > registrationAccessor) { if (!(service is IServiceWithType swt)) { return(Enumerable.Empty <IComponentRegistration>()); } // TODO: Need to investigate this, is not the proper solution if (service is DecoratorService) { return(Enumerable.Empty <IComponentRegistration>()); } Type serviceType = swt.ServiceType; // Ensure is IEnumerable<IPipelineBehavior<,>> if (IsGenericTypeDefined(serviceType, typeof(IEnumerable <>))) { Type enumerableItemType = serviceType.GetGenericArguments().First(); if (IsGenericTypeDefined(enumerableItemType, typeof(IPipelineBehavior <,>))) { Type[] genericTypes = enumerableItemType.GetGenericArguments(); Type requestType = genericTypes[0]; // IQuery<> or ICommand<> Type responseType = genericTypes[1]; // IResponse<TResult> Type resultType = responseType.GetGenericArguments().Single(); // TResult Autofac.Core.Service closePipeline = swt.ChangeType(typeof(IPipelineBehaviour <, ,>).MakeGenericType(new[] { requestType, responseType, resultType })); var activator = new DelegateActivator( enumerableItemType.MakeArrayType(), (ctx, parameters) => { IEnumerable <IComponentRegistration> registrations = ctx.ComponentRegistry.RegistrationsFor(closePipeline); IEnumerable <object> instances = registrations .Select(componentRegistration => ctx.ResolveComponent(componentRegistration, parameters)) .Reverse() .ToArray(); return(OfType(instances, enumerableItemType)); } ); IComponentRegistration registration = new ComponentRegistration( Guid.NewGuid(), activator, new CurrentScopeLifetime(), InstanceSharing.None, InstanceOwnership.OwnedByLifetimeScope, new[] { service }, new Dictionary <string, object>() ); return(new IComponentRegistration[] { registration }); } } return(Enumerable.Empty <IComponentRegistration>()); }