public IApiRepositoryConfig RegisterRepository <TEntity, TMappedEntity, TRepository>() where TEntity : class, IEntity where TMappedEntity : class where TRepository : IRepository { var fullType = typeof(ApiMappedRepository <TEntity, TMappedEntity>); var alias = AliasHelper.GetRepositoryAlias(fullType); if (Repositories.Any(x => x.Alias == alias)) { throw new NotUniqueException(nameof(TRepository)); } var config = new ApiRepositoryConfig { Alias = alias, EntityType = typeof(TEntity), DatabaseType = typeof(TMappedEntity), RepositoryType = typeof(TRepository), ApiRepositoryType = fullType }; Repositories.Add(config); return(config); }
private async Task <HttpResponseMessage> DoRequestAsync(HttpRequestMessage request) { var entityType = typeof(TEntity).FullName; var repoType = typeof(TCorrespondingRepository).FullName; var alias = AliasHelper.GetRepositoryAlias(typeof(ApiRepository <TEntity, TCorrespondingRepository>)); var httpClient = _httpClientFactory.CreateClient(alias); if (httpClient.BaseAddress == default) { throw new InvalidOperationException($"Please configure an HttpClient for the repository '{alias}' using " + $".{nameof(RapidCMSMiddleware.AddRapidCMSApiRepository)}([..]) and configure its BaseAddress correctly."); } var response = await httpClient.SendAsync(request); return(response.StatusCode switch { HttpStatusCode.OK => response, HttpStatusCode.Unauthorized => throw new UnauthorizedAccessException(), HttpStatusCode.Forbidden => throw new UnauthorizedAccessException(), HttpStatusCode.NotFound => throw new NotFoundException($"{request.RequestUri} not found."), _ => throw new InvalidOperationException() });
public void Update(ProductViewModel productViewModel) { var productTags = new List <ProductTag>(); if (!string.IsNullOrEmpty(productViewModel.Tags)) { var tags = productViewModel.Tags.Split(','); foreach (var t in tags) { var tagId = AliasHelper.ConvertToAlias(t); if (!_tagRepository.FindAll(x => x.Id == tagId).Any()) { var tag = new Tag { Id = tagId, Name = t }; _tagRepository.Add(tag); } _productTagRepository.RemoveMultiple(_productTagRepository.FindAll(x => x.Id == productViewModel.Id).ToList()); var productTag = new ProductTag { TagId = tagId }; productTags.Add(productTag); } } var product = _mapper.Map <ProductViewModel, Product>(productViewModel); foreach (var productTag in productTags) { product.ProductTags.Add(productTag); } _productRepository.Update(product); }
public async Task <IActionResult> SaveEntity(ProductViewModel productViewModel) { if (!ModelState.IsValid) { var allErrors = ModelState.Values.SelectMany(v => v.Errors); return(new BadRequestObjectResult(allErrors)); } else { productViewModel.SeoAlias = AliasHelper.ConvertToAlias(productViewModel.Name); if (productViewModel.Id == 0) { var notificationId = Guid.NewGuid().ToString(); var announcement = new AnnouncementViewModel { Title = User.GetSpecificClaim("FullName"), DateCreated = DateTime.Now, Content = $"Product {productViewModel.Name} has been created", Id = notificationId, UserId = User.GetUserId(), Image = User.GetSpecificClaim("Avatar"), Status = Status.Active }; var announcementUsers = new List <AnnouncementUserViewModel>() { new AnnouncementUserViewModel() { AnnouncementId = notificationId, HasRead = false, UserId = User.GetUserId() } }; _productService.Add(announcement, announcementUsers, productViewModel); await _hubContext.Clients.All.SendAsync("ReceiveMessage", announcement); } else { var notificationId = Guid.NewGuid().ToString(); var announcement = new AnnouncementViewModel { Title = User.GetSpecificClaim("FullName"), DateCreated = DateTime.Now, Content = $"Product {productViewModel.Name} has been updated", Id = notificationId, UserId = User.GetUserId(), Image = User.GetSpecificClaim("Avatar"), Status = Status.Active }; var announcementUsers = new List <AnnouncementUserViewModel>() { new AnnouncementUserViewModel() { AnnouncementId = notificationId, HasRead = false, UserId = User.GetUserId() } }; _productService.Update(announcement, announcementUsers, productViewModel); await _hubContext.Clients.All.SendAsync("ReceiveMessage", announcement); } _productService.Save(); return(new OkObjectResult(productViewModel)); } }
public ProductViewModel Add(ProductViewModel productViewModel) { var productTags = new List <ProductTag>(); if (!string.IsNullOrEmpty(productViewModel.Tags)) { var tags = productViewModel.Tags.Split(','); foreach (var t in tags) { var tagId = AliasHelper.ConvertToAlias(t.Trim()); if (!_tagRepository.FindAll(x => x.Id == tagId).Any()) { _tagRepository.Add(new Tag { Id = tagId, Name = t }); } productTags.Add(new ProductTag { TagId = tagId }); } var product = _mapper.Map <ProductViewModel, Product>(productViewModel); foreach (var productTag in productTags) { product.ProductTags.Add(productTag); } _productRepository.Add(product); } return(productViewModel); }
/// <summary> /// Adds a plain HttpClient for the given file upload handler which is hosted at the given baseAddress. /// The ApiFileHandler uses this HttpClient to communicate to the server. /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="services"></param> /// <param name="baseAddress">Base address of the api, for example: https://example.com</param> /// <param name="collectionAlias"></param> /// <returns></returns> public static IHttpClientBuilder AddRapidCMSFileUploadApiHttpClient <THandler>(this IServiceCollection services, Uri baseUri) where THandler : IFileUploadHandler { var alias = AliasHelper.GetFileUploaderAlias(typeof(THandler)); return(services.AddHttpClient <ApiFileUploadHandler <THandler> >(alias) .ConfigureHttpClient(x => x.BaseAddress = new Uri(baseUri, $"api/_rapidcms/{alias}/"))); }
public EntityModelJsonConverter() { var derivedTypes = typeof(TEntity).Assembly .GetTypes() .Where(x => !x.IsAbstract && x.IsSubclassOf(typeof(TEntity))); _typeDictionary = derivedTypes.Append(typeof(TEntity)).ToDictionary(x => AliasHelper.GetEntityVariantAlias(x)); }
public ApiMappedRepository(IHttpClientFactory httpClientFactory) { var jsonSerializerSettings = new JsonSerializerSettings(); jsonSerializerSettings.Converters.Add(new EntityModelJsonConverter <TEntity>()); var repositoryAlias = AliasHelper.GetRepositoryAlias(typeof(ApiMappedRepository <TEntity, TDatabaseEntity>)); _apiRepositoryHelper = new ApiRepositoryHelper(httpClientFactory, jsonSerializerSettings, repositoryAlias); }
public ApiRepository(IHttpClientFactory httpClientFactory, IMemoryCache memoryCache) { var jsonSerializerSettings = new JsonSerializerSettings(); jsonSerializerSettings.Converters.Add(new EntityModelJsonConverter <TEntity>()); var repositoryAlias = AliasHelper.GetRepositoryAlias(typeof(ApiRepository <TEntity, TCorrespondingRepository>)); _apiRepositoryHelper = new ApiRepositoryHelper(memoryCache, httpClientFactory, jsonSerializerSettings, repositoryAlias); }
public static NavigationRequest NavigateToCreateNewEntity(string collectionAlias, IParent?parent, Type?entityVariant = null) { return(new NavigationRequest(collectionAlias) { ParentPath = parent?.GetParentPath(), IsEdit = true, IsNew = true, VariantAlias = entityVariant == null ? null : AliasHelper.GetEntityVariantAlias(entityVariant) }); }
public IApiConfig RegisterFileUploadHandler <THandler>() where THandler : IFileUploadHandler { FileUploadHandlers.Add(new FileUploadHandlerConfig { Alias = AliasHelper.GetFileUploaderAlias(typeof(THandler)), HandlerType = typeof(THandler) }); return(this); }
public CmsRepositoryTypeResolver(ICmsConfig cmsConfig, IServiceProvider serviceProvider) { using var repositoryResolvingScope = serviceProvider.CreateScope(); var types = cmsConfig.RepositoryTypes.Distinct(); _repositoryTypes = types.ToDictionary( type => AliasHelper.GetRepositoryAlias(repositoryResolvingScope.ServiceProvider.GetRequiredService(type).GetType())); _originallyRegisterdRepositoriesToAlias = _repositoryTypes.ToDictionary(x => x.Value, x => x.Key); }
/// <summary> /// Adds the repository as scoped service and adds a plain HttpClient for the given repository. /// </summary> /// <typeparam name="TIRepository"></typeparam> /// <typeparam name="TRepository"></typeparam> /// <param name="services"></param> /// <param name="baseUri"></param> /// <returns></returns> public static IHttpClientBuilder AddRapidCMSApiRepository <TIRepository, TRepository>(this IServiceCollection services, Uri baseUri) where TIRepository : class where TRepository : class, TIRepository { var alias = AliasHelper.GetRepositoryAlias(typeof(TRepository)); services.AddScoped <TIRepository, TRepository>(); return(services.AddHttpClient(alias) .ConfigureHttpClient(x => x.BaseAddress = new Uri(baseUri, $"api/_rapidcms/{alias}/"))); }
private static void AddServicesRequiringRepositories(IServiceCollection services, CmsConfig rootConfig) { var repositoryTypeDictionary = new Dictionary <string, Type>(); var reverseRepositoryTypeDictionary = new Dictionary <Type, string>(); var collectionAliasDictionary = new Dictionary <string, List <string> >(); foreach (var collection in rootConfig.CollectionsAndPages.OfType <ICollectionConfig>()) { ProcessCollection(collection); } services.AddSingleton <IRepositoryTypeResolver>(new CmsRepositoryTypeResolver(repositoryTypeDictionary, reverseRepositoryTypeDictionary)); services.AddSingleton <ICollectionAliasResolver>(new CollectionAliasResolver(collectionAliasDictionary)); void ProcessCollection(ICollectionConfig collection) { foreach (var repository in collection.RepositoryTypes) { var descriptor = services.FirstOrDefault(x => x.ServiceType == repository); if (descriptor == null) { continue; } var implementationType = descriptor.ImplementationType; if (implementationType == null) { continue; } var repositoryAlias = AliasHelper.GetRepositoryAlias(implementationType); repositoryTypeDictionary[repositoryAlias] = repository; reverseRepositoryTypeDictionary[repository] = repositoryAlias; if (implementationType != repository) { reverseRepositoryTypeDictionary[implementationType] = repositoryAlias; } if (!collectionAliasDictionary.ContainsKey(repositoryAlias)) { collectionAliasDictionary.Add(repositoryAlias, new List <string>()); } collectionAliasDictionary[repositoryAlias].Add(collection.Alias); } foreach (var subCollection in collection.CollectionsAndPages.OfType <ICollectionConfig>().Where(x => x is not ReferencedCollectionConfig)) { ProcessCollection(subCollection); } } }
private static void AddServicesRequiringRepositories(IServiceCollection services, CmsConfig rootConfig) { var repositoryTypeDictionary = new Dictionary <string, Type>(); var reverseRepositoryTypeDictionary = new Dictionary <Type, string>(); var collectionAliasDictionary = new Dictionary <string, List <string> >(); foreach (var collection in rootConfig.CollectionsAndPages.OfType <ICollectionConfig>()) { ProcessCollection(collection); } services.AddSingleton <IRepositoryTypeResolver>(new CmsRepositoryTypeResolver(repositoryTypeDictionary, reverseRepositoryTypeDictionary)); services.AddSingleton <ICollectionAliasResolver>(new CollectionAliasResolver(collectionAliasDictionary)); void ProcessCollection(ICollectionConfig collection) { var descriptor = services.FirstOrDefault(x => x.ServiceType == collection.RepositoryType); if (descriptor == null) { throw new InvalidOperationException($"Could not find service descriptor for {collection.RepositoryType}. Please add it to the service collection."); } var implementationType = descriptor.ImplementationType; if (implementationType == null) { throw new InvalidOperationException($"Could not find implementation type for {collection.RepositoryType}. Please add it as type to the service collection."); } var repositoryAlias = AliasHelper.GetRepositoryAlias(implementationType); repositoryTypeDictionary[repositoryAlias] = collection.RepositoryType; reverseRepositoryTypeDictionary[collection.RepositoryType] = repositoryAlias; if (implementationType != collection.RepositoryType) { reverseRepositoryTypeDictionary[implementationType] = repositoryAlias; } if (!collectionAliasDictionary.ContainsKey(repositoryAlias)) { collectionAliasDictionary.Add(repositoryAlias, new List <string>()); } collectionAliasDictionary[repositoryAlias].Add(collection.Alias); foreach (var subCollection in collection.CollectionsAndPages.OfType <ICollectionConfig>().Where(x => !x.Recursive)) { ProcessCollection(subCollection); } } }
public static EntityModel <T> Create <T>(T entity) { if (entity == null) { throw new ArgumentNullException(nameof(entity)); } return(new EntityModel <T> { Entity = entity, VariantAlias = AliasHelper.GetEntityVariantAlias(entity.GetType()) }); }
public GenericResult Update(AnnouncementViewModel announcementViewModel, List <AnnouncementUserViewModel> announcementUsers, ProductViewModel productViewModel) { try { var product = _mapper.Map <ProductViewModel, Product>(productViewModel); if (!string.IsNullOrEmpty(productViewModel.Tags)) { var productTags = new List <ProductTag>(); var tags = productViewModel.Tags.Split(','); foreach (var t in tags) { var tagId = AliasHelper.ConvertToAlias(t.Trim()); if (!_tagRepository.FindAll(x => x.Id == tagId).Any()) { _tagRepository.Add(new Tag { Id = tagId, Name = t }); } _productTagRepository.RemoveMultiple(_productTagRepository.FindAll(x => x.Id == productViewModel.Id) .ToList()); productTags.Add(new ProductTag { TagId = tagId }); } foreach (var productTag in productTags) { product.ProductTags.Add(productTag); } } _productRepository.Update(product); // Real Time var announcement = _mapper.Map <AnnouncementViewModel, Announcement>(announcementViewModel); _announceRepository.Add(announcement); foreach (var announcementUserViewModel in announcementUsers) { _announceUserRepository.Add(_mapper.Map <AnnouncementUserViewModel, AnnouncementUser>(announcementUserViewModel)); } return(new GenericResult(true, "Update Successful", "Successful")); } catch (Exception) { return(new GenericResult(false, "Update Failed", "Error")); } }
public EditContextModel(IEditContext <TEntity> editContext) { EntityModel = ApiBridge.EntityModel.Create(editContext.Entity); ParentPath = editContext.Parent?.GetParentPath()?.ToPathString(); var container = editContext.GetRelationContainer(); RelationContainer = new RelationContainerModel { Relations = container.Relations.Select(relation => { return(new RelationModel { Elements = relation.RelatedElements.Select(el => el.Id), PropertyName = relation.Property.PropertyName, VariantAlias = AliasHelper.GetEntityVariantAlias(relation.RelatedEntityType) }); }) }; }
public IActionResult SaveEntity(ProductViewModel productViewModel) { if (!ModelState.IsValid) { var allErrors = ModelState.Values.SelectMany(v => v.Errors); return(new BadRequestObjectResult(allErrors)); } else { productViewModel.SeoAlias = AliasHelper.ConvertToAlias(productViewModel.Name); if (productViewModel.Id == 0) { _productService.Add(productViewModel); } else { _productService.Update(productViewModel); } _productService.Save(); return(new OkObjectResult(productViewModel)); } }
public GenericResult Add(ProductViewModel productViewModel) { try { var product = _mapper.Map <ProductViewModel, Product>(productViewModel); if (!string.IsNullOrEmpty(productViewModel.Tags)) { var productTags = new List <ProductTag>(); var tags = productViewModel.Tags.Split(','); foreach (var t in tags) { var tagId = AliasHelper.ConvertToAlias(t.Trim()); if (!_tagRepository.FindAll(x => x.Id == tagId).Any()) { _tagRepository.Add(new Tag { Id = tagId, Name = t }); } productTags.Add(new ProductTag { TagId = tagId }); } foreach (var productTag in productTags) { product.ProductTags.Add(productTag); } } _productRepository.Add(product); return(new GenericResult(true, "Add Successful", "Successful")); } catch (Exception) { return(new GenericResult(false, "Add Failed", "Error")); } }
public GlobalEntityVariantSetupResolver() { _types = typeof(IEntity).GetImplementingTypes().ToDictionary(x => AliasHelper.GetEntityVariantAlias(x)); }
public ApiFileUploadHandler( IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; _handlerAlias = AliasHelper.GetFileUploaderAlias(typeof(THandler)); }
/// <summary> /// Use this method to setup the Repository APIs to support RapidCMS WebAssenbly on a separate server. /// </summary> /// <param name="services"></param> /// <param name="config"></param> /// <returns></returns> public static IServiceCollection AddRapidCMSApi(this IServiceCollection services, Action <IApiConfig>?config = null) { if (_routeConvention != null || _controllerFeatureProvider != null) { throw new InvalidOperationException("Cannot call AddRapidCMSApi twice."); } var rootConfig = GetRootConfig(config); services.AddSingleton <IApiConfig>(rootConfig); services.AddHttpContextAccessor(); if (rootConfig.AllowAnonymousUsage) { services.AddSingleton <IAuthorizationHandler, AllowAllAuthorizationHandler>(); services.AddSingleton <AuthenticationStateProvider, AnonymousAuthenticationStateProvider>(); } else { services.AddSingleton <AuthenticationStateProvider, HttpContextAuthenticationStateProvider>(); } services.AddSingleton <ISetupResolver <IEntityVariantSetup>, GlobalEntityVariantSetupResolver>(); services.AddTransient <IDataViewResolver, ApiDataViewResolver>(); services.AddTransient <IRepositoryResolver, RepositoryResolver>(); services.AddSingleton <IRepositoryTypeResolver, ApiRepositoryTypeResolver>(); services.AddTransient <IPresentationDispatcher, GetEntityDispatcher>(); services.AddTransient <IPresentationDispatcher, GetEntitiesDispatcher>(); services.AddTransient <IPresentationService, PresentationService>(); services.AddTransient <IInteractionDispatcher, RelateEntityDispatcher>(); services.AddTransient <IInteractionDispatcher, ReorderEntityDispatcher>(); services.AddTransient <IInteractionDispatcher, PersistEntityDispatcher>(); services.AddTransient <IInteractionDispatcher, DeleteEntityDispatcher>(); services.AddTransient <IInteractionService, InteractionService>(); services.AddTransient <IAuthService, ApiAuthService>(); services.AddSingleton <IExceptionService, ExceptionService>(); // TODO: message service services.AddTransient <IParentService, ParentService>(); services.AddTransient <IEditContextFactory, ApiEditContextWrapperFactory>(); var controllersToAdd = rootConfig.Repositories.ToDictionary( repository => { if (repository.DatabaseType == default) { return(typeof(ApiRepositoryController <,>) .MakeGenericType(repository.EntityType, repository.RepositoryType) .GetTypeInfo()); } else { return(typeof(MappedApiRepositoryController <, ,>) .MakeGenericType(repository.EntityType, repository.DatabaseType, repository.RepositoryType) .GetTypeInfo()); } }, kv => kv.Alias); if (rootConfig.FileUploadHandlers.Any()) { foreach (var handler in rootConfig.FileUploadHandlers) { var type = typeof(ApiFileUploadController <>).MakeGenericType(handler).GetTypeInfo(); var alias = AliasHelper.GetFileUploaderAlias(type); controllersToAdd.Add(type, alias); } } _controllerFeatureProvider = new CollectionControllerFeatureProvider(controllersToAdd.Keys); _routeConvention = new CollectionControllerRouteConvention(controllersToAdd); return(services); }
public IResolvedSetup <IEntityVariantSetup> ResolveSetup(EntityVariantConfig config, ICollectionSetup?collection = default) { if (collection == null) { throw new ArgumentNullException(nameof(collection)); } if (config == default) { return(new ResolvedSetup <IEntityVariantSetup>(EntityVariantSetup.Undefined, true)); } else { return(new ResolvedSetup <IEntityVariantSetup>( new EntityVariantSetup(config.Name, config.Icon, config.Type, AliasHelper.GetEntityVariantAlias(config.Type)), true)); } }
public ParentQueryModel(IParent?parent, Type?variantType, IQuery query) : this(parent, query) { VariantAlias = variantType == null ? null : AliasHelper.GetEntityVariantAlias(variantType); }