public void ResolveWithDefaultResolver() { RepositoryDependencyResolver.SetResolver(new RepositoryDependencyResolver.DefaultDependencyResolver()); Assert.NotNull(RepositoryDependencyResolver.Current.Resolve <ClassToResolve>()); Assert.NotNull((ClassToResolve)RepositoryDependencyResolver.Current.Resolve(typeof(ClassToResolve))); }
public void ResolveWithDelegateResolver() { RepositoryDependencyResolver.SetResolver(type => new ClassToResolve()); Assert.NotNull(RepositoryDependencyResolver.Current.Resolve <ClassToResolve>()); Assert.NotNull((ClassToResolve)RepositoryDependencyResolver.Current.Resolve(typeof(ClassToResolve))); }
public void ThrowsIfUnitOfWorkCreateWithDefaultDependencyResolverForResolvingOptions() { RepositoryDependencyResolver.SetResolver(new RepositoryDependencyResolver.DefaultDependencyResolver()); var ex = Assert.Throws <InvalidOperationException>(() => new UnitOfWork()); Assert.Equal($"Unable to resolve an instance for '{typeof(IRepositoryOptions).FullName}'. Please consider using the RepositoryDependencyResolver to use an IOC container.", ex.Message); }
public void ThrowsIfDefaultResolverResolvesAbstractClasses() { RepositoryDependencyResolver.SetResolver(new RepositoryDependencyResolver.DefaultDependencyResolver()); var ex = Assert.Throws <InvalidOperationException>(() => RepositoryDependencyResolver.Current.Resolve <AbstractClassToResolve>()); Assert.Equal($"Unable to resolve an instance for '{typeof(AbstractClassToResolve).FullName}'. Please consider using the RepositoryDependencyResolver to use an IOC container.", ex.Message); }
public void SetCurrentResolver() { RepositoryDependencyResolver.SetResolver(new RepositoryDependencyResolver.DefaultDependencyResolver()); Assert.Equal(typeof(RepositoryDependencyResolver.DefaultDependencyResolver), RepositoryDependencyResolver.Current.GetType()); }
/// <summary> /// Adds all the repository services using the specified options builder. /// </summary> /// <param name="services">The service collection.</param> /// <param name="optionsAction">A builder action used to create or modify options for the repositories.</param> /// <param name="assembliesToScan">The assemblies to scan.</param> /// <param name="serviceLifetime">The Microsoft.Extensions.DependencyInjection.ServiceLifetime of the service.</param> /// <returns>The same instance of the service collection which has been configured with the repositories.</returns> /// <remarks> /// This method will scan for repositories and interceptors from the specified assemblies collection, and will register them to the container. /// </remarks> public static IServiceCollection AddRepositories([NotNull] this IServiceCollection services, [NotNull] Action <RepositoryOptionsBuilder> optionsAction, [NotNull] Assembly[] assembliesToScan, ServiceLifetime serviceLifetime = ServiceLifetime.Transient) { Guard.NotNull(services, nameof(services)); Guard.NotNull(optionsAction, nameof(optionsAction)); Guard.NotEmpty(assembliesToScan, nameof(assembliesToScan)); var optionsBuilder = new RepositoryOptionsBuilder(); optionsAction(optionsBuilder); var scanResults = AssemblyScanner.FindRepositoriesFromAssemblies(assembliesToScan); // Register scanned types scanResults.ForEach(scanResult => { foreach (var implementationType in scanResult.ImplementationTypes) { // Register as interface services.Add(new ServiceDescriptor( scanResult.InterfaceType, implementationType, serviceLifetime)); // Register as self services.Add(new ServiceDescriptor( implementationType, implementationType, serviceLifetime)); } }); // Register options services services.Add(new ServiceDescriptor( typeof(IRepositoryOptions), sp => { var options = new RepositoryOptions(optionsBuilder.Options); foreach (var interceptorType in scanResults.OfType <IRepositoryInterceptor>()) { if (!options.Interceptors.ContainsKey(interceptorType)) { options = options.With(interceptorType, () => (IRepositoryInterceptor)sp.GetService(interceptorType)); } } if (options.LoggerProvider == null) { var loggerProviderType = scanResults.OfType <ILoggerProvider>().FirstOrDefault(); if (loggerProviderType != null) { options = options.With((ILoggerProvider)sp.GetService(loggerProviderType)); } } if (options.CachingProvider == null) { var cacheProviderType = scanResults.OfType <ICacheProvider>().FirstOrDefault(); if (cacheProviderType != null) { options = options.With((ICacheProvider)sp.GetService(cacheProviderType)); } } return(options); }, serviceLifetime)); // Register resolver var serviceProvider = services.BuildServiceProvider(); RepositoryDependencyResolver.SetResolver(type => serviceProvider.GetService(type)); services.AddSingleton <IRepositoryDependencyResolver>(sp => RepositoryDependencyResolver.Current); return(services); }
/// <summary> /// Register all the repositories services using the specified options builder. /// </summary> /// <param name="container">The unity container.</param> /// <param name="optionsAction">A builder action used to create or modify options for the repositories.</param> /// <param name="assembliesToScan">The assemblies to scan.</param> /// <remarks> /// This method will scan for repositories and interceptors from the specified assemblies collection, and will register them to the container. /// </remarks> public static void RegisterRepositories([NotNull] this IUnityContainer container, [NotNull] Action<RepositoryOptionsBuilder> optionsAction, [NotNull] params Assembly[] assembliesToScan) { Guard.NotNull(container, nameof(container)); Guard.NotNull(optionsAction, nameof(optionsAction)); Guard.NotEmpty(assembliesToScan, nameof(assembliesToScan)); var baseAssembly = Assembly.Load("DotNetToolkit.Repository"); var assToScan = !assembliesToScan.Any(x => x.FullName.Equals(baseAssembly.FullName)) ? assembliesToScan.Concat(new[] { baseAssembly }) : assembliesToScan; var types = assToScan.SelectMany(x => x.GetAccessibleTypes()); var interfaceTypesToScan = new[] { typeof(IService<>), typeof(IService<,>), typeof(IService<,,>), typeof(IService<,,,>), typeof(IRepository<>), typeof(IRepository<,>), typeof(IRepository<,,>), typeof(IRepository<,,,>), typeof(IReadOnlyService<>), typeof(IReadOnlyService<,>), typeof(IReadOnlyService<,,>), typeof(IReadOnlyService<,,,>), typeof(IReadOnlyRepository<>), typeof(IReadOnlyRepository<,>), typeof(IReadOnlyRepository<,,>), typeof(IReadOnlyRepository<,,,>), typeof(IRepositoryInterceptor) }; // Gets all the interfaces that inherent from IRepository<> or IRepositoryInterceptor var interfaceTypes = interfaceTypesToScan .SelectMany(interfaceType => types.Where(t => !t.IsClass && t.ImplementsInterface(interfaceType))) .Distinct(); var serviceTypesMapping = interfaceTypes .SelectMany(interfaceType => types.Where(t => t.IsClass && !t.IsAbstract && t.ImplementsInterface(interfaceType)) .GroupBy(t => interfaceType, t => t)); // Register the repositories and interceptors that have been scanned var optionsBuilder = new RepositoryOptionsBuilder(); optionsAction(optionsBuilder); var registeredInterceptorTypes = new List<Type>(); foreach (var t in serviceTypesMapping) { var serviceType = t.Key; var implementationTypes = t.Where(x => x.IsGenericType == serviceType.IsGenericType && x.GetGenericArguments().Length == serviceType.GetGenericArguments().Length && x.IsVisible && !x.IsAbstract); foreach (var implementationType in implementationTypes) { if (serviceType == typeof(IRepositoryInterceptor)) { if (container.IsRegistered(implementationType) || optionsBuilder.Options.Interceptors.ContainsKey(implementationType)) continue; container.RegisterType(implementationType, implementationType); container.RegisterType(serviceType, implementationType, implementationType.FullName); registeredInterceptorTypes.Add(implementationType); } else { container.RegisterType(serviceType, implementationType); } } } // Register other services container.RegisterFactory<IRepositoryFactory>(c => new RepositoryFactory(c.Resolve<IRepositoryOptions>())); container.RegisterFactory<IUnitOfWork>(c => new UnitOfWork(c.Resolve<IRepositoryOptions>())); container.RegisterFactory<IUnitOfWorkFactory>(c => new UnitOfWorkFactory(c.Resolve<IRepositoryOptions>())); container.RegisterFactory<IServiceFactory>(c => new ServiceFactory(c.Resolve<IUnitOfWorkFactory>())); container.RegisterFactory<IRepositoryOptions>(c => { var options = new RepositoryOptions(optionsBuilder.Options); foreach (var interceptorType in registeredInterceptorTypes) { options = options.With(interceptorType, () => (IRepositoryInterceptor)c.Resolve(interceptorType)); } return options; }); // Register resolver RepositoryDependencyResolver.SetResolver(type => container.Resolve(type)); container.RegisterFactory<IRepositoryDependencyResolver>(c => RepositoryDependencyResolver.Current); }
/// <summary> /// Register all the repositories services using the specified options builder. /// </summary> /// <param name="container">The unity container.</param> /// <param name="optionsAction">A builder action used to create or modify options for the repositories.</param> /// <param name="assembliesToScan">The assemblies to scan.</param> /// <param name="typelifetimeManager">The type lifetime manager for the service.</param> /// <param name="factorylifetimeManager">The factory lifetime manager for the service.</param> /// <remarks> /// This method will scan for repositories and interceptors from the specified assemblies collection, and will register them to the container. /// </remarks> public static void RegisterRepositories([NotNull] this IUnityContainer container, [NotNull] Action <RepositoryOptionsBuilder> optionsAction, [NotNull] Assembly[] assembliesToScan, ITypeLifetimeManager typelifetimeManager = null, IFactoryLifetimeManager factorylifetimeManager = null) { Guard.NotNull(container, nameof(container)); Guard.NotNull(optionsAction, nameof(optionsAction)); Guard.NotEmpty(assembliesToScan, nameof(assembliesToScan)); var optionsBuilder = new RepositoryOptionsBuilder(); optionsAction(optionsBuilder); var scanResults = AssemblyScanner.FindRepositoriesFromAssemblies(assembliesToScan); // Register scanned types scanResults.ForEach(scanResult => { foreach (var implementationType in scanResult.ImplementationTypes) { container.RegisterType(implementationType); if (scanResult.InterfaceType == typeof(IRepositoryInterceptor)) { container.RegisterType(scanResult.InterfaceType, implementationType, implementationType.FullName); } else { container.RegisterType(scanResult.InterfaceType, implementationType); } } }); // Register options services container.RegisterFactory <IRepositoryOptions>(c => { var options = new RepositoryOptions(optionsBuilder.Options); foreach (var interceptorType in scanResults.OfType <IRepositoryInterceptor>()) { if (!options.Interceptors.ContainsKey(interceptorType)) { options = options.With(interceptorType, () => (IRepositoryInterceptor)c.Resolve(interceptorType)); } } if (options.LoggerProvider == null) { var loggerProviderType = scanResults.OfType <ILoggerProvider>().FirstOrDefault(); if (loggerProviderType != null) { options = options.With((ILoggerProvider)c.Resolve(loggerProviderType)); } } if (options.CachingProvider == null) { var cacheProviderType = scanResults.OfType <ICacheProvider>().FirstOrDefault(); if (cacheProviderType != null) { options = options.With((ICacheProvider)c.Resolve(cacheProviderType)); } } return(options); }, factorylifetimeManager); // Register resolver RepositoryDependencyResolver.SetResolver(type => container.Resolve(type)); container.RegisterFactory <IRepositoryDependencyResolver>(c => RepositoryDependencyResolver.Current, new ContainerControlledLifetimeManager()); }
/// <summary> /// Binds all the repositories services using the specified options builder. /// </summary> /// <param name="kernel">The kernel.</param> /// <param name="optionsAction">A builder action used to create or modify options for the repositories.</param> /// <param name="assembliesToScan">The assemblies to scan.</param> /// <remarks> /// This method will scan for repositories and interceptors from the specified assemblies collection, and will bind them to the container. /// </remarks> public static void BindRepositories([NotNull] this IKernel kernel, [NotNull] Action <RepositoryOptionsBuilder> optionsAction, [NotNull] params Assembly[] assembliesToScan) { Guard.NotNull(kernel, nameof(kernel)); Guard.NotNull(optionsAction, nameof(optionsAction)); Guard.NotEmpty(assembliesToScan, nameof(assembliesToScan)); var optionsBuilder = new RepositoryOptionsBuilder(); optionsAction(optionsBuilder); var scanResults = AssemblyScanner.FindRepositoriesFromAssemblies(assembliesToScan); // Binds scanned types scanResults.ForEach(scanResult => { foreach (var implementationType in scanResult.ImplementationTypes) { kernel.Bind(implementationType).ToSelf(); kernel.Bind(scanResult.InterfaceType).To(implementationType); } }); // Binds options services kernel.Bind <IRepositoryOptions>().ToMethod(c => { var options = new RepositoryOptions(optionsBuilder.Options); foreach (var interceptorType in scanResults.OfType <IRepositoryInterceptor>()) { if (!options.Interceptors.ContainsKey(interceptorType)) { options = options.With(interceptorType, () => (IRepositoryInterceptor)c.Kernel.Get(interceptorType)); } } if (options.LoggerProvider == null) { var loggerProviderType = scanResults.OfType <ILoggerProvider>().FirstOrDefault(); if (loggerProviderType != null) { options = options.With((ILoggerProvider)c.Kernel.Get(loggerProviderType)); } } if (options.CachingProvider == null) { var cacheProviderType = scanResults.OfType <ICacheProvider>().FirstOrDefault(); if (cacheProviderType != null) { options = options.With((ICacheProvider)c.Kernel.Get(cacheProviderType)); } } return(options); }); // Binds resolver RepositoryDependencyResolver.SetResolver(type => kernel.Get(type)); kernel.Bind <IRepositoryDependencyResolver>().ToMethod(c => RepositoryDependencyResolver.Current); }