diff --git a/zero.Core/Api/ApplicationsApi.cs b/zero.Core/Api/ApplicationsApi.cs index 8242c4c2..81f06daf 100644 --- a/zero.Core/Api/ApplicationsApi.cs +++ b/zero.Core/Api/ApplicationsApi.cs @@ -8,31 +8,31 @@ using zero.Core.Extensions; namespace zero.Core.Api { - public class ApplicationsApi : BackofficeApi, IApplicationsApi where T : IApplication + public class ApplicationsApi : BackofficeApi, IApplicationsApi { - IValidator Validator; + IValidator Validator; - public ApplicationsApi(IBackofficeStore store, IValidator validator) : base(store) + public ApplicationsApi(IBackofficeStore store) : base(store) { - Validator = validator; + Validator = null; } /// - public async Task GetById(string id) + public async Task GetById(string id) { - return await GetById(id); + return await GetById(id); } /// - public async Task> GetAll() + public async Task> GetAll() { using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) { return await session - .Query() + .Query() .OrderByDescending(x => x.CreatedDate) .ToListAsync(); } @@ -40,58 +40,58 @@ namespace zero.Core.Api /// - public async Task> GetByQuery(ListQuery query) + public async Task> GetByQuery(ListQuery query) { query.SearchFor(entity => entity.Name); using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) { - return await session.Query() + return await session.Query() .ToQueriedListAsync(query); } } /// - public async Task> Save(T model) + public async Task> Save(IApplication model) { return await SaveModel(model, Validator); } /// - public async Task> Delete(string id) + public async Task> Delete(string id) { - return await DeleteById(id); + return await DeleteById(id); } } - public interface IApplicationsApi where T : IApplication + public interface IApplicationsApi { /// /// Get application by Id /// - Task GetById(string id); + Task GetById(string id); /// /// Get all available zero applications /// - Task> GetAll(); + Task> GetAll(); /// /// Get all available applications (with query) /// - Task> GetByQuery(ListQuery query); + Task> GetByQuery(ListQuery query); /// /// Creates or updates a application /// - Task> Save(T model); + Task> Save(IApplication model); /// /// Deletes a application by Id /// - Task> Delete(string id); + Task> Delete(string id); } } diff --git a/zero.Core/Api/CountriesApi.cs b/zero.Core/Api/CountriesApi.cs index 81445c0c..3f7bcead 100644 --- a/zero.Core/Api/CountriesApi.cs +++ b/zero.Core/Api/CountriesApi.cs @@ -11,38 +11,38 @@ using zero.Core.Extensions; namespace zero.Core.Api { - public class CountriesApi : AppAwareBackofficeApi, ICountriesApi where T : ICountry + public class CountriesApi : AppAwareBackofficeApi, ICountriesApi { - IValidator Validator; + IValidator Validator; - public CountriesApi(IBackofficeStore store, IValidator validator) : base(store) + public CountriesApi(IBackofficeStore store) : base(store) { Scope.IncludeShared = true; - Validator = validator; + Validator = null; } /// - public async Task GetById(string id) + public async Task GetById(string id) { - return await GetById(id); + return await GetById(id); } /// - public async Task> GetByIds(params string[] ids) + public async Task> GetByIds(params string[] ids) { - return await GetByIds(ids); + return await GetByIds(ids); } /// - public async Task> GetAll(string languageId) + public async Task> GetAll(string languageId) { using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) { - return await session.Query() + return await session.Query() .Scope(Scope) .Where(x => x.LanguageId == languageId) .OrderByDescending(x => x.IsPreferred) @@ -53,13 +53,13 @@ namespace zero.Core.Api /// - public async Task> GetByQuery(string languageId, ListQuery query) + public async Task> GetByQuery(string languageId, ListQuery query) { query.SearchSelector = country => country.Name; using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) { - return await session.Query() + return await session.Query() .Scope(Scope) .Where(x => x.LanguageId == languageId) .OrderByDescending(x => x.IsPreferred) @@ -70,50 +70,50 @@ namespace zero.Core.Api /// - public async Task> Save(T model) + public async Task> Save(ICountry model) { return await SaveModel(model, Validator); } /// - public async Task> Delete(string id) + public async Task> Delete(string id) { - return await DeleteById(id); + return await DeleteById(id); } } - public interface ICountriesApi where T : ICountry + public interface ICountriesApi { /// /// Get country by Id /// - Task GetById(string id); + Task GetById(string id); /// /// Get countries by ids /// - Task> GetByIds(params string[] ids); + Task> GetByIds(params string[] ids); /// /// Get all available countries /// - Task> GetAll(string languageId); + Task> GetAll(string languageId); /// /// Get all available countries (with query) /// - Task> GetByQuery(string languageId, ListQuery query); + Task> GetByQuery(string languageId, ListQuery query); /// /// Creates or updates a country /// - Task> Save(T model); + Task> Save(ICountry model); /// /// Deletes a country by Id /// - Task> Delete(string id); + Task> Delete(string id); } } diff --git a/zero.Core/Api/LanguagesApi.cs b/zero.Core/Api/LanguagesApi.cs index 6a050d7e..017cdc92 100644 --- a/zero.Core/Api/LanguagesApi.cs +++ b/zero.Core/Api/LanguagesApi.cs @@ -12,38 +12,38 @@ using zero.Core.Extensions; namespace zero.Core.Api { - public class LanguagesApi : AppAwareBackofficeApi, ILanguagesApi where T : ILanguage + public class LanguagesApi : AppAwareBackofficeApi, ILanguagesApi { - protected IValidator Validator { get; private set; } + protected IValidator Validator { get; private set; } - public LanguagesApi(IBackofficeStore store, IValidator validator = null) : base(store) + public LanguagesApi(IBackofficeStore store) : base(store) { Scope.IncludeShared = true; - Validator = validator; + Validator = null; } /// - public async Task GetById(string id) + public async Task GetById(string id) { - return await GetById(id); + return await GetById(id); } /// - public async Task> GetByIds(params string[] ids) + public async Task> GetByIds(params string[] ids) { - return await GetByIds(ids); + return await GetByIds(ids); } /// - public async Task> GetAll() + public async Task> GetAll() { using IAsyncDocumentSession session = Raven.OpenAsyncSession(); - return await session.Query() + return await session.Query() .Scope(Scope) .OrderByDescending(x => x.CreatedDate) .ToListAsync(); @@ -68,47 +68,47 @@ namespace zero.Core.Api /// - public async Task> GetByQuery(ListQuery query) + public async Task> GetByQuery(ListQuery query) { query.SearchFor(entity => entity.Name); using IAsyncDocumentSession session = Raven.OpenAsyncSession(); - return await session.Query().Scope(Scope).ToQueriedListAsync(query); + return await session.Query().Scope(Scope).ToQueriedListAsync(query); } /// - public async Task> Save(T model) + public async Task> Save(ILanguage model) { return await SaveModel(model, Validator); } /// - public async Task> Delete(string id) + public async Task> Delete(string id) { - return await DeleteById(id); + return await DeleteById(id); } } - public interface ILanguagesApi where T : ILanguage + public interface ILanguagesApi { /// /// Get language by Id /// - Task GetById(string id); + Task GetById(string id); /// /// Get countries by ids /// - Task> GetByIds(params string[] ids); + Task> GetByIds(params string[] ids); /// /// Get all available languages /// - Task> GetAll(); + Task> GetAll(); /// /// Get all available cultures @@ -118,16 +118,16 @@ namespace zero.Core.Api /// /// Get all available languages (with query) /// - Task> GetByQuery(ListQuery query); + Task> GetByQuery(ListQuery query); /// /// Creates or updates a language /// - Task> Save(T model); + Task> Save(ILanguage model); /// /// Deletes a language by Id /// - Task> Delete(string id); + Task> Delete(string id); } } diff --git a/zero.Core/Api/TranslationsApi.cs b/zero.Core/Api/TranslationsApi.cs index 1cf72a01..eec3f3ae 100644 --- a/zero.Core/Api/TranslationsApi.cs +++ b/zero.Core/Api/TranslationsApi.cs @@ -10,37 +10,9 @@ using zero.Core.Extensions; namespace zero.Core.Api { - public class TranslationsApiFacade : ITranslationsApiFacade + public class TranslationsApi : AppAwareBackofficeApi, ITranslationsApi { - IServiceProvider Services; - - public TranslationsApiFacade(IServiceProvider services) - { - Services = services; - } - - public ITranslationsApi As() where T : ITranslation - { - return Services.GetService(typeof(ITranslationsApi)) as ITranslationsApi; - } - } - - - public interface ITranslationsApiFacade - { - ITranslationsApi As() where T : ITranslation; - } - - - public class TranslationsApi : TranslationsApi, ITranslationsApi - { - public TranslationsApi(IBackofficeStore store) : base(store) { } - } - - - public class TranslationsApi : AppAwareBackofficeApi, ITranslationsApi where T : ITranslation - { - //IValidator Validator; + //IValidator Validator; public TranslationsApi(IBackofficeStore store) : base(store) @@ -52,23 +24,23 @@ namespace zero.Core.Api /// public async Task GetStringById(string id) { - return (await GetById(id))?.Value; + return (await GetById(id))?.Value; } /// - public async Task GetById(string id) + public async Task GetById(string id) { - return await GetById(id); + return await GetById(id); } /// - public async Task> GetAll() + public async Task> GetAll() { using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) { - return await session.Query() + return await session.Query() .OrderByDescending(x => x.CreatedDate) .Scope(Scope) .ToListAsync(); @@ -77,38 +49,38 @@ namespace zero.Core.Api /// - public async Task> GetByQuery(ListQuery query) + public async Task> GetByQuery(ListQuery query) { query.SearchFor(entity => entity.Key, entity => entity.Value); using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) { - return await session.Query().Scope(Scope).ToQueriedListAsync(query); + return await session.Query().Scope(Scope).ToQueriedListAsync(query); } } /// - public async Task> Save(T model) + public async Task> Save(ITranslation model) { return await SaveModel(model, null); } /// - public async Task> Delete(string id) + public async Task> Delete(string id) { - return await DeleteById(id); + return await DeleteById(id); } } - public interface ITranslationsApi where T : ITranslation + public interface ITranslationsApi { /// /// Get translation by id /// - Task GetById(string id); + Task GetById(string id); /// /// Get a translated string by id @@ -118,27 +90,21 @@ namespace zero.Core.Api /// /// Get all available translations /// - Task> GetAll(); + Task> GetAll(); /// /// Get all available translations (with query) /// - Task> GetByQuery(ListQuery query); + Task> GetByQuery(ListQuery query); /// /// Creates or updates a translation /// - Task> Save(T model); + Task> Save(ITranslation model); /// /// Deletes a translation by id /// - Task> Delete(string id); - } - - - public interface ITranslationsApi : ITranslationsApi - { - + Task> Delete(string id); } } diff --git a/zero.Core/Api/UserApi.cs b/zero.Core/Api/UserApi.cs index aeba05f6..a582c251 100644 --- a/zero.Core/Api/UserApi.cs +++ b/zero.Core/Api/UserApi.cs @@ -9,38 +9,38 @@ using zero.Core.Extensions; namespace zero.Core.Api { - public class UserApi : AppAwareBackofficeApi, IUserApi where T : class, IUser + public class UserApi : AppAwareBackofficeApi, IUserApi { - protected UserManager UserManager { get; private set; } + protected UserManager UserManager { get; private set; } - public UserApi(IBackofficeStore store, UserManager userManager) : base(store) + public UserApi(IBackofficeStore store, UserManager userManager) : base(store) { UserManager = userManager; } /// - public async Task GetUserById(string id) + public async Task GetUserById(string id) { - T user = await UserManager.FindByIdAsync(id); + IUser user = await UserManager.FindByIdAsync(id); return user; } /// - public async Task GetUserByEmail(string email) + public async Task GetUserByEmail(string email) { - T user = await UserManager.FindByEmailAsync(email); + IUser user = await UserManager.FindByEmailAsync(email); return user; } /// - public async Task> GetAll(string appId = null) + public async Task> GetAll(string appId = null) { using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) { - return await session.Query() + return await session.Query() .Scope(appId) .OrderByDescending(x => x.CreatedDate) .ToListAsync(); @@ -49,13 +49,13 @@ namespace zero.Core.Api /// - public async Task> GetByQuery(ListQuery query, string appId = null) + public async Task> GetByQuery(ListQuery query, string appId = null) { query.SearchSelector = user => user.Name; using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) { - return await session.Query() + return await session.Query() .Scope(appId) .ToQueriedListAsync(query); } @@ -63,37 +63,37 @@ namespace zero.Core.Api /// - public async Task> Save(T model) + public async Task> Save(IUser model) { return await SaveModel(model); //, new UserValidator()); } /// - public async Task> Delete(string id) + public async Task> Delete(string id) { - return await DeleteById(id); + return await DeleteById(id); } /// - public async Task> UpdatePassword(T user, string currentPassword, string newPassword) + public async Task> UpdatePassword(IUser user, string currentPassword, string newPassword) { if (currentPassword.IsNullOrWhiteSpace() || newPassword.IsNullOrWhiteSpace()) { - return EntityResult.Fail(nameof(currentPassword), "@errors.changepassword.emptyfields"); + return EntityResult.Fail(nameof(currentPassword), "@errors.changepassword.emptyfields"); } if (user == null) { - return EntityResult.Fail("@errors.changepassword.nouser"); + return EntityResult.Fail("@errors.changepassword.nouser"); } - IdentityResult identityResult = await UserManager.ChangePasswordAsync(user, currentPassword, newPassword); + IdentityResult identityResult = await UserManager.ChangePasswordAsync(user as User, currentPassword, newPassword); if (!identityResult.Succeeded) { - EntityResult result = EntityResult.Fail(); + EntityResult result = EntityResult.Fail(); foreach (IdentityError error in identityResult.Errors) { @@ -103,19 +103,19 @@ namespace zero.Core.Api return result; } - return EntityResult.Success(user); + return EntityResult.Success(user); } /// - public async Task> Enable(T user) + public async Task> Enable(IUser user) { return await UpdateActiveState(user, true); } /// - public async Task> Disable(T user) + public async Task> Disable(IUser user) { return await UpdateActiveState(user, false); } @@ -125,15 +125,15 @@ namespace zero.Core.Api /// Updates the active state of user. /// If IsActive=false, the user cannot login anymore /// - async Task> UpdateActiveState(T user, bool isActive) + async Task> UpdateActiveState(IUser user, bool isActive) { user.IsActive = isActive; - IdentityResult identityResult = await UserManager.UpdateAsync(user); + IdentityResult identityResult = await UserManager.UpdateAsync(user as User); if (!identityResult.Succeeded) { - EntityResult result = EntityResult.Fail(); + EntityResult result = EntityResult.Fail(); foreach (IdentityError error in identityResult.Errors) { @@ -143,59 +143,59 @@ namespace zero.Core.Api return result; } - await UserManager.UpdateSecurityStampAsync(user); + await UserManager.UpdateSecurityStampAsync(user as User); - return EntityResult.Success(user); + return EntityResult.Success(user); } } - public interface IUserApi : IAppAwareBackofficeApi where T : class, IUser + public interface IUserApi : IAppAwareBackofficeApi { /// /// Find user by id /// - Task GetUserById(string id); + Task GetUserById(string id); /// /// Find user by email /// - Task GetUserByEmail(string email); + Task GetUserByEmail(string email); /// /// Get all users for the selected application /// - Task> GetAll(string appId = null); + Task> GetAll(string appId = null); /// /// Get all available users (with query) /// - Task> GetByQuery(ListQuery query, string appId = null); + Task> GetByQuery(ListQuery query, string appId = null); /// /// Creates or updates a user /// - Task> Save(T model); + Task> Save(IUser model); /// /// Deletes a user /// - Task> Delete(string id); + Task> Delete(string id); /// /// Changes the password of the current user. /// User is logged out if this operation succeeds. /// - Task> UpdatePassword(T user, string currentPassword, string newPassword); + Task> UpdatePassword(IUser user, string currentPassword, string newPassword); /// /// Enables a user /// - Task> Enable(T user); + Task> Enable(IUser user); /// /// Disables a user /// - Task> Disable(T user); + Task> Disable(IUser user); } } diff --git a/zero.Core/Entities/Country.cs b/zero.Core/Entities/Country.cs index d06a21f9..49866f2b 100644 --- a/zero.Core/Entities/Country.cs +++ b/zero.Core/Entities/Country.cs @@ -1,4 +1,6 @@ -namespace zero.Core.Entities +using zero.Core.Attributes; + +namespace zero.Core.Entities { public class Country : ZeroEntity, ICountry { @@ -16,6 +18,7 @@ } + [Collection("Countries")] public interface ICountry : IZeroEntity, IAppAwareShareableEntity, ILanguageAwareEntity, IZeroDbConventions { /// diff --git a/zero.Core/Extensions/ServiceCollectionExtensions.cs b/zero.Core/Extensions/ServiceCollectionExtensions.cs index e5cd4fba..826b7fce 100644 --- a/zero.Core/Extensions/ServiceCollectionExtensions.cs +++ b/zero.Core/Extensions/ServiceCollectionExtensions.cs @@ -31,7 +31,12 @@ namespace zero.Core.Extensions { IEnumerable<(Type, TypeInfo)> matches = AssemblyDiscovery.Current.GetAllClassTypes().SelectMany(type => { - IEnumerable genericTypes = type.GetInterfaces().Select(x => x.GetTypeInfo()).Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == serviceType); + var interfaces = type.GetInterfaces().Select(x => x.GetTypeInfo()); + IEnumerable genericTypes = interfaces.Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == serviceType); + if (genericTypes.Any()) + { + var genericTypeDefinitions = genericTypes.First(); + } return genericTypes.Select(x => (x, type)); }); diff --git a/zero.Core/Validation/ApplicationValidator.cs b/zero.Core/Validation/ApplicationValidator.cs index ab8d7558..55ef4208 100644 --- a/zero.Core/Validation/ApplicationValidator.cs +++ b/zero.Core/Validation/ApplicationValidator.cs @@ -5,7 +5,7 @@ using zero.Core.Extensions; namespace zero.Core.Validation { - public class ApplicationValidator : AbstractValidator + public class ApplicationValidator : AbstractValidator { public ApplicationValidator() { diff --git a/zero.Web/ApiControllerFeatureProvider.cs b/zero.Web/ApiControllerFeatureProvider.cs deleted file mode 100644 index a1cbaa0f..00000000 --- a/zero.Web/ApiControllerFeatureProvider.cs +++ /dev/null @@ -1,85 +0,0 @@ -using Microsoft.AspNetCore.Mvc.ApplicationParts; -using Microsoft.AspNetCore.Mvc.Controllers; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using zero.Core; -using zero.Core.Assemblies; -using zero.Core.Entities; -using zero.Web.Controllers; -using zero.Web.Filters; - -namespace zero.Web -{ - public class ApiControllerFeatureProvider : IApplicationFeatureProvider - { - IServiceCollection ServiceCollection; - - public ApiControllerFeatureProvider(IServiceCollection serviceCollection) - { - ServiceCollection = serviceCollection; - } - - - public void PopulateFeature(IEnumerable parts, ControllerFeature feature) - { - var pagetype = typeof(IPage); - var page = ServiceCollection.FirstOrDefault(x => x.ServiceType.Equals(pagetype)); - IEnumerable candidates = AssemblyDiscovery.Current.GetTypes(parts, true).Where(x => x.ContainsGenericParameters); - - foreach (TypeInfo candidate in candidates) - { - Type genericType = candidate.GetGenericTypeDefinition(); - Type[] genericArguments = genericType.GetGenericArguments(); - - List concreteArguments = new List(); - - bool isValid = true; - - foreach (Type arg in genericArguments) - { - Type requiredService = arg.GetInterfaces().FirstOrDefault(); - - if (requiredService == null) - { - isValid = false; - break; - } - - TypeInfo concreteArgument = null; - - ServiceDescriptor descriptor = ServiceCollection.FirstOrDefault(x => x.ServiceType.Equals(requiredService)); - - if (descriptor != null) - { - concreteArgument = descriptor.ImplementationType?.GetTypeInfo(); - } - - if (concreteArgument == null) - { - IEnumerable concreteArgumentCandidates = AssemblyDiscovery.Current.GetTypes(requiredService, parts); - concreteArgument = concreteArgumentCandidates.FirstOrDefault(); - - if (concreteArgument == null) - { - isValid = false; - break; - } - } - - concreteArguments.Add(concreteArgument); - } - - if (!isValid) - { - continue; - } - - TypeInfo type = candidate.MakeGenericType(concreteArguments.ToArray()).GetTypeInfo(); - feature.Controllers.Add(type); - } - } - } -} diff --git a/zero.Web/Controllers/ApplicationsController.cs b/zero.Web/Controllers/ApplicationsController.cs index 97c5e3eb..e25bee81 100644 --- a/zero.Web/Controllers/ApplicationsController.cs +++ b/zero.Web/Controllers/ApplicationsController.cs @@ -2,25 +2,28 @@ using System.Threading.Tasks; using zero.Core.Api; using zero.Core.Entities; +using zero.Core.Extensions; using zero.Core.Identity; namespace zero.Web.Controllers { [ZeroAuthorize(Permissions.Settings.Applications, PermissionsValue.Read)] - public class ApplicationsController : BackofficeController where T : IApplication, new() + public class ApplicationsController : BackofficeController { - IApplicationsApi Api; + IApplicationsApi Api; + IApplication Blueprint; - public ApplicationsController(IApplicationsApi api) + public ApplicationsController(IApplicationsApi api, IApplication blueprint) { Api = api; + Blueprint = blueprint; } /// /// Get translation by id /// - public IActionResult GetEmpty() => Edit(new T()); + public IActionResult GetEmpty() => Edit(Blueprint.Clone()); /// @@ -32,7 +35,7 @@ namespace zero.Web.Controllers /// /// Get all translations /// - public async Task GetAll([FromQuery] ListQuery query = null) + public async Task GetAll([FromQuery] ListQuery query = null) { if (query == null) { @@ -53,7 +56,7 @@ namespace zero.Web.Controllers /// Save translation /// [ZeroAuthorize(Permissions.Settings.Applications, PermissionsValue.Update)] - public async Task Save([FromBody] T model) => Json(await Api.Save(model)); + public async Task Save([FromBody] IApplication model) => Json(await Api.Save(model)); /// diff --git a/zero.Web/Controllers/BackofficeController.cs b/zero.Web/Controllers/BackofficeController.cs index ebeda02f..7c0ed325 100644 --- a/zero.Web/Controllers/BackofficeController.cs +++ b/zero.Web/Controllers/BackofficeController.cs @@ -16,9 +16,8 @@ using zero.Web.Models; namespace zero.Web.Controllers { [ZeroAuthorize] - [BackofficeGenericController] [ServiceFilter(typeof(ModelStateValidationFilterAttribute))] - public abstract class BackofficeController : Controller, ISupportsGenericsController + public abstract class BackofficeController : Controller { IMapper _mapper; IZeroOptions _options; diff --git a/zero.Web/Controllers/CountriesController.cs b/zero.Web/Controllers/CountriesController.cs index d142c0be..a0241c3d 100644 --- a/zero.Web/Controllers/CountriesController.cs +++ b/zero.Web/Controllers/CountriesController.cs @@ -5,28 +5,31 @@ using System.Threading.Tasks; using zero.Core; using zero.Core.Api; using zero.Core.Entities; +using zero.Core.Extensions; using zero.Core.Identity; namespace zero.Web.Controllers { [ZeroAuthorize(Permissions.Settings.Countries, PermissionsValue.Read)] - public class CountriesController : BackofficeController where T : ICountry, new() + public class CountriesController : BackofficeController { - ICountriesApi Api; + ICountriesApi Api; + ICountry Blueprint; - public CountriesController(ICountriesApi api) + public CountriesController(ICountriesApi api, ICountry blueprint) { Api = api; + Blueprint = blueprint; } public async Task GetById([FromQuery] string id) => Edit(await Api.GetById(id)); - public IActionResult GetEmpty() => Edit(new T()); + public IActionResult GetEmpty() => Edit(Blueprint.Clone()); - public async Task GetAll([FromQuery] ListQuery query) => Json(await Api.GetByQuery("languages.1-A", query)); // TODO correct language + public async Task GetAll([FromQuery] ListQuery query) => Json(await Api.GetByQuery("languages.1-A", query)); // TODO correct language public async Task GetForPicker() => Json((await Api.GetAll("languages.1-A")).Select(x => new SelectModel() @@ -49,7 +52,7 @@ namespace zero.Web.Controllers [ZeroAuthorize(Permissions.Settings.Countries, PermissionsValue.Update)] - public async Task Save([FromBody] T model) => Json(await Api.Save(model)); + public async Task Save([FromBody] ICountry model) => Json(await Api.Save(model)); [ZeroAuthorize(Permissions.Settings.Countries, PermissionsValue.Update)] diff --git a/zero.Web/Controllers/ISupportsGenericsController.cs b/zero.Web/Controllers/ISupportsGenericsController.cs deleted file mode 100644 index c1397269..00000000 --- a/zero.Web/Controllers/ISupportsGenericsController.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace zero.Web.Controllers -{ - public interface ISupportsGenericsController - { - } -} diff --git a/zero.Web/Controllers/LanguagesController.cs b/zero.Web/Controllers/LanguagesController.cs index 7f831f08..87800db2 100644 --- a/zero.Web/Controllers/LanguagesController.cs +++ b/zero.Web/Controllers/LanguagesController.cs @@ -4,27 +4,28 @@ using System.Linq; using System.Threading.Tasks; using zero.Core.Api; using zero.Core.Entities; +using zero.Core.Extensions; using zero.Core.Identity; -using zero.Web.Filters; namespace zero.Web.Controllers { [ZeroAuthorize(Permissions.Settings.Languages, PermissionsValue.Read)] - public class LanguagesController : BackofficeController where T : ILanguage, new() + public class LanguagesController : BackofficeController { - ILanguagesApi Api; + ILanguagesApi Api; + ILanguage Blueprint; - - public LanguagesController(ILanguagesApi api) + public LanguagesController(ILanguagesApi api, ILanguage blueprint) { Api = api; + Blueprint = blueprint; } /// /// Get empty language model /// - public IActionResult GetEmpty() => Edit(new T()); + public IActionResult GetEmpty() => Edit(Blueprint.Clone()); /// @@ -36,7 +37,7 @@ namespace zero.Web.Controllers /// /// Get all languages /// - public async Task GetAll([FromQuery] ListQuery query) => Json(await Api.GetByQuery(query)); + public async Task GetAll([FromQuery] ListQuery query) => Json(await Api.GetByQuery(query)); /// @@ -74,7 +75,7 @@ namespace zero.Web.Controllers /// Save language /// [ZeroAuthorize(Permissions.Settings.Languages, PermissionsValue.Update)] - public async Task Save([FromBody] T model) => Json(await Api.Save(model)); + public async Task Save([FromBody] ILanguage model) => Json(await Api.Save(model)); /// diff --git a/zero.Web/Controllers/PagesController.cs b/zero.Web/Controllers/PagesController.cs index e21d7c71..dee5053f 100644 --- a/zero.Web/Controllers/PagesController.cs +++ b/zero.Web/Controllers/PagesController.cs @@ -40,6 +40,7 @@ namespace zero.Web.Controllers public IActionResult GetEmpty(string type, string parent = null) { + // TODO this will return an instance of Page, but the subclass with type=$type is needed IPage entity = Blueprint.Clone(); entity.PageTypeAlias = type; entity.ParentId = parent; diff --git a/zero.Web/Controllers/SettingsController.cs b/zero.Web/Controllers/SettingsController.cs index 59d4bbaa..6de72a5d 100644 --- a/zero.Web/Controllers/SettingsController.cs +++ b/zero.Web/Controllers/SettingsController.cs @@ -14,10 +14,10 @@ namespace zero.Web.Controllers { IAuthenticationApi AuthApi; - IApplicationsApi ApplicationsApi; + IApplicationsApi ApplicationsApi; - public SettingsController(IAuthenticationApi authApi, IApplicationsApi applicationsApi) + public SettingsController(IAuthenticationApi authApi, IApplicationsApi applicationsApi) { AuthApi = authApi; ApplicationsApi = applicationsApi; @@ -68,7 +68,7 @@ namespace zero.Web.Controllers } } - IList applications = new List(); + IList applications = new List(); if (Permission.CanReadKey(permissions, Permissions.Settings.Applications, false)) { diff --git a/zero.Web/Controllers/TranslationsController.cs b/zero.Web/Controllers/TranslationsController.cs index 1e73a2dc..be06922c 100644 --- a/zero.Web/Controllers/TranslationsController.cs +++ b/zero.Web/Controllers/TranslationsController.cs @@ -2,26 +2,28 @@ using System.Threading.Tasks; using zero.Core.Api; using zero.Core.Entities; +using zero.Core.Extensions; using zero.Core.Identity; -using zero.Web.Models; namespace zero.Web.Controllers { [ZeroAuthorize(Permissions.Settings.Translations, PermissionsValue.Read)] - public class TranslationsController : BackofficeController where T : ITranslation, new() + public class TranslationsController : BackofficeController { - ITranslationsApi Api; + ITranslationsApi Api; + ITranslation Blueprint; - public TranslationsController(ITranslationsApi api) + public TranslationsController(ITranslationsApi api, ITranslation blueprint) { Api = api; + Blueprint = blueprint; } /// /// Get translation by id /// - public IActionResult GetEmpty() => Edit(new T()); + public IActionResult GetEmpty() => Edit(Blueprint.Clone()); /// @@ -33,14 +35,14 @@ namespace zero.Web.Controllers /// /// Get all translations /// - public async Task GetAll([FromQuery] ListQuery query) => Json(await Api.GetByQuery(query)); + public async Task GetAll([FromQuery] ListQuery query) => Json(await Api.GetByQuery(query)); /// /// Save translation /// [ZeroAuthorize(Permissions.Settings.Translations, PermissionsValue.Update)] - public async Task Save([FromBody] T model) => Json(await Api.Save(model)); + public async Task Save([FromBody] ITranslation model) => Json(await Api.Save(model)); /// diff --git a/zero.Web/Controllers/UsersController.cs b/zero.Web/Controllers/UsersController.cs index d87c68f4..0b785344 100644 --- a/zero.Web/Controllers/UsersController.cs +++ b/zero.Web/Controllers/UsersController.cs @@ -8,18 +8,16 @@ using zero.Web.Models; namespace zero.Web.Controllers { [ZeroAuthorize(Permissions.Settings.Users, PermissionsValue.Read)] - public class UsersController : BackofficeController - where T : class, IUser - where TLanguage : ILanguage + public class UsersController : BackofficeController { - IUserApi Api; + IUserApi Api; IAuthenticationApi AuthenticationApi; IUserRolesApi RolesApi; - ILanguagesApi LanguagesApi; + ILanguagesApi LanguagesApi; IPermissionsApi PermissionsApi; - public UsersController(IUserApi api, IAuthenticationApi authenticationApi, IUserRolesApi rolesApi, ILanguagesApi languagesApi, IPermissionsApi permissionsApi) + public UsersController(IUserApi api, IAuthenticationApi authenticationApi, IUserRolesApi rolesApi, ILanguagesApi languagesApi, IPermissionsApi permissionsApi) { Api = api; AuthenticationApi = authenticationApi; @@ -35,7 +33,7 @@ namespace zero.Web.Controllers public IActionResult GetSupportedCultures() => Json(LanguagesApi.GetAllCultures(Options.SupportedLanguages)); - public async Task GetAll([FromQuery] ListQuery query) => Json(await Api.GetByQuery(query)); + public async Task GetAll([FromQuery] ListQuery query) => Json(await Api.GetByQuery(query)); public IActionResult GetAllPermissions() => Json(PermissionsApi.GetAll()); @@ -44,16 +42,16 @@ namespace zero.Web.Controllers [ZeroAuthorize] public async Task UpdatePassword([FromBody] UserPasswordEditModel model) { - EntityResult result; + EntityResult result; if (model.NewPassword != model.ConfirmNewPassword) { - result = EntityResult.Fail(nameof(model.NewPassword), "@errors.changepassword.newpasswordsnotmatching"); + result = EntityResult.Fail(nameof(model.NewPassword), "@errors.changepassword.newpasswordsnotmatching"); } else { User user = await AuthenticationApi.GetUser(); - result = await Api.UpdatePassword(user as T, model.CurrentPassword, model.NewPassword); + result = await Api.UpdatePassword(user as IUser, model.CurrentPassword, model.NewPassword); if (result.IsSuccess) { @@ -66,28 +64,28 @@ namespace zero.Web.Controllers [ZeroAuthorize(Permissions.Settings.Users, PermissionsValue.Update)] - public async Task Disable([FromBody] T model) + public async Task Disable([FromBody] IUser model) { - T entity = await Api.GetUserById(model.Id); + IUser entity = await Api.GetUserById(model.Id); return Json(await Api.Disable(entity)); } [ZeroAuthorize(Permissions.Settings.Users, PermissionsValue.Update)] - public async Task Enable([FromBody] T model) + public async Task Enable([FromBody] IUser model) { - T entity = await Api.GetUserById(model.Id); + IUser entity = await Api.GetUserById(model.Id); return Json(await Api.Enable(entity)); } [ZeroAuthorize(Permissions.Settings.Users, PermissionsValue.Update)] - public async Task Save([FromBody] T model) => Json(await Api.Save(model)); + public async Task Save([FromBody] IUser model) => Json(await Api.Save(model)); [ZeroAuthorize(Permissions.Settings.Users, PermissionsValue.Update)] // TODO do not need settings.users authorization for editing current user profiles - public async Task SaveCurrent([FromBody] T model) => Json(await Api.Save(model)); + public async Task SaveCurrent([FromBody] IUser model) => Json(await Api.Save(model)); [ZeroAuthorize(Permissions.Settings.Users, PermissionsValue.Update)] diff --git a/zero.Web/Defaults/ZeroBackofficePlugin.cs b/zero.Web/Defaults/ZeroBackofficePlugin.cs index 9b63b8a7..8992ec9f 100644 --- a/zero.Web/Defaults/ZeroBackofficePlugin.cs +++ b/zero.Web/Defaults/ZeroBackofficePlugin.cs @@ -7,6 +7,7 @@ using zero.Core.Entities; using zero.Core.Extensions; using zero.Core.Options; using zero.Core.Plugins; +using zero.Core.Validation; using zero.Web.Mapper; using zero.Web.Sections; @@ -20,24 +21,19 @@ namespace zero.Web.Defaults services.AddAll(typeof(IValidator), ServiceLifetime.Scoped); services.AddTransient(); + //services.AddTransient, ApplicationValidator>(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient(typeof(IApplicationsApi<>), typeof(ApplicationsApi<>)); - services.AddTransient(typeof(ICountriesApi<>), typeof(CountriesApi<>)); - services.AddTransient(typeof(ILanguagesApi<>), typeof(LanguagesApi<>)); - services.AddTransient(typeof(ITranslationsApi), typeof(TranslationsApi)); - services.AddTransient(typeof(ITranslationsApi<>), typeof(TranslationsApi<>)); - services.AddTransient(typeof(ITranslationsApiFacade), typeof(TranslationsApiFacade)); - //services.AddTransient(typeof(IPagesApi<>), typeof(PagesApi<>)); - //services.AddTransient(typeof(IPageTreeApi<>), typeof(PageTreeApi<>)); - services.AddTransient(typeof(IUserApi<>), typeof(UserApi<>)); - services.AddTransient(typeof(IRecycleBinApi), typeof(RecycleBinApi)); - // services.AddTransient(typeof(IRecycleBinApi), typeof(RecycleBinApi)); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -54,6 +50,7 @@ namespace zero.Web.Defaults services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); } public void Configure(IZeroPluginOptions plugin, IZeroOptions zero) diff --git a/zero.Web/Filters/BackofficeGenericControllerAttribute.cs b/zero.Web/Filters/BackofficeGenericControllerAttribute.cs deleted file mode 100644 index 9697ca2d..00000000 --- a/zero.Web/Filters/BackofficeGenericControllerAttribute.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.AspNetCore.Mvc.ApplicationModels; -using System; -using zero.Core.Extensions; - -namespace zero.Web.Filters -{ - public class BackofficeGenericControllerAttribute : Attribute, IControllerModelConvention - { - const char BACKTICK = '`'; - - const string CONTROLLER = "Controller"; - - - public void Apply(ControllerModel controller) - { - if (controller.ControllerName.Contains(BACKTICK)) - { - controller.ControllerName = controller.ControllerName.Split(BACKTICK)[0].TrimEnd(CONTROLLER); - } - } - } -} diff --git a/zero.Web/ZeroBuilder.cs b/zero.Web/ZeroBuilder.cs index aab3c978..8121d574 100644 --- a/zero.Web/ZeroBuilder.cs +++ b/zero.Web/ZeroBuilder.cs @@ -93,7 +93,6 @@ namespace zero.Web { Mvc.AddRazorRuntimeCompilation(); } - Mvc.PartManager.FeatureProviders.Add(new ApiControllerFeatureProvider(Services)); // configure Raven + Identity diff --git a/zero.Web/ZeroVue.cs b/zero.Web/ZeroVue.cs index c1cef1d4..521dd25e 100644 --- a/zero.Web/ZeroVue.cs +++ b/zero.Web/ZeroVue.cs @@ -27,7 +27,7 @@ namespace zero.Web protected IWebHostEnvironment Environment { get; private set; } - protected IApplicationsApi ApplicationsApi { get; private set; } + protected IApplicationsApi ApplicationsApi { get; private set; } protected IAuthenticationApi AuthenticationApi { get; private set; } @@ -38,7 +38,7 @@ namespace zero.Web protected IApplicationContext AppContext { get; private set; } - public ZeroVue(IZeroOptions options, IWebHostEnvironment env, IApplicationsApi applicationsApi, IAuthenticationApi authenticationApi, IMapper mapper, IEnumerable plugins, IApplicationContext appContext) + public ZeroVue(IZeroOptions options, IWebHostEnvironment env, IApplicationsApi applicationsApi, IAuthenticationApi authenticationApi, IMapper mapper, IEnumerable plugins, IApplicationContext appContext) { Environment = env; Options = options; @@ -219,7 +219,7 @@ namespace zero.Web /// async Task> CreateApplications() { - IList applications = await ApplicationsApi.GetAll(); + IList applications = await ApplicationsApi.GetAll(); return applications.OrderBy(app => app.Sort).Select(app => new ZeroVueApplication() {