Ejemplo n.º 1
0
        public void GetCacheTemplateFromReflectionType()
        {
            var reflectionType     = typeof(IProductRepository);
            var cacheConfiguration = new InterfaceCacheConfiguration();
            var template           = reflectionType.GetCacheTemplateFromReflectionType(cacheConfiguration);

            Assert.Equal(reflectionType.FullName, template.InterfaceName);
        }
        private static void DecorateWithCacheProxy(this IServiceCollection services, InterfaceCacheConfiguration repositoryInterface)
        {
            var serviceMatched = services.FirstOrDefault(x => x.ServiceType.Name == repositoryInterface.Name);

            if (serviceMatched == null)
            {
                return;
            }

            var typeService = serviceMatched.ServiceType;

            services.Decorate(typeService, (service, provider) =>
            {
                return(CreateCacheProxy(provider, typeService, service, repositoryInterface));
            });
        }
        private static IEnumerable <InterfaceCacheConfiguration> GetInterfaceCacheConfigurations(this IConfiguration configuration, string keyConfiguration)
        {
            var dynamicServices = configuration.GetSection(keyConfiguration).GetChildren();

            foreach (var serviceConfiguration in dynamicServices)
            {
                var interfaceCacheConfiguration = new InterfaceCacheConfiguration(serviceConfiguration.Key);
                var methodsConfiguration        = serviceConfiguration.GetChildren();
                foreach (var methodConfiguration in methodsConfiguration)
                {
                    var methodName = methodConfiguration.Key;
                    var methodCacheConfiguration = methodConfiguration.Get <MethodCacheConfiguration>();
                    interfaceCacheConfiguration
                    .AddMethod(methodName, methodCacheConfiguration.KeyTemplate, methodCacheConfiguration.ExpirationSeconds);
                }
                yield return(interfaceCacheConfiguration);
            }
        }
        private static dynamic CreateCacheProxy(
            IServiceProvider services,
            Type typeService,
            dynamic decoratedService,
            InterfaceCacheConfiguration repositoryInterface)
        {
            var     nameCreateMethod     = nameof(DispatchProxy.Create);
            var     dispatchProxyMethod  = typeof(DispatchProxy).GetMethod(nameCreateMethod);
            var     cacheRepositoryProxy = typeof(DefensiveCacheProxy <>).MakeGenericType(typeService);
            dynamic proxy = dispatchProxyMethod.MakeGenericMethod(typeService, cacheRepositoryProxy).Invoke(null, null);

            var typeLogger      = typeof(ILogger <>).MakeGenericType(typeService);
            var logger          = (ILogger)services.GetService(typeLogger);
            var cacheSerializer = services.GetService <ICacheSerializer>();

            proxy.Decorated           = decoratedService;
            proxy.Logger              = logger;
            proxy.CacheSerializer     = cacheSerializer;
            proxy.RepositoryInterface = repositoryInterface;
            return(proxy);
        }
        public static CacheTemplate GetCacheTemplateFromReflectionType(this Type type, InterfaceCacheConfiguration cacheConfiguration)
        {
            if (type == null)
            {
                throw new Exception("Service type is no defined.");
            }

            if (!type.IsInterface)
            {
                throw new Exception("Only service interfaces are allowed for cache code generation.");
            }

            var cacheTemplate = new CacheTemplate(type);

            foreach (var method in type.GetAllMethods())
            {
                var methodConfiguration = cacheConfiguration.Methods.FirstOrDefault(x => x.Name == method.Name);
                var cacheMethod         = new CacheMethodTemplate(method, methodConfiguration);
                cacheTemplate.AddMethod(cacheMethod);
            }
            ;
            foreach (var property in type.GetProperties())
            {
                cacheTemplate.AddProperty(property);
            }

            var methodNamesCacheTemplate      = cacheTemplate.Methods.Select(m => m.Name);
            var methodNamesCacheConfiguration = cacheConfiguration.Methods.Select(m => m.Name);
            var methodsNotMatched             = methodNamesCacheConfiguration?.Where(x => !methodNamesCacheTemplate?.Contains(x) ?? false);

            if (methodsNotMatched?.Any() ?? false)
            {
                var methodName = methodsNotMatched.FirstOrDefault();
                throw new Exception($"Method '{methodName}' not found in interface {type.Name}.");
            }

            return(cacheTemplate);
        }
        public static string GenerateCacheCodeFromType(this Type type, InterfaceCacheConfiguration cacheConfiguration)
        {
            var cacheTemplate = type.GetCacheTemplateFromReflectionType(cacheConfiguration);

            return(GenerateCacheCode(cacheTemplate));
        }
        public static void DecorateWithCacheDynamicService(this IServiceCollection services, InterfaceCacheConfiguration cacheConfiguration)
        {
            var serviceMatched = services.FirstOrDefault(x => x.ServiceType.Name == cacheConfiguration.Name);

            if (serviceMatched == null)
            {
                return;
            }

            var typeService   = serviceMatched.ServiceType;
            var cacheTemplate = typeService.GetCacheTemplateFromReflectionType(cacheConfiguration);
            var cacheCode     = TemplateService.GenerateCacheCode(cacheTemplate);
            var assemblyCache = CompilerService.GenerateAssemblyFromCode(typeService.Assembly, cacheTemplate.Name, cacheCode);
            var typeCache     = assemblyCache.GetTypes().FirstOrDefault();

            services.Decorate(typeService, typeCache);
        }
        public static void DecorateWithCacheGeneratedService(this IServiceCollection services, Assembly assembly, InterfaceCacheConfiguration cacheConfiguration)
        {
            var serviceMatched = services.FirstOrDefault(x => x.ServiceType.Name == cacheConfiguration.Name);

            if (serviceMatched == null)
            {
                return;
            }

            var typeService   = serviceMatched.ServiceType;
            var generatedType = assembly.GetTypes().FirstOrDefault(x => x.Name == cacheConfiguration.Name + CacheTemplate.NameSuffix);

            if (generatedType == null)
            {
                return;
            }

            services.Decorate(typeService, generatedType);
        }