diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json index 32d3c16a01..c190a91470 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json @@ -197,6 +197,7 @@ "RemoveCache": "Remove Cache", "Language": "Language", "Optional": "Optional", - "CreateArticleLanguageInfo": "The language in which the article is written" + "CreateArticleLanguageInfo": "The language in which the post is written", + "Enum:ContentSource:2": "Video Post" } -} \ No newline at end of file +} diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json index 79493b537e..f061408c98 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/zh-Hans.json @@ -27,6 +27,8 @@ "Blog": "博客", "Commercial": "商业版", "MyAccount": "我的账户", + "Permission:License": "许可", + "Permission:UserInfo": "用户信息", "SeeDocuments": "查看文档", "Samples": "示例" } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json index 0147e71a05..82c23450a0 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json @@ -28,8 +28,12 @@ "MyOrganizations": "我的组织", "ApiKey": "API key", "UserNameNotFound": "没有用户名为{0}的用户", - "SuccessfullyAddedToNewsletter": "感谢你订阅我们的新闻通讯!", + "SuccessfullyAddedToNewsletter": "感谢你订阅我们的新闻简讯!", "MyProfile": "我的资料", - "EmailNotValid": "请输入有效的电子邮件地址" + "EmailNotValid": "请输入有效的电子邮件地址", + "JoinOurMarketingNewsletter": "加入我们的营销简讯", + "WouldLikeToReceiveMarketingMaterials": "我想收到市场营销资料,例如产品交易和特别优惠.", + "StartUsingYourLicenseNow": "立即开始使用你的许可证", + "WelcomePage": "欢迎页面" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json index a92c20a991..5bf922f012 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json @@ -25,18 +25,17 @@ "MostRead": "Most Read", "Latest": "Latest", "ContributeAbpCommunity": "Contribute to the ABP Community", - "SubmitYourArticle": "Submit Your Article", + "SubmitYourArticle": "Submit Your Post", "ContributionGuide": "Contribution Guide", "BugReport": "Bug Report", - "SeeAllArticles": "See All Articles", + "SeeAllArticles": "See All Posts", "WelcomeToABPCommunity!": "Welcome to the ABP Community!", "MyProfile": "My profile", "MyOrganizations": "My organizations", "EmailNotValid": "Please enter a valid email address.", "FeatureRequest": "Feature Request", - "CreateArticleTitleInfo": "Title of the article to be shown on the article list.", - "CreateArticleUrlInfo": "Original GitHub/External URL of the article.", - "CreateArticleSummaryInfo": "A short summary of the article to be shown on the article list.", + "CreateArticleTitleInfo": "Title of the post to be shown on the post list.", + "CreateArticleSummaryInfo": "A short summary of the post to be shown on the post list.", "CreateArticleCoverInfo": "For creating an effective article, add a cover photo. Upload 16:9 aspect ratio pictures for the best view. Maximum file size: 1MB.", "ThisExtensionIsNotAllowed": "This extension is not allowed.", "TheFileIsTooLarge": "The file is too large.", @@ -87,7 +86,7 @@ "PlannedReleaseDate": "Planned release date", "CommunityArticleRequestErrorMessage": "Could not get the latest article request from Github.", "ArticleRequestFromGithubIssue": "There are not any article requests now.", - "LatestArticles": "Latest Articles", + "LatestArticles": "Latest Posts", "ArticleRequests": "Article Requests", "AllArticleRequests": "See All Article Requests", "SubscribeToTheNewsletter": "Subscribe to the Newsletter", @@ -101,6 +100,38 @@ "ArticleRequestMessageTitle": "Open an issue on the GitHub to request an article/tutorial you want to see on this web site.", "ArticleRequestMessageBody": "Here, the list of the requested articles by the community. Do you want to write a requested article? Please click to the request and join to the discussion.", "Language": "Language", - "CreateArticleLanguageInfo": "The language in which the article is written" + "CreateArticleLanguageInfo": "The language for the post content.", + "VideoPost": "Video Post", + "Article": "Article", + "Read": "Read", + "CreateGithubArticleUrlInfo": "Original GitHub URL of the article.", + "CreateVideoContentUrlInfo": "Original Youtube URL of the post.", + "CreateExternalArticleUrlInfo": "Original External Url of the article.", + "VideoContentForm": "Submit Video on YouTube", + "GithubPostForm": "Submit Article on GitHub", + "ExternalPostForm": "Submit an External Content", + "HowToPost": "How to Post?", + "Posts": "Posts", + "VideoUrl": "Video Url", + "GithubArticleUrl": "Github Article Url", + "ExternalArticleUrl": "External Article Url", + "CreatePostCoverInfo": "For creating an effective post, add a cover photo. Upload 16:9 aspect ratio pictures for the best view. Maximum file size: 1MB.", + "ThankYouForContribution": "Thank you for contributing to the ABP Community.", + "GithubArticle": "Github Article", + "GithubArticleSubmitStepOne": "1. Write an article on any public GitHub repository with the Markdown format. example", + "GithubArticleSubmitStepTwo": "2. Submit your article URL using the form.", + "GithubArticleSubmitStepThree": "3. Your article will be rendered in this web site.", + "YoutubeVideo": "Youtube Video", + "YoutubeVideoSubmitStepOne": "1. Publish your video on YouTube.", + "YoutubeVideoSubmitStepTwo": "2. Submit the video URL using the form.", + "YoutubeVideoSubmitStepThree": "3. Visitors will be able to watch your video content directly on this website.", + "ExternalContent": "External Content", + "ExternalContentSubmitStepOne": "1. Create a content on any public platform (medium, your own blog or anywhere you like).", + "ExternalContentSubmitStepTwo": "2. Submit your content URL using the form.", + "ExternalContentSubmitStepThree": "3. Visitors are redirected to the content on the original website.", + "ChooseYourContentType": "Please choose the way you want to add your content.", + "PostContentViaGithub": "I want to add my article with GitHub in accordance with the markdown rules.", + "PostContentViaYoutube": "I want to share my videos available on Youtube here.", + "PostContentViaExternalSource": "I want to add the content I published on another platform here." } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json index fa793c91a0..49b819227f 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json @@ -35,7 +35,6 @@ "EmailNotValid": "请输入有效的电子邮箱地址.", "FeatureRequest": "功能请求", "CreateArticleTitleInfo": "文章标题显示在文章列表中.", - "CreateArticleUrlInfo": "文章的原始GitHub/外部URL.", "CreateArticleSummaryInfo": "文章的简短摘要将显示在文章列表中.", "CreateArticleCoverInfo": "为了创建有效的文章,请添加封面图. 仅支持16:9的图片!", "ThisExtensionIsNotAllowed": "不允许此扩展名.", @@ -84,6 +83,34 @@ "Edit": "修改", "ProfileImageChange": "更改资料图片", "BlogItemErrorMessage": "无法从ABP获取最新的博客文章详细信息.", - "PlannedReleaseDate": "计划发布日期" + "PlannedReleaseDate": "计划发布日期", + "CommunityArticleRequestErrorMessage": "无法从Github获取最新的文章请求.", + "ArticleRequestFromGithubIssue": "现在没有任何文章请求.", + "LatestArticles": "最新的帖子", + "ArticleRequests": "文章请求", + "AllArticleRequests": "查看所有文章请求", + "SubscribeToTheNewsletter": "订阅简讯", + "NewsletterEmailDefinition": "获取有关ABP发生的信息,例如新版本,免费资源,文章等.", + "NoThanks": "不用了,谢谢", + "MaybeLater": "以后再说", + "JoinOurArticleNewsletter": "加入我们的文章简讯", + "Community": "社区", + "Marketing": "营销", + "CommunityPrivacyPolicyConfirmation": "我同意条款和条件以及隐私政策.", + "ArticleRequestMessageTitle": "在GitHub上创建一个Issue,以请求你要在此网站上查看的文章/教程.", + "ArticleRequestMessageBody": "在这里,是社区请求的文章列表. 您要写一篇要求的文章吗? 请单击该请求并加入讨论.", + "Language": "语言", + "CreateArticleLanguageInfo": "本文所用的语言", + "VideoPost": "视频", + "Article": "文章", + "Read": "阅读", + "CreateGithubArticleUrlInfo": "文章的原始GitHub链接.", + "CreateVideoContentUrlInfo": "文章的原始Youtube链接.", + "CreateExternalArticleUrlInfo": "本文的原始外部网址", + "VideoContentForm": "视频内容来源", + "GithubPostForm": "Github文章来源", + "ExternalPostForm": "外部文章来源", + "PostSourceTypeChooses": "我们接受文章的三种来源类型;", + "Posts": "文章" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json index caf52554d1..d01d847716 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json @@ -192,6 +192,7 @@ "MultipleUIOptions": "多个UI选项", "MultipleDBOptions": "多个数据库提供程序", "MultipleUIOptionsExplanation": "核心框架设计为独立与UI,可以和任何类型的UI系统一起使用. 同时提供了多个开箱即用的预构建集成选项.", - "SelectLanguage": "選擇語言" + "MultipleDBOptionsExplanation": "该框架可以使用任何数据源,并且以下提供程序已得到正式开发和支持;", + "SelectLanguage": "选择语言" } -} \ No newline at end of file +} diff --git a/docs/en/Background-Workers.md b/docs/en/Background-Workers.md index 8225aac2a6..b12f1881fb 100644 --- a/docs/en/Background-Workers.md +++ b/docs/en/Background-Workers.md @@ -45,7 +45,7 @@ Assume that we want to make a user passive, if the user has not logged in to the public class PassiveUserCheckerWorker : AsyncPeriodicBackgroundWorkerBase { public PassiveUserCheckerWorker( - AbpTimer timer, + AbpAsyncTimer timer, IServiceScopeFactory serviceScopeFactory ) : base( timer, diff --git a/docs/en/Blob-Storing.md b/docs/en/Blob-Storing.md index a2d7a89e7a..82c2a861ab 100644 --- a/docs/en/Blob-Storing.md +++ b/docs/en/Blob-Storing.md @@ -14,7 +14,7 @@ ABP BLOB Storage system is also compatible to other ABP Framework features like ## BLOB Storage Providers -The ABP Framework has already the following storage provider implementations; +The ABP Framework has already the following storage provider implementations: * [File System](Blob-Storing-File-System.md): Stores BLOBs in a folder of the local file system, as standard files. * [Database](Blob-Storing-Database.md): Stores BLOBs in a database. diff --git a/docs/en/Community-Articles/2020-08-12-Patch-Chrome-Login-Issue-For-IdentityServer4/POST.md b/docs/en/Community-Articles/2020-08-12-Patch-Chrome-Login-Issue-For-IdentityServer4/POST.md index 718a949f3a..d0d2b1ccee 100644 --- a/docs/en/Community-Articles/2020-08-12-Patch-Chrome-Login-Issue-For-IdentityServer4/POST.md +++ b/docs/en/Community-Articles/2020-08-12-Patch-Chrome-Login-Issue-For-IdentityServer4/POST.md @@ -11,157 +11,75 @@ When you use HTTP on your Identity Server 4 enabled website, users may not login Create the below extension in your ***.Web** project. ```csharp -using System; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; namespace Microsoft.Extensions.DependencyInjection { public static class SameSiteCookiesServiceCollectionExtensions { - /// - /// -1 defines the unspecified value, which tells ASPNET Core to NOT - /// send the SameSite attribute. With ASPNET Core 3.1 the - /// enum will have a definition for - /// Unspecified. - /// - private const SameSiteMode Unspecified = (SameSiteMode)(-1); - - /// - /// Configures a cookie policy to properly set the SameSite attribute - /// for Browsers that handle unknown values as Strict. Ensure that you - /// add the - /// into the pipeline before sending any cookies! - /// - /// - /// Minimum ASPNET Core Version required for this code: - /// - 2.1.14 - /// - 2.2.8 - /// - 3.0.1 - /// - 3.1.0-preview1 - /// Starting with version 80 of Chrome (to be released in February 2020) - /// cookies with NO SameSite attribute are treated as SameSite=Lax. - /// In order to always get the cookies send they need to be set to - /// SameSite=None. But since the current standard only defines Lax and - /// Strict as valid values there are some browsers that treat invalid - /// values as SameSite=Strict. We therefore need to check the browser - /// and either send SameSite=None or prevent the sending of SameSite=None. - /// Relevant links: - /// - https://tools.ietf.org/html/draft-west-first-party-cookies-07#section-4.1 - /// - https://tools.ietf.org/html/draft-west-cookie-incrementalism-00 - /// - https://www.chromium.org/updates/same-site - /// - https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/ - /// - https://bugs.webkit.org/show_bug.cgi?id=198181 - /// - /// The service collection to register into. - /// The modified . - public static IServiceCollection ConfigureNonBreakingSameSiteCookies(this IServiceCollection services) + public static IServiceCollection AddSameSiteCookiePolicy(this IServiceCollection services) { services.Configure(options => { - options.MinimumSameSitePolicy = Unspecified; - options.OnAppendCookie = cookieContext => - CheckSameSite(cookieContext.Context, cookieContext.CookieOptions); - options.OnDeleteCookie = cookieContext => - CheckSameSite(cookieContext.Context, cookieContext.CookieOptions); + options.MinimumSameSitePolicy = SameSiteMode.Unspecified; + options.OnAppendCookie = cookieContext => + CheckSameSite(cookieContext.Context, cookieContext.CookieOptions); + options.OnDeleteCookie = cookieContext => + CheckSameSite(cookieContext.Context, cookieContext.CookieOptions); }); return services; } - + private static void CheckSameSite(HttpContext httpContext, CookieOptions options) { if (options.SameSite == SameSiteMode.None) { var userAgent = httpContext.Request.Headers["User-Agent"].ToString(); - - if (DisallowsSameSiteNone(userAgent)) + if (!httpContext.Request.IsHttps || DisallowsSameSiteNone(userAgent)) { - options.SameSite = Unspecified; + // For .NET Core < 3.1 set SameSite = (SameSiteMode)(-1) + options.SameSite = SameSiteMode.Unspecified; } } } - /// - /// Checks if the UserAgent is known to interpret an unknown value as Strict. - /// For those the property should be - /// set to . - /// - /// - /// This code is taken from Microsoft: - /// https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/ - /// - /// The user agent string to check. - /// Whether the specified user agent (browser) accepts SameSite=None or not. private static bool DisallowsSameSiteNone(string userAgent) { // Cover all iOS based browsers here. This includes: - // - Safari on iOS 12 for iPhone, iPod Touch, iPad - // - WkWebview on iOS 12 for iPhone, iPod Touch, iPad - // - Chrome on iOS 12 for iPhone, iPod Touch, iPad - // All of which are broken by SameSite=None, because they use the - // iOS networking stack. - // Notes from Thinktecture: - // Regarding https://caniuse.com/#search=samesite iOS versions lower - // than 12 are not supporting SameSite at all. Starting with version 13 - // unknown values are NOT treated as strict anymore. Therefore we only - // need to check version 12. - if (userAgent.Contains("CPU iPhone OS 12") - || userAgent.Contains("iPad; CPU OS 12")) + // - Safari on iOS 12 for iPhone, iPod Touch, iPad + // - WkWebview on iOS 12 for iPhone, iPod Touch, iPad + // - Chrome on iOS 12 for iPhone, iPod Touch, iPad + // All of which are broken by SameSite=None, because they use the iOS networking stack + if (userAgent.Contains("CPU iPhone OS 12") || userAgent.Contains("iPad; CPU OS 12")) { return true; } - // Cover Mac OS X based browsers that use the Mac OS networking stack. - // This includes: - // - Safari on Mac OS X. + // Cover Mac OS X based browsers that use the Mac OS networking stack. This includes: + // - Safari on Mac OS X. // This does not include: - // - Chrome on Mac OS X - // because they do not use the Mac OS networking stack. - // Notes from Thinktecture: - // Regarding https://caniuse.com/#search=samesite MacOS X versions lower - // than 10.14 are not supporting SameSite at all. Starting with version - // 10.15 unknown values are NOT treated as strict anymore. Therefore we - // only need to check version 10.14. - if (userAgent.Contains("Safari") - && userAgent.Contains("Macintosh; Intel Mac OS X 10_14") - && userAgent.Contains("Version/")) + // - Chrome on Mac OS X + // Because they do not use the Mac OS networking stack. + if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") && + userAgent.Contains("Version/") && userAgent.Contains("Safari")) { return true; } - // Cover Chrome 50-69, because some versions are broken by SameSite=None + // Cover Chrome 50-69, because some versions are broken by SameSite=None, // and none in this range require it. - // Note: this covers some pre-Chromium Edge versions, + // Note: this covers some pre-Chromium Edge versions, // but pre-Chromium Edge does not require SameSite=None. - // Notes from Thinktecture: - // We can not validate this assumption, but we trust Microsofts - // evaluation. And overall not sending a SameSite value equals to the same - // behavior as SameSite=None for these old versions anyways. if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6")) { return true; } - - if (GetChromeVersion(userAgent) >= 80) - { - return true; - } return false; } - - private static int GetChromeVersion(string userAgent) - { - try - { - return Convert.ToInt32(userAgent.Split("Chrome/")[1].Split('.')[0]); - } - catch (Exception) - { - return 0; - } - } } } ``` @@ -173,7 +91,7 @@ Assume that your project name is *Acme.BookStore*. Then open `AcmeBookStoreWebMo Add the following line to `ConfigureServices()` method. ```csharp - context.Services.ConfigureNonBreakingSameSiteCookies(); + context.Services.AddSameSiteCookiePolicy(); // cookie policy to deal with temporary browser incompatibilities ``` ### Step-3 @@ -195,18 +113,14 @@ public override void OnApplicationInitialization(ApplicationInitializationContex app.UseHsts(); } - app.UseCookiePolicy(); //<--- added this ---> + app.UseCookiePolicy(); // added this, Before UseAuthentication or anything else that writes cookies. //.... } ``` - - It's all! You are ready to go! - - --- -Referenced from https://www.thinktecture.com/en/identity/samesite/prepare-your-identityserver/ +Referenced from https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/ diff --git a/docs/en/Community-Articles/2020-12-11-Using-Angular-Material-Components-With-ABP-Framework/POST.md b/docs/en/Community-Articles/2020-12-11-Using-Angular-Material-Components-With-ABP-Framework/POST.md index 7b1ae846af..02cef11a2e 100644 --- a/docs/en/Community-Articles/2020-12-11-Using-Angular-Material-Components-With-ABP-Framework/POST.md +++ b/docs/en/Community-Articles/2020-12-11-Using-Angular-Material-Components-With-ABP-Framework/POST.md @@ -260,7 +260,7 @@ import { MatFormFieldModule } from "@angular/material/form-field"; import { MatInputModule } from "@angular/material/input"; import { MatSelectModule } from "@angular/material/select"; import { MatIconModule } from "@angular/material/icon"; -import { MatNativeDateModule } from '@angular/material/core'; +import { MatNativeDateModule } from "@angular/material/core"; @NgModule({ imports: [ @@ -1576,6 +1576,10 @@ Final UI looks as shown below: ![Author With Books](./author-with-books.gif) +## The Source Code + +You can download the source code from [here](https://github.com/abpframework/abp-samples/tree/master/AcmeBookStoreAngularMaterial). + ## Conclusion We implemented Angular Material Components to our angular application which was created with ABP Framework. There is no blocker case of using angular libraries with the ABP framework. diff --git a/docs/en/Modules/Index.md b/docs/en/Modules/Index.md index 9d0199f4c3..8851f8b554 100644 --- a/docs/en/Modules/Index.md +++ b/docs/en/Modules/Index.md @@ -2,7 +2,7 @@ ABP is a **modular application framework** which consists of dozens of **NuGet & NPM packages**. It also provides a complete infrastructure to build your own application modules which may have entities, services, database integration, APIs, UI components and so on. -There are **two types of modules.** They don't have any structural difference but categorized by functionality and purpose: +There are **two types of modules.** They don't have any structural difference but are categorized by functionality and purpose: * [**Framework modules**](https://github.com/abpframework/abp/tree/master/framework/src): These are **core modules of the framework** like caching, emailing, theming, security, serialization, validation, EF Core integration, MongoDB integration... etc. They do not have application/business functionalities but makes your daily development easier by providing common infrastructure, integration and abstractions. * [**Application modules**](https://github.com/abpframework/abp/tree/master/modules): These modules implement specific application/business functionalities like blogging, document management, identity management, tenant management... etc. They generally have their own entities, services, APIs and UI components. diff --git a/docs/en/Modules/Setting-Management.md b/docs/en/Modules/Setting-Management.md index 134e24aed2..dff8da3f8e 100644 --- a/docs/en/Modules/Setting-Management.md +++ b/docs/en/Modules/Setting-Management.md @@ -75,7 +75,7 @@ Setting values are cached using the [distributed cache](../Caching.md) system. A ## Setting Management Providers -Setting Management module is extensible, just like the [setting system](../Settings.md). You can extend it by defining setting management providers. There are 5 pre-built setting management providers registered by the order below: +Setting Management module is extensible, just like the [setting system](../Settings.md). You can extend it by defining setting management providers. There are 5 pre-built setting management providers registered it the following order: * `DefaultValueSettingManagementProvider`: Gets the value from the default value of the setting definition. It can not set the default value since default values are hard-coded on the setting definition. * `ConfigurationSettingManagementProvider`: Gets the value from the [IConfiguration service](../Configuration.md). It can not set the configuration value because it is not possible to change the configuration values on runtime. diff --git a/docs/en/Text-Templating.md b/docs/en/Text-Templating.md index b080087ba8..bdea7cd00b 100644 --- a/docs/en/Text-Templating.md +++ b/docs/en/Text-Templating.md @@ -423,7 +423,7 @@ This example simply adds a header and footer to the template and renders the con **3)** Configure the embedded resources in the `.csproj` file * Add [Microsoft.Extensions.FileProviders.Embedded](https://www.nuget.org/packages/Microsoft.Extensions.FileProviders.Embedded) NuGet package to the project. -* Add `true` into the `...` section of your `.csproj` file. +* Add `true` into the `...` section of your `.csproj` file. * Add the following code into your `.csproj` file: ````xml diff --git a/docs/en/UI/Angular/Authorization.md b/docs/en/UI/Angular/Authorization.md new file mode 100644 index 0000000000..75d6107341 --- /dev/null +++ b/docs/en/UI/Angular/Authorization.md @@ -0,0 +1,28 @@ +# Authorization in Angular UI + +OAuth is preconfigured in Angular application templates. So, when you start a project using the CLI (or Suite, for that matter), authorization already works. You can find **OAuth configuration** in the _environment.ts_ files. + +```js +import { Config } from '@abp/ng.core'; + +const baseUrl = 'http://localhost:4200'; + +export const environment = { + // other options removed for sake of brevity + + oAuthConfig: { + issuer: 'https://localhost:44305', + redirectUri: baseUrl, + clientId: 'MyProjectName_App', + responseType: 'code', + scope: 'offline_access MyProjectName', + }, + + // other options removed for sake of brevity +} as Config.Environment; + +``` + +This configuration results in an [OAuth authorization code flow with PKCE](https://tools.ietf.org/html/rfc7636) and we are using [angular-oauth2-oidc library](https://github.com/manfredsteyer/angular-oauth2-oidc#logging-in) for managing OAuth in the Angular client. + +According to this flow, the user is redirected to an external login page which is built with MVC. So, if you need **to customize the login page**, please follow [this community article](https://community.abp.io/articles/how-to-customize-the-login-page-for-mvc-razor-page-applications-9a40f3cd). diff --git a/docs/en/UI/Angular/Multi-Tenancy.md b/docs/en/UI/Angular/Multi-Tenancy.md index e7e284bb0d..7622db6de0 100644 --- a/docs/en/UI/Angular/Multi-Tenancy.md +++ b/docs/en/UI/Angular/Multi-Tenancy.md @@ -1,4 +1,4 @@ -# Multi Tenancy in Angular UI +# Multi-Tenancy in Angular UI ABP Angular UI supports the multi-tenancy. The following features related to multi-tenancy are available in the startup templates. @@ -8,7 +8,7 @@ ABP Angular UI supports the multi-tenancy. The following features related to mul On the page above, you can; -- See the all tenants. +- See all tenants. - Create a new tenant. - Edit an existing tenant. - Delete a tenant. @@ -17,9 +17,11 @@ On the page above, you can;

Tenant Switching Component

-You can switch between existing tenants by using the tenant switching component in the child pages of the `AccountLayoutComponent` (like Login page). Angular UI sends the selected tenant id to the backend as `__tenant` header on each request. +You can switch between existing tenants by using the tenant switching box in the child pages of the MVC Account Public Module (like Login page). Angular UI gets selected tenant from `application-configuration` response and sends the tenant id to the backend as `__tenant` header on each request. -## Domain Tenant Resolver +## Domain/Subdomain Tenant Resolver + +> **Note:** If you are going to implement the steps below, you should also implement the domain/subdomain tenant resolver feature for the backend. See the [Domain/Subdomain Tenant Resolver section in Multi-Tenancy document](../../Multi-Tenancy#domain-subdomain-tenant-resolver) to learn the backend implementation. Angular UI can get the tenant name from the app running URL. You can determine the current tenant by subdomain (like mytenant1.mydomain.com) or by the whole domain (like mytenant.com). To do this, you need to set the `application.baseUrl` property in the environment: diff --git a/docs/en/UI/Angular/Page-Alerts.md b/docs/en/UI/Angular/Page-Alerts.md new file mode 100644 index 0000000000..e59d620432 --- /dev/null +++ b/docs/en/UI/Angular/Page-Alerts.md @@ -0,0 +1,64 @@ +# Page Alerts + +A page alert is useful for displaying an important message to the user. The ABP Framework provides an easy way to show the following alert to the user. + +![angular-page-alert-example](./images/page-alert-warning-example.png) + +You can simply import `PageAlertService` from `@abp/ng.theme.shared` and utilize it as follows: + +```typescript +import { PageAlertService } from '@abp/ng.theme.shared'; + +@Component({ + // ... +}) +export class MyComponent { + constructor(private service: PageAlertService) {} + + showWarning() { + this.service.show({ + type: 'warning', + message: + 'We will have a service interruption between 02:00 AM and 04:00 AM at October 23, 2023!', + title: 'Service Interruption', + }); + } +} +``` + +## `SHOW` + +The method `show` accepts a single object that is type of `PageAlert` + +```typescript +export interface PageAlert { + type: 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'light' | 'dark'; + message: string; + title?: string; + dismissible?: boolean; + messageLocalizationParams?: string[]; + titleLocalizationParams?: string[]; +} +``` + +* `type` (Required): Defines what type of alert will be shown +* `message` (Required): The message who will be shown, also works with localization as well. +* `title` (Optional): The title of the message. If it is not provided, the title will be hidden. +* `dismissible` (Optional): Default is `true`. If enabled, a button on the top right corner will be shown to the users so that they can dismiss the message. +* `messageLocalizationParams` and `titleLocalizationParams` (Optional): If the message and/or the title is a key for localization service and contains some parameters, these fields could be used to pass those parameters. + +### An example with Localization + +```typescript +this.service.show({ + type: 'danger', + message: 'AbpAccount::PagerInfo{0}{1}{2}', + messageLocalizationParams: ['10', '20', '30'], + title: 'AbpAccount::EntityNotFoundErrorMessage', + titleLocalizationParams: ['Test', 'id123'], +}); +``` + +![angular-page-alert-with-params-example](./images/page-alert-with-params-example.png) + + diff --git a/docs/en/UI/Angular/Testing.md b/docs/en/UI/Angular/Testing.md index f24ae62982..7b93d48585 100644 --- a/docs/en/UI/Angular/Testing.md +++ b/docs/en/UI/Angular/Testing.md @@ -1,3 +1,376 @@ -# Angular UI: Testing +# Unit Testing Angular UI -TODO \ No newline at end of file +ABP Angular UI is tested like any other Angular application. So, [the guide here](https://angular.io/guide/testing) applies to ABP too. That said, we would like to point out some **unit testing topics specific to ABP Angular applications**. + +## Setup + +In Angular, unit tests use [Karma](https://karma-runner.github.io/) and [Jasmine](https://jasmine.github.io) by default. Although we like Jest more, we chose not to deviate from these defaults, so **the application template you download will have Karma and Jasmine preconfigured**. You can find the Karma configuration inside the _karma.conf.js_ file in the root folder. You don't have to do anything. Adding a spec file and running `npm test` will work. + +## Basics + +An over-simplified spec file looks like this: + +```ts +import { CoreTestingModule } from "@abp/ng.core/testing"; +import { ThemeBasicTestingModule } from "@abp/ng.theme.basic/testing"; +import { ThemeSharedTestingModule } from "@abp/ng.theme.shared/testing"; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; +import { NgxValidateCoreModule } from "@ngx-validate/core"; +import { MyComponent } from "./my.component"; + +describe("MyComponent", () => { + let fixture: ComponentFixture; + + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [MyComponent], + imports: [ + CoreTestingModule.withConfig(), + ThemeSharedTestingModule.withConfig(), + ThemeBasicTestingModule.withConfig(), + NgxValidateCoreModule, + ], + providers: [ + /* mock providers here */ + ], + }).compileComponents(); + }) + ); + + beforeEach(() => { + fixture = TestBed.createComponent(MyComponent); + fixture.detectChanges(); + }); + + it("should be initiated", () => { + expect(fixture.componentInstance).toBeTruthy(); + }); +}); +``` + +If you take a look at the imports, you will notice that we have prepared some testing modules to replace built-in ABP modules. This is necessary for providing mocks for some features which otherwise would break your tests. Please remember to **use testing modules** and **call their `withConfig` static method**. + +## Tips + +### Angular Testing Library + +Although you can test your code with Angular TestBed, you may find [Angular Testing Library](https://testing-library.com/docs/angular-testing-library/intro) a good alternative. + +The simple example above can be written with Angular Testing Library as follows: + +```ts +import { CoreTestingModule } from "@abp/ng.core/testing"; +import { ThemeBasicTestingModule } from "@abp/ng.theme.basic/testing"; +import { ThemeSharedTestingModule } from "@abp/ng.theme.shared/testing"; +import { ComponentFixture } from "@angular/core/testing"; +import { NgxValidateCoreModule } from "@ngx-validate/core"; +import { render } from "@testing-library/angular"; +import { MyComponent } from "./my.component"; + +describe("MyComponent", () => { + let fixture: ComponentFixture; + + beforeEach(async () => { + const result = await render(MyComponent, { + imports: [ + CoreTestingModule.withConfig(), + ThemeSharedTestingModule.withConfig(), + ThemeBasicTestingModule.withConfig(), + NgxValidateCoreModule, + ], + providers: [ + /* mock providers here */ + ], + }); + + fixture = result.fixture; + }); + + it("should be initiated", () => { + expect(fixture.componentInstance).toBeTruthy(); + }); +}); +``` + +Very similar, as you can see. The real difference kicks in when we use queries and fire events. + +```ts +// other imports +import { getByLabelText, screen } from "@testing-library/angular"; +import userEvent from "@testing-library/user-event"; + +describe("MyComponent", () => { + beforeEach(/* removed for sake of brevity */); + + it("should display advanced filters", () => { + const filters = screen.getByTestId("author-filters"); + const nameInput = getByLabelText(filters, /name/i) as HTMLInputElement; + expect(nameInput.offsetWidth).toBe(0); + + const advancedFiltersBtn = screen.getByRole("link", { name: /advanced/i }); + userEvent.click(advancedFiltersBtn); + + expect(nameInput.offsetWidth).toBeGreaterThan(0); + + userEvent.type(nameInput, "fooo{backspace}"); + expect(nameInput.value).toBe("foo"); + }); +}); +``` + +The **queries in Angular Testing Library follow practices for maintainable tests**, the user event package provides a **human-like interaction** with the DOM, and the library in general has **a clear API** that simplifies component testing. Please find some useful links below: + +- [Queries](https://testing-library.com/docs/dom-testing-library/api-queries) +- [User Event](https://testing-library.com/docs/ecosystem-user-event) +- [Examples](https://github.com/testing-library/angular-testing-library/tree/master/apps/example-app/app/examples) + +### Clearing DOM After Each Spec + +One thing to remember is that Karma runs tests in real browser instances. That means, you will be able to see the result of your test code, but also have problems with components attached to the document body which may not get cleared after each test, even when you configure Karma to do so. + +We have prepared a simple function with which you can clear any leftover DOM elements after each test. + +```ts +// other imports +import { clearPage } from "@abp/ng.core/testing"; + +describe("MyComponent", () => { + let fixture: ComponentFixture; + + afterEach(() => clearPage(fixture)); + + beforeEach(async () => { + const result = await render(MyComponent, { + /* removed for sake of brevity */ + }); + fixture = result.fixture; + }); + + // specs here +}); +``` + +Please make sure you use it because Karma will fail to remove dialogs otherwise and you will have multiple copies of modals, confirmation boxes, and alike. + +### Waiting + +Some components, modals, in particular, work off-detection-cycle. In other words, you cannot reach DOM elements inserted by these components immediately after opening them. Similarly, inserted elements are not immediately destroyed upon closing them. + +For this purpose, we have prepared a `wait` function. + +```ts +// other imports +import { wait } from "@abp/ng.core/testing"; + +describe("MyComponent", () => { + beforeEach(/* removed for sake of brevity */); + + it("should open a modal", async () => { + const openModalBtn = screen.getByRole("button", { name: "Open Modal" }); + userEvent.click(openModalBtn); + + await wait(fixture); + + const modal = screen.getByRole("dialog"); + + expect(modal).toBeTruthy(); + + /* wait again after closing the modal */ + }); +}); +``` + +The `wait` function takes a second parameter, i.e. timeout (default: `0`). Try not to use it though. Using a timeout bigger than `0` is usually a signal that something is not quite right. + +## Testing Example + +Here is an example test suite. It doesn't cover all, but gives quite a good idea about what the testing experience will be like. + +```ts +import { clearPage, CoreTestingModule, wait } from "@abp/ng.core/testing"; +import { ThemeBasicTestingModule } from "@abp/ng.theme.basic/testing"; +import { ThemeSharedTestingModule } from "@abp/ng.theme.shared/testing"; +import { ComponentFixture } from "@angular/core/testing"; +import { + NgbCollapseModule, + NgbDatepickerModule, + NgbDropdownModule, +} from "@ng-bootstrap/ng-bootstrap"; +import { NgxValidateCoreModule } from "@ngx-validate/core"; +import { CountryService } from "@proxy/countries"; +import { + findByText, + getByLabelText, + getByRole, + getByText, + queryByRole, + render, + screen, +} from "@testing-library/angular"; +import userEvent from "@testing-library/user-event"; +import { BehaviorSubject, of } from "rxjs"; +import { CountryComponent } from "./country.component"; + +const list$ = new BehaviorSubject({ + items: [{ id: "ID_US", name: "United States of America" }], + totalCount: 1, +}); + +describe("Country", () => { + let fixture: ComponentFixture; + + afterEach(() => clearPage(fixture)); + + beforeEach(async () => { + const result = await render(CountryComponent, { + imports: [ + CoreTestingModule.withConfig(), + ThemeSharedTestingModule.withConfig(), + ThemeBasicTestingModule.withConfig(), + NgxValidateCoreModule, + NgbCollapseModule, + NgbDatepickerModule, + NgbDropdownModule, + ], + providers: [ + { + provide: CountryService, + useValue: { + getList: () => list$, + }, + }, + ], + }); + + fixture = result.fixture; + }); + + it("should display advanced filters", () => { + const filters = screen.getByTestId("country-filters"); + const nameInput = getByLabelText(filters, /name/i) as HTMLInputElement; + expect(nameInput.offsetWidth).toBe(0); + + const advancedFiltersBtn = screen.getByRole("link", { name: /advanced/i }); + userEvent.click(advancedFiltersBtn); + + expect(nameInput.offsetWidth).toBeGreaterThan(0); + + userEvent.type(nameInput, "fooo{backspace}"); + expect(nameInput.value).toBe("foo"); + + userEvent.click(advancedFiltersBtn); + expect(nameInput.offsetWidth).toBe(0); + }); + + it("should have a heading", () => { + const heading = screen.getByRole("heading", { name: "Countries" }); + expect(heading).toBeTruthy(); + }); + + it("should render list in table", async () => { + const table = await screen.findByTestId("country-table"); + + const name = getByText(table, "United States of America"); + expect(name).toBeTruthy(); + }); + + it("should display edit modal", async () => { + const actionsBtn = screen.queryByRole("button", { name: /actions/i }); + userEvent.click(actionsBtn); + + const editBtn = screen.getByRole("button", { name: /edit/i }); + userEvent.click(editBtn); + + await wait(fixture); + + const modal = screen.getByRole("dialog"); + const modalHeading = queryByRole(modal, "heading", { name: /edit/i }); + expect(modalHeading).toBeTruthy(); + + const closeBtn = getByText(modal, "×"); + userEvent.click(closeBtn); + + await wait(fixture); + + expect(screen.queryByRole("dialog")).toBeFalsy(); + }); + + it("should display create modal", async () => { + const newBtn = screen.getByRole("button", { name: /new/i }); + userEvent.click(newBtn); + + await wait(fixture); + + const modal = screen.getByRole("dialog"); + const modalHeading = queryByRole(modal, "heading", { name: /new/i }); + + expect(modalHeading).toBeTruthy(); + }); + + it("should validate required name field", async () => { + const newBtn = screen.getByRole("button", { name: /new/i }); + userEvent.click(newBtn); + + await wait(fixture); + + const modal = screen.getByRole("dialog"); + const nameInput = getByRole(modal, "textbox", { + name: /^name/i, + }) as HTMLInputElement; + + userEvent.type(nameInput, "x"); + userEvent.type(nameInput, "{backspace}"); + + const nameError = await findByText(modal, /required/i); + expect(nameError).toBeTruthy(); + }); + + it("should delete a country", () => { + const getSpy = spyOn(fixture.componentInstance.list, "get"); + const deleteSpy = jasmine.createSpy().and.returnValue(of(null)); + fixture.componentInstance.service.delete = deleteSpy; + + const actionsBtn = screen.queryByRole("button", { name: /actions/i }); + userEvent.click(actionsBtn); + + const deleteBtn = screen.getByRole("button", { name: /delete/i }); + userEvent.click(deleteBtn); + + const confirmText = screen.getByText("AreYouSure"); + expect(confirmText).toBeTruthy(); + + const confirmBtn = screen.getByRole("button", { name: "Yes" }); + userEvent.click(confirmBtn); + + expect(deleteSpy).toHaveBeenCalledWith(list$.value.items[0].id); + expect(getSpy).toHaveBeenCalledTimes(1); + }); +}); +``` + +## CI Configuration + +You would need a different configuration for your CI environment. To set up a new configuration for your unit tests, find the test project in _angular.json_ file and add one as seen below: + +```json +// angular.json + +"test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { /* several options here */ }, + "configurations": { + "production": { + "karmaConfig": "karma.conf.prod.js" + } + } +} +``` + +Now you can copy the _karma.conf.js_ as _karma.conf.prod.js_ and use any configuration you like in it. Please check [Karma configuration file document](http://karma-runner.github.io/5.2/config/configuration-file.html) for config options. + +Finally, don't forget to run your CI tests with the following command: + +```sh +npm test -- --prod +``` diff --git a/docs/en/UI/Angular/images/page-alert-warning-example.png b/docs/en/UI/Angular/images/page-alert-warning-example.png new file mode 100644 index 0000000000..253a811a22 Binary files /dev/null and b/docs/en/UI/Angular/images/page-alert-warning-example.png differ diff --git a/docs/en/UI/Angular/images/page-alert-with-params-example.png b/docs/en/UI/Angular/images/page-alert-with-params-example.png new file mode 100644 index 0000000000..8fc5236de3 Binary files /dev/null and b/docs/en/UI/Angular/images/page-alert-with-params-example.png differ diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index c7a7554fdc..517da0239f 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -740,6 +740,10 @@ { "text": "PWA Configuration", "path": "UI/Angular/PWA-Configuration.md" + }, + { + "text": "Unit Testing", + "path": "UI/Angular/Testing.md" } ] }, @@ -750,6 +754,10 @@ "text": "Config State Service", "path": "UI/Angular/Config-State-Service.md" }, + { + "text": "Authorization", + "path": "UI/Angular/Authorization.md" + }, { "text": "HTTP Requests", "path": "UI/Angular/HTTP-Requests.md" @@ -814,6 +822,10 @@ { "text": "Toast Overlay", "path": "UI/Angular/Toaster-Service.md" + }, + { + "text": "Page Alerts", + "path": "UI/Angular/Page-Alerts.md" } ] }, diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LanguageSwitch.razor b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LanguageSwitch.razor index 6b93618f44..bfc970c436 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LanguageSwitch.razor +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LanguageSwitch.razor @@ -21,7 +21,7 @@ private IReadOnlyList _otherLanguages; private LanguageInfo _currentLanguage; - protected async override Task OnInitializedAsync() + protected override async Task OnInitializedAsync() { var selectedLanguageName = await JsRuntime.InvokeAsync( "localStorage.getItem", diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs index 494eca34ab..3238483cfb 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs @@ -13,7 +13,7 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic protected ApplicationMenu Menu { get; set; } - protected async override Task OnInitializedAsync() + protected override async Task OnInitializedAsync() { Menu = await MenuManager.GetAsync(StandardMenus.User); diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenu.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenu.razor.cs index 1779d73d28..416efeffad 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenu.razor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavMenu.razor.cs @@ -11,7 +11,7 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic protected ApplicationMenu Menu { get; set; } - protected async override Task OnInitializedAsync() + protected override async Task OnInitializedAsync() { Menu = await MenuManager.GetAsync(StandardMenus.Main); } diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavToolbar.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavToolbar.razor.cs index 33044282f9..6fddf263b3 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavToolbar.razor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/NavToolbar.razor.cs @@ -12,7 +12,7 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic private List ToolbarItemRenders { get; set; } = new List(); - protected async override Task OnInitializedAsync() + protected override async Task OnInitializedAsync() { var toolbar = await ToolbarManager.GetAsync(StandardToolbars.Main); diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Toolbars/ToolbarConfigurationContext.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Toolbars/ToolbarConfigurationContext.cs index 7174dbe431..4e30a50206 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Toolbars/ToolbarConfigurationContext.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Toolbars/ToolbarConfigurationContext.cs @@ -4,35 +4,19 @@ using JetBrains.Annotations; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; +using Volo.Abp.DependencyInjection; namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Toolbars { public class ToolbarConfigurationContext : IToolbarConfigurationContext { public IServiceProvider ServiceProvider { get; } - private readonly object _serviceProviderLock = new object(); - private TRef LazyGetRequiredService(Type serviceType, ref TRef reference) - { - if (reference == null) - { - lock (_serviceProviderLock) - { - if (reference == null) - { - reference = (TRef)ServiceProvider.GetRequiredService(serviceType); - } - } - } - - return reference; - } + private readonly IAbpLazyServiceProvider _lazyServiceProvider; - public IAuthorizationService AuthorizationService => LazyGetRequiredService(typeof(IAuthorizationService), ref _authorizationService); - private IAuthorizationService _authorizationService; + public IAuthorizationService AuthorizationService => _lazyServiceProvider.LazyGetRequiredService(); - private IStringLocalizerFactory _stringLocalizerFactory; - public IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(typeof(IStringLocalizerFactory),ref _stringLocalizerFactory); + public IStringLocalizerFactory StringLocalizerFactory => _lazyServiceProvider.LazyGetRequiredService(); public Toolbar Toolbar { get; } @@ -40,6 +24,7 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Toolbars { Toolbar = toolbar; ServiceProvider = serviceProvider; + _lazyServiceProvider = ServiceProvider.GetRequiredService(); } public Task IsGrantedAsync(string policyName) diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs index 7fa2038020..255e0ac89b 100644 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs @@ -25,7 +25,12 @@ namespace Volo.Abp.AspNetCore.MultiTenancy protected override Task GetTenantIdOrNameFromHttpContextOrNullAsync(ITenantResolveContext context, HttpContext httpContext) { - var hostName = httpContext.Request.Host.Host.RemovePreFix(ProtocolPrefixes); + if (!httpContext.Request.Host.HasValue) + { + return Task.FromResult(null); + } + + var hostName = httpContext.Request.Host.Value.RemovePreFix(ProtocolPrefixes); var extractResult = FormattedStringValueExtracter.Extract(hostName, _domainFormat, ignoreCase: true); context.Handled = true; diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/FormTenantResolveContributor.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/FormTenantResolveContributor.cs index 868ef78519..77c12bef7b 100644 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/FormTenantResolveContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/FormTenantResolveContributor.cs @@ -11,7 +11,7 @@ namespace Volo.Abp.AspNetCore.MultiTenancy public override string Name => ContributorName; - protected async override Task GetTenantIdOrNameFromHttpContextOrNullAsync(ITenantResolveContext context, HttpContext httpContext) + protected override async Task GetTenantIdOrNameFromHttpContextOrNullAsync(ITenantResolveContext context, HttpContext httpContext) { if (!httpContext.Request.HasFormContentType) { diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpTenantResolveContributerBase.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpTenantResolveContributerBase.cs index 18f76ee711..3b454b5ef9 100644 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpTenantResolveContributerBase.cs +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpTenantResolveContributerBase.cs @@ -10,7 +10,7 @@ namespace Volo.Abp.AspNetCore.MultiTenancy { public abstract class HttpTenantResolveContributorBase : TenantResolveContributorBase { - public async override Task ResolveAsync(ITenantResolveContext context) + public override async Task ResolveAsync(ITenantResolveContext context) { var httpContext = context.GetHttpContext(); if (httpContext == null) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo.Abp.AspNetCore.Mvc.Client.Common.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo.Abp.AspNetCore.Mvc.Client.Common.csproj index dc672d842f..b509a5df59 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo.Abp.AspNetCore.Mvc.Client.Common.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo.Abp.AspNetCore.Mvc.Client.Common.csproj @@ -16,7 +16,9 @@ + + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCommonModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCommonModule.cs index de5e80ff64..b37c9d57fd 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCommonModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCommonModule.cs @@ -1,5 +1,7 @@ using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Authorization; using Volo.Abp.Caching; +using Volo.Abp.Features; using Volo.Abp.Http.Client; using Volo.Abp.Localization; using Volo.Abp.Modularity; @@ -10,7 +12,9 @@ namespace Volo.Abp.AspNetCore.Mvc.Client typeof(AbpHttpClientModule), typeof(AbpAspNetCoreMvcContractsModule), typeof(AbpCachingModule), - typeof(AbpLocalizationModule) + typeof(AbpLocalizationModule), + typeof(AbpAuthorizationModule), + typeof(AbpFeaturesModule) )] public class AbpAspNetCoreMvcClientCommonModule : AbpModule { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteFeatureChecker.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteFeatureChecker.cs index 4cba01bea2..f769f512a5 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteFeatureChecker.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteFeatureChecker.cs @@ -13,7 +13,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Client ConfigurationClient = configurationClient; } - public async override Task GetOrNullAsync(string name) + public override async Task GetOrNullAsync(string name) { var configuration = await ConfigurationClient.GetAsync(); return configuration.Features.Values.GetOrDefault(name); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo.Abp.AspNetCore.Mvc.Client.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo.Abp.AspNetCore.Mvc.Client.csproj index 3657e27fef..aae260d7e8 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo.Abp.AspNetCore.Mvc.Client.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo.Abp.AspNetCore.Mvc.Client.csproj @@ -18,6 +18,7 @@ + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs index 1186b48ae7..48e2461167 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs @@ -1,9 +1,11 @@ -using Volo.Abp.Modularity; +using Volo.Abp.EventBus; +using Volo.Abp.Modularity; namespace Volo.Abp.AspNetCore.Mvc.Client { [DependsOn( - typeof(AbpAspNetCoreMvcClientCommonModule) + typeof(AbpAspNetCoreMvcClientCommonModule), + typeof(AbpEventBusModule) )] public class AbpAspNetCoreMvcClientModule : AbpModule { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs index a6a4d33668..4f5b7c84b0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs @@ -56,7 +56,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Client async () => await Proxy.Service.GetAsync(), () => new DistributedCacheEntryOptions { - AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(120) //TODO: Should be configurable. Default value should be higher (5 mins would be good). + AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300) //TODO: Should be configurable. } ); @@ -83,7 +83,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Client protected virtual string CreateCacheKey() { - return $"ApplicationConfiguration_{CurrentUser.Id?.ToString("N") ?? "Anonymous"}_{CultureInfo.CurrentUICulture.Name}"; + return MvcCachedApplicationConfigurationClientHelper.CreateCacheKey(CurrentUser); } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs new file mode 100644 index 0000000000..4b4a0e6301 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs @@ -0,0 +1,13 @@ +using System.Globalization; +using Volo.Abp.Users; + +namespace Volo.Abp.AspNetCore.Mvc.Client +{ + internal static class MvcCachedApplicationConfigurationClientHelper + { + public static string CreateCacheKey(ICurrentUser currentUser) + { + return $"ApplicationConfiguration_{currentUser.Id?.ToString("N") ?? "Anonymous"}_{CultureInfo.CurrentUICulture.Name}"; + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCurrentApplicationConfigurationCacheResetEventHandler.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCurrentApplicationConfigurationCacheResetEventHandler.cs new file mode 100644 index 0000000000..e8f5b201da --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCurrentApplicationConfigurationCacheResetEventHandler.cs @@ -0,0 +1,34 @@ +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus; +using Volo.Abp.Users; + +namespace Volo.Abp.AspNetCore.Mvc.Client +{ + public class MvcCurrentApplicationConfigurationCacheResetEventHandler : + ILocalEventHandler, + ITransientDependency + { + protected ICurrentUser CurrentUser { get; } + protected IDistributedCache Cache { get; } + + public MvcCurrentApplicationConfigurationCacheResetEventHandler(ICurrentUser currentUser, + IDistributedCache cache) + { + CurrentUser = currentUser; + Cache = cache; + } + + public virtual async Task HandleEventAsync(CurrentApplicationConfigurationCacheResetEventData eventData) + { + await Cache.RemoveAsync(CreateCacheKey()); + } + + protected virtual string CreateCacheKey() + { + return MvcCachedApplicationConfigurationClientHelper.CreateCacheKey(CurrentUser); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo.Abp.AspNetCore.Mvc.Contracts.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo.Abp.AspNetCore.Mvc.Contracts.csproj index 04b2e7ec59..7a5da3dca7 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo.Abp.AspNetCore.Mvc.Contracts.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo.Abp.AspNetCore.Mvc.Contracts.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcContractsModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcContractsModule.cs index 54a7589dd4..3bf299437c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcContractsModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcContractsModule.cs @@ -4,7 +4,7 @@ using Volo.Abp.Modularity; namespace Volo.Abp.AspNetCore.Mvc { [DependsOn( - typeof(AbpDddApplicationModule) + typeof(AbpDddApplicationContractsModule) )] public class AbpAspNetCoreMvcContractsModule : AbpModule { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentApplicationConfigurationCacheResetEventData.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentApplicationConfigurationCacheResetEventData.cs new file mode 100644 index 0000000000..e84e96d9dd --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentApplicationConfigurationCacheResetEventData.cs @@ -0,0 +1,10 @@ +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations +{ + /// + /// This event is used to invalidate current user's cached configuration. + /// + public class CurrentApplicationConfigurationCacheResetEventData + { + + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Breadcrumb/AbpBreadcrumbTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Breadcrumb/AbpBreadcrumbTagHelperService.cs index e1b4469f8c..4b433ac495 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Breadcrumb/AbpBreadcrumbTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Breadcrumb/AbpBreadcrumbTagHelperService.cs @@ -8,7 +8,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Breadcrumb { public class AbpBreadcrumbTagHelperService : AbpTagHelperService { - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { output.TagName = "nav"; output.Attributes.Add("aria-label", "breadcrumb"); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Carousel/AbpCarouselTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Carousel/AbpCarouselTagHelperService.cs index e4a277ba66..c3672db7f5 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Carousel/AbpCarouselTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Carousel/AbpCarouselTagHelperService.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Carousel L = localizer; } - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { output.TagName = "div"; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionItemTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionItemTagHelperService.cs index f9e019391f..6afb918704 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionItemTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionItemTagHelperService.cs @@ -9,7 +9,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Collapse { public class AbpAccordionItemTagHelperService : AbpTagHelperService { - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { SetRandomIdIfNotProvided(); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionTagHelperService.cs index 7651309e1a..d55bb04d21 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpAccordionTagHelperService.cs @@ -17,7 +17,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Collapse HtmlGenerator = htmlGenerator; } - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { SetRandomIdIfNotProvided(); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelperService.cs index 198c5b91e6..3c429b32ef 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelperService.cs @@ -6,7 +6,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Collapse { public class AbpCollapseBodyTagHelperService : AbpTagHelperService { - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { output.TagName = "div"; output.Attributes.AddClass("collapse"); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelperService.cs index 52ea6ace85..c6a0307d2d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelperService.cs @@ -24,7 +24,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown _serviceProvider = serviceProvider; } - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var content = await output.GetChildContentAsync(); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs index da622b968b..7d2f0804b7 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs @@ -36,7 +36,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form _localizer = localizer; } - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var list = InitilizeFormGroupContentsContext(context, output); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index 246c611533..48abbd93e9 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -26,7 +26,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form _tagHelperLocalizer = tagHelperLocalizer; } - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var (innerHtml, isCheckBox) = await GetFormInputGroupAsHtmlAsync(context, output); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs index dde58ed3e4..6050fb91d6 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -36,7 +36,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form _stringLocalizerFactory = stringLocalizerFactory; } - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var innerHtml = await GetFormInputGroupAsHtmlAsync(context, output); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelperService.cs index aa83265e94..5bc2330bf1 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelperService.cs @@ -8,7 +8,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal { public class AbpModalTagHelperService : AbpTagHelperService { - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { output.TagName = null; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Pagination/AbpPaginationTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Pagination/AbpPaginationTagHelperService.cs index 148f196aad..cb1e395f40 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Pagination/AbpPaginationTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Pagination/AbpPaginationTagHelperService.cs @@ -32,7 +32,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination _stringLocalizerFactory = stringLocalizerFactory; } - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { if (TagHelper.Model.ShownItemsCount <= 0) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tab/AbpTabDropdownTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tab/AbpTabDropdownTagHelperService.cs index 02810e9666..726a947be2 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tab/AbpTabDropdownTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tab/AbpTabDropdownTagHelperService.cs @@ -9,7 +9,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Tab { public class AbpTabDropdownTagHelperService : AbpTagHelperService { - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { if (string.IsNullOrWhiteSpace(TagHelper.Name)) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tab/AbpTabTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tab/AbpTabTagHelperService.cs index db05c5c686..a9a134ceba 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tab/AbpTabTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tab/AbpTabTagHelperService.cs @@ -9,7 +9,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Tab { public class AbpTabTagHelperService : AbpTagHelperService { - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { SetPlaceholderForNameIfNotProvided(); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tab/AbpTabsTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tab/AbpTabsTagHelperService.cs index 8046af8ccd..92e50990a4 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tab/AbpTabsTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tab/AbpTabsTagHelperService.cs @@ -20,7 +20,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Tab HtmlGenerator = htmlGenerator; } - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { SetRandomNameIfNotProvided(); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleConfigurationContext.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleConfigurationContext.cs index 98fe3546c5..00c3762ed9 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleConfigurationContext.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleConfigurationContext.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; using Volo.Abp.Localization; namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling @@ -13,35 +14,18 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling public IFileProvider FileProvider { get; } + public IServiceProvider ServiceProvider { get; } + + private readonly IAbpLazyServiceProvider _lazyServiceProvider; + public BundleConfigurationContext(IServiceProvider serviceProvider, IFileProvider fileProvider) { Files = new List(); ServiceProvider = serviceProvider; + _lazyServiceProvider = ServiceProvider.GetRequiredService(); FileProvider = fileProvider; } - public IServiceProvider ServiceProvider { get; } - private readonly object _serviceProviderLock = new object(); - - private TRef LazyGetRequiredService(Type serviceType, ref TRef reference) - { - if (reference == null) - { - lock (_serviceProviderLock) - { - if (reference == null) - { - reference = (TRef)ServiceProvider.GetRequiredService(serviceType); - } - } - } - - return reference; - } - - private IOptions _abpLocalizationOptions; - - public AbpLocalizationOptions LocalizationOptions => - LazyGetRequiredService(typeof(IOptions), ref _abpLocalizationOptions).Value; + public AbpLocalizationOptions LocalizationOptions => _lazyServiceProvider.LazyGetRequiredService>().Value; } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleItemTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleItemTagHelperService.cs index 0ffb5b9049..eca80c5fcf 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleItemTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleItemTagHelperService.cs @@ -16,7 +16,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers ResourceService = resourceService; } - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var tagHelperItems = context.Items.GetOrDefault(AbpTagHelperConsts.ContextBundleItemListKey) as List; if (tagHelperItems != null) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleTagHelperService.cs index 9158f33b90..f0c76d5cc4 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleTagHelperService.cs @@ -16,7 +16,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers ResourceService = resourceService; } - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { await ResourceService.ProcessAsync( TagHelper.ViewContext, diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpTagHelperScriptService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpTagHelperScriptService.cs index 9e4e77a6dd..6efbb793e7 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpTagHelperScriptService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpTagHelperScriptService.cs @@ -38,7 +38,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers ); } - protected async override Task> GetBundleFilesAsync(string bundleName) + protected override async Task> GetBundleFilesAsync(string bundleName) { return await BundleManager.GetScriptBundleFilesAsync(bundleName); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpTagHelperStyleService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpTagHelperStyleService.cs index a9d9b54fca..8612e4f8b4 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpTagHelperStyleService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpTagHelperStyleService.cs @@ -38,7 +38,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers ); } - protected async override Task> GetBundleFilesAsync(string bundleName) + protected override async Task> GetBundleFilesAsync(string bundleName) { return await BundleManager.GetStyleBundleFilesAsync(bundleName); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/TagHelpers/AbpComponentDemoSectionTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/TagHelpers/AbpComponentDemoSectionTagHelper.cs index 9a16b4b43a..328024cc2b 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/TagHelpers/AbpComponentDemoSectionTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo/Views/Components/Themes/Shared/TagHelpers/AbpComponentDemoSectionTagHelper.cs @@ -28,7 +28,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Demo.Views.Components.Themes.S _guidGenerator = guidGenerator; } - public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { output.TagName = null; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarConfigurationContext.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarConfigurationContext.cs index 37f3308198..7ae40af60f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarConfigurationContext.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Toolbars/ToolbarConfigurationContext.cs @@ -5,35 +5,19 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using Volo.Abp.AspNetCore.Mvc.UI.Theming; +using Volo.Abp.DependencyInjection; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars { public class ToolbarConfigurationContext : IToolbarConfigurationContext { public IServiceProvider ServiceProvider { get; } - private readonly object _serviceProviderLock = new object(); - private TRef LazyGetRequiredService(Type serviceType, ref TRef reference) - { - if (reference == null) - { - lock (_serviceProviderLock) - { - if (reference == null) - { - reference = (TRef)ServiceProvider.GetRequiredService(serviceType); - } - } - } - - return reference; - } + private readonly IAbpLazyServiceProvider _lazyServiceProvider; - public IAuthorizationService AuthorizationService => LazyGetRequiredService(typeof(IAuthorizationService), ref _authorizationService); - private IAuthorizationService _authorizationService; + public IAuthorizationService AuthorizationService => _lazyServiceProvider.LazyGetRequiredService(); - private IStringLocalizerFactory _stringLocalizerFactory; - public IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(typeof(IStringLocalizerFactory),ref _stringLocalizerFactory); + public IStringLocalizerFactory StringLocalizerFactory => _lazyServiceProvider.LazyGetRequiredService(); public ITheme Theme { get; } @@ -44,8 +28,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars Theme = currentTheme; Toolbar = toolbar; ServiceProvider = serviceProvider; + _lazyServiceProvider = ServiceProvider.GetRequiredService(); } - + public Task IsGrantedAsync(string policyName) { return AuthorizationService.IsGrantedAsync(policyName); @@ -62,7 +47,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars { return StringLocalizerFactory.Create(); } - + [NotNull] public IStringLocalizer GetLocalizer(Type resourceType) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/RazorPages/AbpPageModel.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/RazorPages/AbpPageModel.cs index fcbe9af59c..449747d0cc 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/RazorPages/AbpPageModel.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/RazorPages/AbpPageModel.cs @@ -10,6 +10,7 @@ using System; using System.Threading.Tasks; using Volo.Abp.AspNetCore.Mvc.UI.Alerts; using Volo.Abp.AspNetCore.Mvc.Validation; +using Volo.Abp.DependencyInjection; using Volo.Abp.Guids; using Volo.Abp.Localization; using Volo.Abp.MultiTenancy; @@ -24,67 +25,27 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.RazorPages { public abstract class AbpPageModel : PageModel { - public IServiceProvider ServiceProvider { get; set; } - protected readonly object ServiceProviderLock = new object(); - - protected TService LazyGetRequiredService(ref TService reference) - => LazyGetRequiredService(typeof(TService), ref reference); + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } - protected TRef LazyGetRequiredService(Type serviceType, ref TRef reference) - { - if (reference == null) - { - lock (ServiceProviderLock) - { - if (reference == null) - { - reference = (TRef)ServiceProvider.GetRequiredService(serviceType); - } - } - } - - return reference; - } + public IServiceProvider ServiceProvider { get; set; } - protected IClock Clock => LazyGetRequiredService(ref _clock); - private IClock _clock; + protected IClock Clock => LazyServiceProvider.LazyGetRequiredService(); protected AlertList Alerts => AlertManager.Alerts; - protected IUnitOfWorkManager UnitOfWorkManager => LazyGetRequiredService(ref _unitOfWorkManager); - private IUnitOfWorkManager _unitOfWorkManager; + protected IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService(); protected Type ObjectMapperContext { get; set; } - protected IObjectMapper ObjectMapper - { - get - { - if (_objectMapper != null) - { - return _objectMapper; - } - - if (ObjectMapperContext == null) - { - return LazyGetRequiredService(ref _objectMapper); - } - - return LazyGetRequiredService( - typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext), - ref _objectMapper - ); - } - } - private IObjectMapper _objectMapper; + protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetService(provider => + ObjectMapperContext == null + ? provider.GetRequiredService() + : (IObjectMapper) provider.GetRequiredService(typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext))); - protected IGuidGenerator GuidGenerator => LazyGetRequiredService(ref _guidGenerator); - private IGuidGenerator _guidGenerator; + protected IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance); - protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); - private ILoggerFactory _loggerFactory; + protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService(); - protected IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(ref _stringLocalizerFactory); - private IStringLocalizerFactory _stringLocalizerFactory; + protected IStringLocalizerFactory StringLocalizerFactory => LazyServiceProvider.LazyGetRequiredService(); protected IStringLocalizer L { @@ -103,31 +64,23 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.RazorPages protected Type LocalizationResourceType { get; set; } - protected ICurrentUser CurrentUser => LazyGetRequiredService(ref _currentUser); - private ICurrentUser _currentUser; + protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService(); - protected ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant); - private ICurrentTenant _currentTenant; + protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService(); - protected ISettingProvider SettingProvider => LazyGetRequiredService(ref _settingProvider); - private ISettingProvider _settingProvider; + protected ISettingProvider SettingProvider => LazyServiceProvider.LazyGetRequiredService(); - protected IModelStateValidator ModelValidator => LazyGetRequiredService(ref _modelValidator); - private IModelStateValidator _modelValidator; + protected IModelStateValidator ModelValidator => LazyServiceProvider.LazyGetRequiredService(); - protected IAuthorizationService AuthorizationService => LazyGetRequiredService(ref _authorizationService); - private IAuthorizationService _authorizationService; + protected IAuthorizationService AuthorizationService => LazyServiceProvider.LazyGetRequiredService(); - protected IAlertManager AlertManager => LazyGetRequiredService(ref _alertManager); - private IAlertManager _alertManager; + protected IAlertManager AlertManager => LazyServiceProvider.LazyGetRequiredService(); protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current; - protected ILogger Logger => _lazyLogger.Value; - private Lazy _lazyLogger => new Lazy(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true); + protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance); - protected IAppUrlProvider AppUrlProvider => LazyGetRequiredService(ref _appUrlProvider); - private IAppUrlProvider _appUrlProvider; + protected IAppUrlProvider AppUrlProvider => LazyServiceProvider.LazyGetRequiredService(); protected virtual NoContentResult NoContent() //TODO: Is that true to return empty result like that? { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj index d0806d929d..81c4a3e7e6 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj @@ -21,6 +21,7 @@ + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpActionContextExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpActionContextExtensions.cs new file mode 100644 index 0000000000..07b54cc5df --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpActionContextExtensions.cs @@ -0,0 +1,20 @@ +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Mvc +{ + internal static class AbpActionContextExtensions + { + public static T GetRequiredService(this FilterContext context) + where T : class + { + return context.HttpContext.RequestServices.GetRequiredService(); + } + + public static T GetService(this FilterContext context, T defaultValue = default) + where T : class + { + return context.HttpContext.RequestServices.GetService() ?? defaultValue; + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs index e5edd9662d..0c2e9345e6 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs @@ -22,6 +22,7 @@ using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Localization; using Volo.Abp.ApiVersioning; +using Volo.Abp.Application; using Volo.Abp.AspNetCore.Mvc.AntiForgery; using Volo.Abp.AspNetCore.Mvc.ApiExploring; using Volo.Abp.AspNetCore.Mvc.Conventions; @@ -49,7 +50,8 @@ namespace Volo.Abp.AspNetCore.Mvc typeof(AbpApiVersioningAbstractionsModule), typeof(AbpAspNetCoreMvcContractsModule), typeof(AbpUiNavigationModule), - typeof(AbpGlobalFeaturesModule) + typeof(AbpGlobalFeaturesModule), + typeof(AbpDddApplicationModule) )] public class AbpAspNetCoreMvcModule : AbpModule { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs index f83353092e..52f1d251cb 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs @@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Volo.Abp.Aspects; using Volo.Abp.AspNetCore.Mvc.Validation; +using Volo.Abp.DependencyInjection; using Volo.Abp.Features; using Volo.Abp.Guids; using Volo.Abp.Localization; @@ -22,85 +23,41 @@ namespace Volo.Abp.AspNetCore.Mvc { public abstract class AbpController : Controller, IAvoidDuplicateCrossCuttingConcerns { - public IServiceProvider ServiceProvider { get; set; } - protected readonly object ServiceProviderLock = new object(); - - protected TService LazyGetRequiredService(ref TService reference) - => LazyGetRequiredService(typeof(TService), ref reference); - - protected TRef LazyGetRequiredService(Type serviceType, ref TRef reference) - { - if (reference == null) - { - lock (ServiceProviderLock) - { - if (reference == null) - { - reference = (TRef)ServiceProvider.GetRequiredService(serviceType); - } - } - } + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } - return reference; - } + public IServiceProvider ServiceProvider { get; set; } - protected IUnitOfWorkManager UnitOfWorkManager => LazyGetRequiredService(ref _unitOfWorkManager); - private IUnitOfWorkManager _unitOfWorkManager; + protected IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService(); protected Type ObjectMapperContext { get; set; } - protected IObjectMapper ObjectMapper - { - get - { - if (_objectMapper != null) - { - return _objectMapper; - } + protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetService(provider => + ObjectMapperContext == null + ? provider.GetRequiredService() + : (IObjectMapper) provider.GetRequiredService(typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext))); - if (ObjectMapperContext == null) - { - return LazyGetRequiredService(ref _objectMapper); - } + protected IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance); - return LazyGetRequiredService( - typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext), - ref _objectMapper - ); - } - } - private IObjectMapper _objectMapper; - - protected IGuidGenerator GuidGenerator => LazyGetRequiredService(ref _guidGenerator); - private IGuidGenerator _guidGenerator; - - protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); - private ILoggerFactory _loggerFactory; + protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService(); - protected ILogger Logger => _lazyLogger.Value; - private Lazy _lazyLogger => new Lazy(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true); + protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance); - protected ICurrentUser CurrentUser => LazyGetRequiredService(ref _currentUser); - private ICurrentUser _currentUser; + protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService(); - protected ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant); - private ICurrentTenant _currentTenant; + protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService(); - protected IAuthorizationService AuthorizationService => LazyGetRequiredService(ref _authorizationService); - private IAuthorizationService _authorizationService; + protected IAuthorizationService AuthorizationService => LazyServiceProvider.LazyGetRequiredService(); protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current; - protected IClock Clock => LazyGetRequiredService(ref _clock); - private IClock _clock; + protected IClock Clock => LazyServiceProvider.LazyGetRequiredService(); - protected IModelStateValidator ModelValidator => LazyGetRequiredService(ref _modelValidator); - private IModelStateValidator _modelValidator; + protected IModelStateValidator ModelValidator => LazyServiceProvider.LazyGetRequiredService(); - protected IFeatureChecker FeatureChecker => LazyGetRequiredService(ref _featureChecker); - private IFeatureChecker _featureChecker; + protected IFeatureChecker FeatureChecker => LazyServiceProvider.LazyGetRequiredService(); - protected IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(ref _stringLocalizerFactory); - private IStringLocalizerFactory _stringLocalizerFactory; + protected IAppUrlProvider AppUrlProvider => LazyServiceProvider.LazyGetRequiredService(); + + protected IStringLocalizerFactory StringLocalizerFactory => LazyServiceProvider.LazyGetRequiredService(); protected IStringLocalizer L { @@ -116,9 +73,6 @@ namespace Volo.Abp.AspNetCore.Mvc } private IStringLocalizer _localizer; - protected IAppUrlProvider AppUrlProvider => LazyGetRequiredService(ref _appUrlProvider); - private IAppUrlProvider _appUrlProvider; - protected Type LocalizationResource { get => _localizationResource; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpViewComponent.cs index 2c0e38c13c..2ac02b8ac5 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpViewComponent.cs @@ -1,55 +1,22 @@ using System; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.DependencyInjection; using Volo.Abp.ObjectMapping; namespace Volo.Abp.AspNetCore.Mvc { public abstract class AbpViewComponent : ViewComponent { - public IServiceProvider ServiceProvider { get; set; } - protected readonly object ServiceProviderLock = new object(); - - protected TService LazyGetRequiredService(ref TService reference) - => LazyGetRequiredService(typeof(TService), ref reference); - - protected TRef LazyGetRequiredService(Type serviceType, ref TRef reference) - { - if (reference == null) - { - lock (ServiceProviderLock) - { - if (reference == null) - { - reference = (TRef)ServiceProvider.GetRequiredService(serviceType); - } - } - } + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } - return reference; - } + public IServiceProvider ServiceProvider { get; set; } protected Type ObjectMapperContext { get; set; } - protected IObjectMapper ObjectMapper - { - get - { - if (_objectMapper != null) - { - return _objectMapper; - } - - if (ObjectMapperContext == null) - { - return LazyGetRequiredService(ref _objectMapper); - } - return LazyGetRequiredService( - typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext), - ref _objectMapper - ); - } - } - private IObjectMapper _objectMapper; + protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetService(provider => + ObjectMapperContext == null + ? provider.GetRequiredService() + : (IObjectMapper) provider.GetRequiredService(typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext))); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs index 0ee62f9b65..33db273c07 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs @@ -12,17 +12,6 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing { public class AbpAuditActionFilter : IAsyncActionFilter, ITransientDependency { - protected AbpAuditingOptions Options { get; } - private readonly IAuditingHelper _auditingHelper; - private readonly IAuditingManager _auditingManager; - - public AbpAuditActionFilter(IOptions options, IAuditingHelper auditingHelper, IAuditingManager auditingManager) - { - Options = options.Value; - _auditingHelper = auditingHelper; - _auditingManager = auditingManager; - } - public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { if (!ShouldSaveAudit(context, out var auditLog, out var auditLogAction)) @@ -63,7 +52,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing auditLog = null; auditLogAction = null; - if (!Options.IsEnabled) + var options = context.GetRequiredService>().Value; + if (!options.IsEnabled) { return false; } @@ -73,19 +63,20 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing return false; } - var auditLogScope = _auditingManager.Current; + var auditLogScope = context.GetRequiredService().Current; if (auditLogScope == null) { return false; } - if (!_auditingHelper.ShouldSaveAudit(context.ActionDescriptor.GetMethodInfo(), true)) + var auditingHelper = context.GetRequiredService(); + if (!auditingHelper.ShouldSaveAudit(context.ActionDescriptor.GetMethodInfo(), true)) { return false; } auditLog = auditLogScope.Log; - auditLogAction = _auditingHelper.CreateAuditLogAction( + auditLogAction = auditingHelper.CreateAuditLogAction( auditLog, context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.AsType(), context.ActionDescriptor.AsControllerActionDescriptor().MethodInfo, diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs index 6e9996574c..cc12120280 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs @@ -12,22 +12,11 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing { public class AbpAuditPageFilter : IAsyncPageFilter, ITransientDependency { - protected AbpAuditingOptions Options { get; } - private readonly IAuditingHelper _auditingHelper; - private readonly IAuditingManager _auditingManager; - - public AbpAuditPageFilter(IOptions options, IAuditingHelper auditingHelper, IAuditingManager auditingManager) - { - Options = options.Value; - _auditingHelper = auditingHelper; - _auditingManager = auditingManager; - } - public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) { return Task.CompletedTask; } - + public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) { if (context.HandlerMethod == null || !ShouldSaveAudit(context, out var auditLog, out var auditLogAction)) @@ -68,7 +57,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing auditLog = null; auditLogAction = null; - if (!Options.IsEnabled) + var options = context.GetRequiredService>().Value; + if (!options.IsEnabled) { return false; } @@ -78,19 +68,20 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing return false; } - var auditLogScope = _auditingManager.Current; + var auditLogScope = context.GetRequiredService().Current; if (auditLogScope == null) { return false; } - if (!_auditingHelper.ShouldSaveAudit(context.HandlerMethod.MethodInfo, true)) + var auditingHelper = context.GetRequiredService(); + if (!auditingHelper.ShouldSaveAudit(context.HandlerMethod.MethodInfo, true)) { return false; } auditLog = auditLogScope.Log; - auditLogAction = _auditingHelper.CreateAuditLogAction( + auditLogAction = auditingHelper.CreateAuditLogAction( auditLog, context.HandlerMethod.GetType(), context.HandlerMethod.MethodInfo, @@ -100,4 +91,4 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing return true; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Content/RemoteStreamContentOutputFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Content/RemoteStreamContentOutputFormatter.cs index d3ecfaff27..706e514254 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Content/RemoteStreamContentOutputFormatter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Content/RemoteStreamContentOutputFormatter.cs @@ -18,7 +18,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Content return typeof(IRemoteStreamContent).IsAssignableFrom(type); } - public async override Task WriteResponseBodyAsync(OutputFormatterWriteContext context) + public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context) { var remoteStream = (IRemoteStreamContent)context.Object; using (var stream = remoteStream.GetStream()) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs index c6f353b876..6c447bc893 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs @@ -1,11 +1,10 @@ -using System; +using System; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Filters; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; @@ -19,27 +18,6 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling { public class AbpExceptionFilter : IAsyncExceptionFilter, ITransientDependency { - public ILogger Logger { get; set; } - - private readonly IExceptionToErrorInfoConverter _errorInfoConverter; - private readonly IHttpExceptionStatusCodeFinder _statusCodeFinder; - private readonly IJsonSerializer _jsonSerializer; - private readonly AbpExceptionHandlingOptions _exceptionHandlingOptions; - - public AbpExceptionFilter( - IExceptionToErrorInfoConverter errorInfoConverter, - IHttpExceptionStatusCodeFinder statusCodeFinder, - IJsonSerializer jsonSerializer, - IOptions exceptionHandlingOptions) - { - _errorInfoConverter = errorInfoConverter; - _statusCodeFinder = statusCodeFinder; - _jsonSerializer = jsonSerializer; - _exceptionHandlingOptions = exceptionHandlingOptions.Value; - - Logger = NullLogger.Instance; - } - public async Task OnExceptionAsync(ExceptionContext context) { if (!ShouldHandleException(context)) @@ -78,9 +56,13 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling //TODO: Trigger an AbpExceptionHandled event or something like that. context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true"); - context.HttpContext.Response.StatusCode = (int)_statusCodeFinder.GetStatusCode(context.HttpContext, context.Exception); + context.HttpContext.Response.StatusCode = (int) context + .GetRequiredService() + .GetStatusCode(context.HttpContext, context.Exception); - var remoteServiceErrorInfo = _errorInfoConverter.Convert(context.Exception, _exceptionHandlingOptions.SendExceptionsDetailsToClients); + var exceptionHandlingOptions = context.GetRequiredService>().Value; + var exceptionToErrorInfoConverter = context.GetRequiredService(); + var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, exceptionHandlingOptions.SendExceptionsDetailsToClients); context.Result = new ObjectResult(new RemoteServiceErrorResponse(remoteServiceErrorInfo)); @@ -88,17 +70,15 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling var remoteServiceErrorInfoBuilder = new StringBuilder(); remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------"); - remoteServiceErrorInfoBuilder.AppendLine( _jsonSerializer.Serialize(remoteServiceErrorInfo, indented: true)); - Logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString()); + remoteServiceErrorInfoBuilder.AppendLine(context.GetRequiredService().Serialize(remoteServiceErrorInfo, indented: true)); + + var logger = context.GetService>(NullLogger.Instance); + + logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString()); - Logger.LogException(context.Exception, logLevel); + logger.LogException(context.Exception, logLevel); - await context.HttpContext - .RequestServices - .GetRequiredService() - .NotifyAsync( - new ExceptionNotificationContext(context.Exception) - ); + await context.GetRequiredService().NotifyAsync(new ExceptionNotificationContext(context.Exception)); context.Exception = null; //Handled! } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs index 9ef0378909..f3666d2f91 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs @@ -5,7 +5,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Filters; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; @@ -19,27 +18,6 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling { public class AbpExceptionPageFilter : IAsyncPageFilter, ITransientDependency { - public ILogger Logger { get; set; } - - private readonly IExceptionToErrorInfoConverter _errorInfoConverter; - private readonly IHttpExceptionStatusCodeFinder _statusCodeFinder; - private readonly IJsonSerializer _jsonSerializer; - private readonly AbpExceptionHandlingOptions _exceptionHandlingOptions; - - public AbpExceptionPageFilter( - IExceptionToErrorInfoConverter errorInfoConverter, - IHttpExceptionStatusCodeFinder statusCodeFinder, - IJsonSerializer jsonSerializer, - IOptions exceptionHandlingOptions) - { - _errorInfoConverter = errorInfoConverter; - _statusCodeFinder = statusCodeFinder; - _jsonSerializer = jsonSerializer; - _exceptionHandlingOptions = exceptionHandlingOptions.Value; - - Logger = NullLogger.Instance; - } - public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) { return Task.CompletedTask; @@ -90,9 +68,13 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling //TODO: Trigger an AbpExceptionHandled event or something like that. context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true"); - context.HttpContext.Response.StatusCode = (int)_statusCodeFinder.GetStatusCode(context.HttpContext, context.Exception); + context.HttpContext.Response.StatusCode = (int) context + .GetRequiredService() + .GetStatusCode(context.HttpContext, context.Exception); - var remoteServiceErrorInfo = _errorInfoConverter.Convert(context.Exception, _exceptionHandlingOptions.SendExceptionsDetailsToClients); + var exceptionHandlingOptions = context.GetRequiredService>().Value; + var exceptionToErrorInfoConverter = context.GetRequiredService(); + var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, exceptionHandlingOptions.SendExceptionsDetailsToClients); context.Result = new ObjectResult(new RemoteServiceErrorResponse(remoteServiceErrorInfo)); @@ -100,17 +82,14 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling var remoteServiceErrorInfoBuilder = new StringBuilder(); remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------"); - remoteServiceErrorInfoBuilder.AppendLine( _jsonSerializer.Serialize(remoteServiceErrorInfo, indented: true)); - Logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString()); + remoteServiceErrorInfoBuilder.AppendLine(context.GetRequiredService().Serialize(remoteServiceErrorInfo, indented: true)); + + var logger = context.GetService>(NullLogger.Instance); + logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString()); - Logger.LogException(context.Exception, logLevel); + logger.LogException(context.Exception, logLevel); - await context.HttpContext - .RequestServices - .GetRequiredService() - .NotifyAsync( - new ExceptionNotificationContext(context.Exception) - ); + await context.GetRequiredService().NotifyAsync(new ExceptionNotificationContext(context.Exception)); context.Exception = null; //Handled! } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeatureActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeatureActionFilter.cs index 577acda339..2d468b30d9 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeatureActionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeatureActionFilter.cs @@ -1,5 +1,4 @@ using Microsoft.AspNetCore.Mvc.Filters; -using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Abstractions; using Volo.Abp.Aspects; @@ -10,16 +9,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Features { public class AbpFeatureActionFilter : IAsyncActionFilter, ITransientDependency { - private readonly IMethodInvocationFeatureCheckerService _methodInvocationAuthorizationService; - - public AbpFeatureActionFilter(IMethodInvocationFeatureCheckerService methodInvocationAuthorizationService) - { - _methodInvocationAuthorizationService = methodInvocationAuthorizationService; - } - - public async Task OnActionExecutionAsync( - ActionExecutingContext context, - ActionExecutionDelegate next) + public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { if (!context.ActionDescriptor.IsControllerAction()) { @@ -31,9 +21,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Features using (AbpCrossCuttingConcerns.Applying(context.Controller, AbpCrossCuttingConcerns.FeatureChecking)) { - await _methodInvocationAuthorizationService.CheckAsync( - new MethodInvocationFeatureCheckerContext(methodInfo) - ); + var methodInvocationFeatureCheckerService = context.GetRequiredService(); + await methodInvocationFeatureCheckerService.CheckAsync(new MethodInvocationFeatureCheckerContext(methodInfo)); await next(); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs index 83e26ace9c..913716ab33 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs @@ -9,18 +9,11 @@ namespace Volo.Abp.AspNetCore.Mvc.Features { public class AbpFeaturePageFilter : IAsyncPageFilter, ITransientDependency { - private readonly IMethodInvocationFeatureCheckerService _methodInvocationAuthorizationService; - - public AbpFeaturePageFilter(IMethodInvocationFeatureCheckerService methodInvocationAuthorizationService) - { - _methodInvocationAuthorizationService = methodInvocationAuthorizationService; - } - public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) { return Task.CompletedTask; } - + public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) { if (context.HandlerMethod == null || !context.ActionDescriptor.IsPageAction()) @@ -33,12 +26,11 @@ namespace Volo.Abp.AspNetCore.Mvc.Features using (AbpCrossCuttingConcerns.Applying(context.HandlerInstance, AbpCrossCuttingConcerns.FeatureChecking)) { - await _methodInvocationAuthorizationService.CheckAsync( - new MethodInvocationFeatureCheckerContext(methodInfo) - ); + var methodInvocationFeatureCheckerService = context.GetRequiredService(); + await methodInvocationFeatureCheckerService.CheckAsync(new MethodInvocationFeatureCheckerContext(methodInfo)); await next(); } } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeatureActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeatureActionFilter.cs index e3fa489115..9498b31a3f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeatureActionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeatureActionFilter.cs @@ -13,13 +13,6 @@ namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures { public class GlobalFeatureActionFilter : IAsyncActionFilter, ITransientDependency { - public ILogger Logger { get; set; } - - public GlobalFeatureActionFilter() - { - Logger = NullLogger.Instance; - } - public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { if (!context.ActionDescriptor.IsControllerAction()) @@ -30,7 +23,8 @@ namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures if (!IsGlobalFeatureEnabled(context.Controller.GetType(), out var attribute)) { - Logger.LogWarning($"The '{context.Controller.GetType().FullName}' controller needs to enable '{attribute.Name}' feature."); + var logger = context.GetService>(NullLogger.Instance); + logger.LogWarning($"The '{context.Controller.GetType().FullName}' controller needs to enable '{attribute.Name}' feature."); context.Result = new NotFoundResult(); return; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeaturePageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeaturePageFilter.cs index d29c44b4af..a3415f6be8 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeaturePageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeaturePageFilter.cs @@ -13,13 +13,6 @@ namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures { public class GlobalFeaturePageFilter: IAsyncPageFilter, ITransientDependency { - public ILogger Logger { get; set; } - - public GlobalFeaturePageFilter() - { - Logger = NullLogger.Instance; - } - public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) { return Task.CompletedTask; @@ -35,7 +28,8 @@ namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures if (!IsGlobalFeatureEnabled(context.HandlerInstance.GetType(), out var attribute)) { - Logger.LogWarning($"The '{context.HandlerInstance.GetType().FullName}' page needs to enable '{attribute.Name}' feature."); + var logger = context.GetService>(NullLogger.Instance); + logger.LogWarning($"The '{context.HandlerInstance.GetType().FullName}' page needs to enable '{attribute.Name}' feature."); context.Result = new NotFoundResult(); return; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonInputFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonInputFormatter.cs index bd2ade69ad..8c0277321e 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonInputFormatter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonInputFormatter.cs @@ -8,8 +8,14 @@ namespace Volo.Abp.AspNetCore.Mvc.Json { public class AbpHybridJsonInputFormatter : TextInputFormatter, IInputFormatterExceptionPolicy { - public AbpHybridJsonInputFormatter() + private readonly SystemTextJsonInputFormatter _systemTextJsonInputFormatter; + private readonly NewtonsoftJsonInputFormatter _newtonsoftJsonInputFormatter; + + public AbpHybridJsonInputFormatter(SystemTextJsonInputFormatter systemTextJsonInputFormatter, NewtonsoftJsonInputFormatter newtonsoftJsonInputFormatter) { + _systemTextJsonInputFormatter = systemTextJsonInputFormatter; + _newtonsoftJsonInputFormatter = newtonsoftJsonInputFormatter; + SupportedEncodings.Add(UTF8EncodingWithoutBOM); SupportedEncodings.Add(UTF16EncodingLittleEndian); @@ -18,7 +24,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Json SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationAnyJsonSyntax); } - public async override Task ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding) + public override async Task ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding) { return await GetTextInputFormatter(context).ReadRequestBodyAsync(context, encoding); } @@ -26,12 +32,13 @@ namespace Volo.Abp.AspNetCore.Mvc.Json protected virtual TextInputFormatter GetTextInputFormatter(InputFormatterContext context) { var typesMatcher = context.HttpContext.RequestServices.GetRequiredService(); + if (!typesMatcher.Match(context.ModelType)) { - return context.HttpContext.RequestServices.GetRequiredService(); + return _systemTextJsonInputFormatter; } - return context.HttpContext.RequestServices.GetRequiredService(); + return _newtonsoftJsonInputFormatter; } public virtual InputFormatterExceptionPolicy ExceptionPolicy => InputFormatterExceptionPolicy.MalformedInputExceptions; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOptionsSetup.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOptionsSetup.cs new file mode 100644 index 0000000000..c0987e8f76 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOptionsSetup.cs @@ -0,0 +1,73 @@ +using System.Buffers; +using System.Text.Encodings.Web; +using System.Text.Json; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Formatters; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.ObjectPool; +using Microsoft.Extensions.Options; + +namespace Volo.Abp.AspNetCore.Mvc.Json +{ + public class AbpHybridJsonOptionsSetup : IConfigureOptions + { + private readonly IOptions _jsonOptions; + private readonly IOptions _mvcNewtonsoftJsonOptions; + private readonly ILoggerFactory _loggerFactory; + private readonly ArrayPool _charPool; + private readonly ObjectPoolProvider _objectPoolProvider; + + public AbpHybridJsonOptionsSetup( + IOptions jsonOptions, + IOptions mvcNewtonsoftJsonOptions, + ILoggerFactory loggerFactory, + ArrayPool charPool, + ObjectPoolProvider objectPoolProvider) + { + _jsonOptions = jsonOptions; + _mvcNewtonsoftJsonOptions = mvcNewtonsoftJsonOptions; + _loggerFactory = loggerFactory; + _charPool = charPool; + _objectPoolProvider = objectPoolProvider; + } + + public void Configure(MvcOptions options) + { + var systemTextJsonInputFormatter = new SystemTextJsonInputFormatter( + _jsonOptions.Value, + _loggerFactory.CreateLogger()); + + var newtonsoftJsonInputFormatter = new NewtonsoftJsonInputFormatter( + _loggerFactory.CreateLogger(), + _mvcNewtonsoftJsonOptions.Value.SerializerSettings, + _charPool, + _objectPoolProvider, + options, + _mvcNewtonsoftJsonOptions.Value); + + options.InputFormatters.RemoveType(); + options.InputFormatters.RemoveType(); + options.InputFormatters.Add(new AbpHybridJsonInputFormatter(systemTextJsonInputFormatter, newtonsoftJsonInputFormatter)); + + var jsonSerializerOptions = _jsonOptions.Value.JsonSerializerOptions; + if (jsonSerializerOptions.Encoder is null) + { + // If the user hasn't explicitly configured the encoder, use the less strict encoder that does not encode all non-ASCII characters. + jsonSerializerOptions = new JsonSerializerOptions(jsonSerializerOptions) + { + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + }; + } + + var systemTextJsonOutputFormatter = new SystemTextJsonOutputFormatter(jsonSerializerOptions); + var newtonsoftJsonOutputFormatter = new NewtonsoftJsonOutputFormatter( + _mvcNewtonsoftJsonOptions.Value.SerializerSettings, + _charPool, + options); + + options.OutputFormatters.RemoveType(); + options.OutputFormatters.RemoveType(); + options.OutputFormatters.Add(new AbpHybridJsonOutputFormatter(systemTextJsonOutputFormatter, newtonsoftJsonOutputFormatter)); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOutputFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOutputFormatter.cs index 1507457f08..1dcd5d0fac 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOutputFormatter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/AbpHybridJsonOutputFormatter.cs @@ -8,8 +8,14 @@ namespace Volo.Abp.AspNetCore.Mvc.Json { public class AbpHybridJsonOutputFormatter : TextOutputFormatter { - public AbpHybridJsonOutputFormatter() + private readonly SystemTextJsonOutputFormatter _systemTextJsonOutputFormatter; + private readonly NewtonsoftJsonOutputFormatter _newtonsoftJsonOutputFormatter; + + public AbpHybridJsonOutputFormatter(SystemTextJsonOutputFormatter systemTextJsonOutputFormatter, NewtonsoftJsonOutputFormatter newtonsoftJsonOutputFormatter) { + _systemTextJsonOutputFormatter = systemTextJsonOutputFormatter; + _newtonsoftJsonOutputFormatter = newtonsoftJsonOutputFormatter; + SupportedEncodings.Add(Encoding.UTF8); SupportedEncodings.Add(Encoding.Unicode); @@ -18,7 +24,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Json SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationAnyJsonSyntax); } - public async override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) + public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) { await GetTextInputFormatter(context).WriteResponseBodyAsync(context, selectedEncoding); } @@ -28,10 +34,10 @@ namespace Volo.Abp.AspNetCore.Mvc.Json var typesMatcher = context.HttpContext.RequestServices.GetRequiredService(); if (!typesMatcher.Match(context.ObjectType)) { - return context.HttpContext.RequestServices.GetRequiredService(); + return _systemTextJsonOutputFormatter; } - return context.HttpContext.RequestServices.GetRequiredService(); + return _newtonsoftJsonOutputFormatter; } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs index b4e19e6ae7..366a24e8f4 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs @@ -1,12 +1,7 @@ -using System.Buffers; -using System.Text.Json; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Formatters; +using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; -using System.Text.Encodings.Web; -using Microsoft.Extensions.Logging; using Microsoft.Extensions.ObjectPool; using Volo.Abp.Json; @@ -24,68 +19,10 @@ namespace Volo.Abp.AspNetCore.Mvc.Json return builder; } - //SystemTextJsonInputFormatter - builder.Services.AddTransient(provider => - { - var jsonOptions = provider.GetRequiredService>(); - var logger = provider.GetRequiredService().CreateLogger(); - return new SystemTextJsonInputFormatter(jsonOptions.Value, logger); - }); - builder.Services.TryAddTransient(); - //NewtonsoftJsonInputFormatter - builder.Services.AddTransient(provider => - { - var jsonOptions = provider.GetRequiredService>().Value; - - return new NewtonsoftJsonInputFormatter( - provider.GetRequiredService().CreateLogger(), - jsonOptions.SerializerSettings, - provider.GetRequiredService>(), - provider.GetRequiredService(), - provider.GetRequiredService>().Value, - jsonOptions); - }); - - //SystemTextJsonOutputFormatter - builder.Services.AddTransient(provider => - { - var jsonSerializerOptions = provider.GetRequiredService>().Value.JsonSerializerOptions; - if (jsonSerializerOptions.Encoder is null) - { - // If the user hasn't explicitly configured the encoder, use the less strict encoder that does not encode all non-ASCII characters. - jsonSerializerOptions = new JsonSerializerOptions(jsonSerializerOptions) - { - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - }; - } - return new SystemTextJsonOutputFormatter(jsonSerializerOptions); - }); - - //NewtonsoftJsonOutputFormatter - builder.Services.AddTransient(provider => - { - var jsonOptions = provider.GetRequiredService>().Value; - return new NewtonsoftJsonOutputFormatter( - jsonOptions.SerializerSettings, - provider.GetRequiredService>(), - provider.GetRequiredService>().Value); - }); - builder.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpJsonOptionsSetup>()); builder.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpMvcNewtonsoftJsonOptionsSetup>()); - - builder.Services.Configure(options => - { - options.InputFormatters.RemoveType(); - options.InputFormatters.RemoveType(); - options.InputFormatters.Add(new AbpHybridJsonInputFormatter()); - - options.OutputFormatters.RemoveType(); - options.OutputFormatters.RemoveType(); - options.OutputFormatters.Add(new AbpHybridJsonOutputFormatter()); - }); - + builder.Services.TryAddEnumerable(ServiceDescriptor.Transient, AbpHybridJsonOptionsSetup>()); return builder; } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs index 43dedf916f..95a961b814 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Abstractions; @@ -12,15 +12,6 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow { public class AbpUowActionFilter : IAsyncActionFilter, ITransientDependency { - private readonly IUnitOfWorkManager _unitOfWorkManager; - private readonly AbpUnitOfWorkDefaultOptions _defaultOptions; - - public AbpUowActionFilter(IUnitOfWorkManager unitOfWorkManager, IOptions options) - { - _unitOfWorkManager = unitOfWorkManager; - _defaultOptions = options.Value; - } - public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { if (!context.ActionDescriptor.IsControllerAction()) @@ -45,20 +36,22 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow var options = CreateOptions(context, unitOfWorkAttr); + var unitOfWorkManager = context.GetRequiredService(); + //Trying to begin a reserved UOW by AbpUnitOfWorkMiddleware - if (_unitOfWorkManager.TryBeginReserved(UnitOfWork.UnitOfWorkReservationName, options)) + if (unitOfWorkManager.TryBeginReserved(UnitOfWork.UnitOfWorkReservationName, options)) { var result = await next(); if (!Succeed(result)) { - await RollbackAsync(context); + await RollbackAsync(context, unitOfWorkManager); } return; } //Begin a new, independent unit of work - using (var uow = _unitOfWorkManager.Begin(options)) + using (var uow = unitOfWorkManager.Begin(options)) { var result = await next(); if (Succeed(result)) @@ -76,7 +69,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow if (unitOfWorkAttribute?.IsTransactional == null) { - options.IsTransactional = _defaultOptions.CalculateIsTransactional( + var abpUnitOfWorkDefaultOptions = context.GetRequiredService>().Value; + options.IsTransactional = abpUnitOfWorkDefaultOptions.CalculateIsTransactional( autoValue: !string.Equals(context.HttpContext.Request.Method, HttpMethod.Get.Method, StringComparison.OrdinalIgnoreCase) ); } @@ -84,9 +78,9 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow return options; } - private async Task RollbackAsync(ActionExecutingContext context) + private async Task RollbackAsync(ActionExecutingContext context, IUnitOfWorkManager unitOfWorkManager) { - var currentUow = _unitOfWorkManager.Current; + var currentUow = unitOfWorkManager.Current; if (currentUow != null) { await currentUow.RollbackAsync(context.HttpContext.RequestAborted); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs index 960c47b591..30c713940f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Abstractions; @@ -12,14 +12,6 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow { public class AbpUowPageFilter : IAsyncPageFilter, ITransientDependency { - private readonly IUnitOfWorkManager _unitOfWorkManager; - private readonly AbpUnitOfWorkDefaultOptions _defaultOptions; - - public AbpUowPageFilter(IUnitOfWorkManager unitOfWorkManager, IOptions options) - { - _unitOfWorkManager = unitOfWorkManager; - _defaultOptions = options.Value; - } public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) { return Task.CompletedTask; @@ -49,20 +41,22 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow var options = CreateOptions(context, unitOfWorkAttr); + var unitOfWorkManager = context.GetRequiredService(); + //Trying to begin a reserved UOW by AbpUnitOfWorkMiddleware - if (_unitOfWorkManager.TryBeginReserved(UnitOfWork.UnitOfWorkReservationName, options)) + if (unitOfWorkManager.TryBeginReserved(UnitOfWork.UnitOfWorkReservationName, options)) { var result = await next(); if (!Succeed(result)) { - await RollbackAsync(context); + await RollbackAsync(context, unitOfWorkManager); } return; } //Begin a new, independent unit of work - using (var uow = _unitOfWorkManager.Begin(options)) + using (var uow = unitOfWorkManager.Begin(options)) { var result = await next(); if (Succeed(result)) @@ -80,7 +74,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow if (unitOfWorkAttribute?.IsTransactional == null) { - options.IsTransactional = _defaultOptions.CalculateIsTransactional( + var abpUnitOfWorkDefaultOptions = context.GetRequiredService>().Value; + options.IsTransactional = abpUnitOfWorkDefaultOptions.CalculateIsTransactional( autoValue: !string.Equals(context.HttpContext.Request.Method, HttpMethod.Get.Method, StringComparison.OrdinalIgnoreCase) ); } @@ -88,9 +83,9 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow return options; } - private async Task RollbackAsync(PageHandlerExecutingContext context) + private async Task RollbackAsync(PageHandlerExecutingContext context, IUnitOfWorkManager unitOfWorkManager) { - var currentUow = _unitOfWorkManager.Current; + var currentUow = unitOfWorkManager.Current; if (currentUow != null) { await currentUow.RollbackAsync(context.HttpContext.RequestAborted); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs index 8fe699f4ba..751afe84d0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs @@ -7,13 +7,6 @@ namespace Volo.Abp.AspNetCore.Mvc.Validation { public class AbpValidationActionFilter : IAsyncActionFilter, ITransientDependency { - private readonly IModelStateValidator _validator; - - public AbpValidationActionFilter(IModelStateValidator validator) - { - _validator = validator; - } - public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { //TODO: Configuration to disable validation for controllers..? @@ -25,7 +18,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Validation return; } - _validator.Validate(context.ModelState); + context.GetRequiredService().Validate(context.ModelState); await next(); } } diff --git a/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpHub.cs b/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpHub.cs index 4e23a4cb41..a9d9316f41 100644 --- a/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpHub.cs +++ b/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpHub.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.DependencyInjection; using Volo.Abp.Localization; using Volo.Abp.MultiTenancy; using Volo.Abp.Timing; @@ -14,48 +15,23 @@ namespace Volo.Abp.AspNetCore.SignalR { public abstract class AbpHub : Hub { - public IServiceProvider ServiceProvider { get; set; } - protected readonly object ServiceProviderLock = new object(); - - protected TService LazyGetRequiredService(ref TService reference) - => LazyGetRequiredService(typeof(TService), ref reference); - - protected TRef LazyGetRequiredService(Type serviceType, ref TRef reference) - { - if (reference == null) - { - lock (ServiceProviderLock) - { - if (reference == null) - { - reference = (TRef)ServiceProvider.GetRequiredService(serviceType); - } - } - } + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } - return reference; - } + public IServiceProvider ServiceProvider { get; set; } - protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); - private ILoggerFactory _loggerFactory; + protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetService(); - protected ILogger Logger => _lazyLogger.Value; - private Lazy _lazyLogger => new Lazy(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true); + protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance); - protected ICurrentUser CurrentUser => LazyGetRequiredService(ref _currentUser); - private ICurrentUser _currentUser; + protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetService(); - protected ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant); - private ICurrentTenant _currentTenant; + protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetService(); - protected IAuthorizationService AuthorizationService => LazyGetRequiredService(ref _authorizationService); - private IAuthorizationService _authorizationService; + protected IAuthorizationService AuthorizationService => LazyServiceProvider.LazyGetService(); - protected IClock Clock => LazyGetRequiredService(ref _clock); - private IClock _clock; + protected IClock Clock => LazyServiceProvider.LazyGetService(); - protected IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(ref _stringLocalizerFactory); - private IStringLocalizerFactory _stringLocalizerFactory; + protected IStringLocalizerFactory StringLocalizerFactory => LazyServiceProvider.LazyGetService(); protected IStringLocalizer L { @@ -102,48 +78,23 @@ namespace Volo.Abp.AspNetCore.SignalR public abstract class AbpHub : Hub where T : class { - public IServiceProvider ServiceProvider { get; set; } - protected readonly object ServiceProviderLock = new object(); - - protected TService LazyGetRequiredService(ref TService reference) - => LazyGetRequiredService(typeof(TService), ref reference); - - protected TRef LazyGetRequiredService(Type serviceType, ref TRef reference) - { - if (reference == null) - { - lock (ServiceProviderLock) - { - if (reference == null) - { - reference = (TRef)ServiceProvider.GetRequiredService(serviceType); - } - } - } + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } - return reference; - } + public IServiceProvider ServiceProvider { get; set; } - protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); - private ILoggerFactory _loggerFactory; + protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetService(); - protected ILogger Logger => _lazyLogger.Value; - private Lazy _lazyLogger => new Lazy(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true); + protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance); - protected ICurrentUser CurrentUser => LazyGetRequiredService(ref _currentUser); - private ICurrentUser _currentUser; + protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetService(); - protected ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant); - private ICurrentTenant _currentTenant; + protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetService(); - protected IAuthorizationService AuthorizationService => LazyGetRequiredService(ref _authorizationService); - private IAuthorizationService _authorizationService; + protected IAuthorizationService AuthorizationService => LazyServiceProvider.LazyGetService(); - protected IClock Clock => LazyGetRequiredService(ref _clock); - private IClock _clock; + protected IClock Clock => LazyServiceProvider.LazyGetService(); - protected IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(ref _stringLocalizerFactory); - private IStringLocalizerFactory _stringLocalizerFactory; + protected IStringLocalizerFactory StringLocalizerFactory => LazyServiceProvider.LazyGetService(); protected IStringLocalizer L { diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/SecurityLog/AspNetCoreSecurityLogManager.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/SecurityLog/AspNetCoreSecurityLogManager.cs index b518c5abbb..f0fc0aa347 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/SecurityLog/AspNetCoreSecurityLogManager.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/SecurityLog/AspNetCoreSecurityLogManager.cs @@ -48,7 +48,7 @@ namespace Volo.Abp.AspNetCore.SecurityLog WebClientInfoProvider = webClientInfoProvider; } - protected async override Task CreateAsync() + protected override async Task CreateAsync() { var securityLogInfo = await base.CreateAsync(); diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs index 0eef78ed6a..9142db5617 100644 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Aspects; using Volo.Abp.DependencyInjection; using Volo.Abp.DynamicProxy; @@ -9,16 +10,14 @@ namespace Volo.Abp.Auditing { public class AuditingInterceptor : AbpInterceptor, ITransientDependency { - private readonly IAuditingHelper _auditingHelper; - private readonly IAuditingManager _auditingManager; + private readonly IServiceScopeFactory _serviceScopeFactory; - public AuditingInterceptor(IAuditingHelper auditingHelper, IAuditingManager auditingManager) + public AuditingInterceptor(IServiceScopeFactory serviceScopeFactory) { - _auditingHelper = auditingHelper; - _auditingManager = auditingManager; + _serviceScopeFactory = serviceScopeFactory; } - public async override Task InterceptAsync(IAbpMethodInvocation invocation) + public override async Task InterceptAsync(IAbpMethodInvocation invocation) { if (!ShouldIntercept(invocation, out var auditLog, out var auditLogAction)) { @@ -58,26 +57,31 @@ namespace Volo.Abp.Auditing return false; } - var auditLogScope = _auditingManager.Current; - if (auditLogScope == null) + using (var scope = _serviceScopeFactory.CreateScope()) { - return false; - } + var auditingManager = scope.ServiceProvider.GetRequiredService(); + var auditLogScope = auditingManager.Current; + if (auditLogScope == null) + { + return false; + } - if (!_auditingHelper.ShouldSaveAudit(invocation.Method)) - { - return false; - } + var auditingHelper = scope.ServiceProvider.GetRequiredService(); + if (!auditingHelper.ShouldSaveAudit(invocation.Method)) + { + return false; + } - auditLog = auditLogScope.Log; - auditLogAction = _auditingHelper.CreateAuditLogAction( - auditLog, - invocation.TargetObject.GetType(), - invocation.Method, - invocation.Arguments - ); + auditLog = auditLogScope.Log; + auditLogAction = auditingHelper.CreateAuditLogAction( + auditLog, + invocation.TargetObject.GetType(), + invocation.Method, + invocation.Arguments + ); - return true; + return true; + } } } } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationPolicyProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationPolicyProvider.cs index f889251c69..f636877fc1 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationPolicyProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationPolicyProvider.cs @@ -23,7 +23,7 @@ namespace Volo.Abp.Authorization _options = options.Value; } - public async override Task GetPolicyAsync(string policyName) + public override async Task GetPolicyAsync(string policyName) { var policy = await base.GetPolicyAsync(policyName); if (policy != null) diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptor.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptor.cs index 82f4adeabe..44466884dd 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptor.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptor.cs @@ -13,7 +13,7 @@ namespace Volo.Abp.Authorization _methodInvocationAuthorizationService = methodInvocationAuthorizationService; } - public async override Task InterceptAsync(IAbpMethodInvocation invocation) + public override async Task InterceptAsync(IAbpMethodInvocation invocation) { await AuthorizeAsync(invocation); await invocation.ProceedAsync(); diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/nl.json b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/nl.json new file mode 100644 index 0000000000..6be7515c01 --- /dev/null +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/nl.json @@ -0,0 +1,10 @@ +{ + "culture": "nl", + "texts": { + "Volo.Authorization:010001": "Autorisatie mislukt! De benodigde policy is niet aan u verleend.", + "Volo.Authorization:010002": "Autorisatie mislukt! De benodigde policy: '{PolicyName}' is niet aan u verleend.", + "Volo.Authorization:010003": "Autorisatie mislukt! De benodigde policy is niet aan de opgegeven resource: '{ResourceName}' verleend.", + "Volo.Authorization:010004": "Autorisatie mislukt! De benodigde requirement is niet aan de opgegeven resource: '{ResourceName}' verleend.", + "Volo.Authorization:010005": "Autorisatie mislukt! De benodigde requirements zijn niet aan de opgegeven resource: '{ResourceName}' verleend." + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs index fb35d142cb..c00c652500 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs @@ -36,7 +36,7 @@ namespace Volo.Abp.Authorization { return; } - + await _abpAuthorizationService.CheckAsync(authorizationPolicy); } @@ -64,4 +64,4 @@ namespace Volo.Abp.Authorization return attributes; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/PermissionRequirementHandler.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/PermissionRequirementHandler.cs index b0446f5602..d4ec7c1d3c 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/PermissionRequirementHandler.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/PermissionRequirementHandler.cs @@ -13,7 +13,7 @@ namespace Volo.Abp.Authorization _permissionChecker = permissionChecker; } - protected async override Task HandleRequirementAsync( + protected override async Task HandleRequirementAsync( AuthorizationHandlerContext context, PermissionRequirement requirement) { diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs index ac76733524..6e14b304e3 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/ClientPermissionValueProvider.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.Authorization.Permissions CurrentTenant = currentTenant; } - public async override Task CheckAsync(PermissionValueCheckContext context) + public override async Task CheckAsync(PermissionValueCheckContext context) { var clientId = context.Principal?.FindFirst(AbpClaimTypes.ClientId)?.Value; @@ -36,7 +36,7 @@ namespace Volo.Abp.Authorization.Permissions } } - public async override Task CheckAsync(PermissionValuesCheckContext context) + public override async Task CheckAsync(PermissionValuesCheckContext context) { var permissionNames = context.Permissions.Select(x => x.Name).ToArray(); diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs index e3ab7629a2..eec94b3b98 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs @@ -17,7 +17,7 @@ namespace Volo.Abp.Authorization.Permissions } - public async override Task CheckAsync(PermissionValueCheckContext context) + public override async Task CheckAsync(PermissionValueCheckContext context) { var roles = context.Principal?.FindAll(AbpClaimTypes.Role).Select(c => c.Value).ToArray(); @@ -37,7 +37,7 @@ namespace Volo.Abp.Authorization.Permissions return PermissionGrantResult.Undefined; } - public async override Task CheckAsync(PermissionValuesCheckContext context) + public override async Task CheckAsync(PermissionValuesCheckContext context) { var permissionNames = context.Permissions.Select(x => x.Name).ToList(); var result = new MultiplePermissionGrantResult(permissionNames.ToArray()); diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/UserPermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/UserPermissionValueProvider.cs index fcdc25d1e1..c90344371e 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/UserPermissionValueProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/UserPermissionValueProvider.cs @@ -16,7 +16,7 @@ namespace Volo.Abp.Authorization.Permissions } - public async override Task CheckAsync(PermissionValueCheckContext context) + public override async Task CheckAsync(PermissionValueCheckContext context) { var userId = context.Principal?.FindFirst(AbpClaimTypes.UserId)?.Value; @@ -30,7 +30,7 @@ namespace Volo.Abp.Authorization.Permissions : PermissionGrantResult.Undefined; } - public async override Task CheckAsync(PermissionValuesCheckContext context) + public override async Task CheckAsync(PermissionValuesCheckContext context) { var permissionNames = context.Permissions.Select(x => x.Name).ToArray(); diff --git a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs index 2635294323..8eec35d816 100644 --- a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs +++ b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs @@ -30,7 +30,7 @@ namespace Volo.Abp.BackgroundJobs Timer.Period = WorkerOptions.JobPollPeriod; } - protected async override Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext) + protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext) { var store = workerContext.ServiceProvider.GetRequiredService(); diff --git a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/AsyncPeriodicBackgroundWorkerBase.cs b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/AsyncPeriodicBackgroundWorkerBase.cs index 094c6eb7eb..ce4f9b42d7 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/AsyncPeriodicBackgroundWorkerBase.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/AsyncPeriodicBackgroundWorkerBase.cs @@ -22,13 +22,13 @@ namespace Volo.Abp.BackgroundWorkers Timer.Elapsed = Timer_Elapsed; } - public async override Task StartAsync(CancellationToken cancellationToken = default) + public override async Task StartAsync(CancellationToken cancellationToken = default) { await base.StartAsync(cancellationToken); Timer.Start(cancellationToken); } - public async override Task StopAsync(CancellationToken cancellationToken = default) + public override async Task StopAsync(CancellationToken cancellationToken = default) { Timer.Stop(cancellationToken); await base.StopAsync(cancellationToken); diff --git a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerBase.cs b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerBase.cs index bf654cf6a7..85523d7ee9 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerBase.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerBase.cs @@ -1,9 +1,9 @@ using System; using System.Threading; using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.DependencyInjection; namespace Volo.Abp.BackgroundWorkers { @@ -13,33 +13,14 @@ namespace Volo.Abp.BackgroundWorkers public abstract class BackgroundWorkerBase : IBackgroundWorker { //TODO: Add UOW, Localization and other useful properties..? - public IServiceProvider ServiceProvider { get; set; } - protected readonly object ServiceProviderLock = new object(); - protected TService LazyGetRequiredService(ref TService reference) - => LazyGetRequiredService(typeof(TService), ref reference); + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } - protected TRef LazyGetRequiredService(Type serviceType, ref TRef reference) - { - if (reference == null) - { - lock (ServiceProviderLock) - { - if (reference == null) - { - reference = (TRef)ServiceProvider.GetRequiredService(serviceType); - } - } - } - - return reference; - } + public IServiceProvider ServiceProvider { get; set; } - protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); - private ILoggerFactory _loggerFactory; + protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService(); - protected ILogger Logger => _lazyLogger.Value; - private Lazy _lazyLogger => new Lazy(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true); + protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance); public virtual Task StartAsync(CancellationToken cancellationToken = default) { diff --git a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/PeriodicBackgroundWorkerBase.cs b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/PeriodicBackgroundWorkerBase.cs index 6ac757fef5..e89204e81f 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/PeriodicBackgroundWorkerBase.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/PeriodicBackgroundWorkerBase.cs @@ -25,13 +25,13 @@ namespace Volo.Abp.BackgroundWorkers Timer.Elapsed += Timer_Elapsed; } - public async override Task StartAsync(CancellationToken cancellationToken = default) + public override async Task StartAsync(CancellationToken cancellationToken = default) { await base.StartAsync(cancellationToken); Timer.Start(cancellationToken); } - public async override Task StopAsync(CancellationToken cancellationToken = default) + public override async Task StopAsync(CancellationToken cancellationToken = default) { Timer.Stop(cancellationToken); await base.StopAsync(cancellationToken); diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/EntityAction.razor.cs b/framework/src/Volo.Abp.BlazoriseUI/Components/EntityAction.razor.cs index e3e7112afa..7f0edf3b4a 100644 --- a/framework/src/Volo.Abp.BlazoriseUI/Components/EntityAction.razor.cs +++ b/framework/src/Volo.Abp.BlazoriseUI/Components/EntityAction.razor.cs @@ -41,7 +41,7 @@ namespace Volo.Abp.BlazoriseUI.Components [Inject] protected IUiMessageService UiMessageService { get; set; } - protected async override Task OnInitializedAsync() + protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); await SetDefaultValuesAsync(); diff --git a/framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj b/framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj index de793e078f..9405337b89 100644 --- a/framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj +++ b/framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj @@ -12,9 +12,9 @@ - - - + + + diff --git a/framework/src/Volo.Abp.BlobStoring.Aliyun/Volo/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.Aliyun/Volo/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs index d6c9303afd..39e8aff996 100644 --- a/framework/src/Volo.Abp.BlobStoring.Aliyun/Volo/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs +++ b/framework/src/Volo.Abp.BlobStoring.Aliyun/Volo/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs @@ -73,7 +73,7 @@ namespace Volo.Abp.BlobStoring.Aliyun return Task.FromResult(BlobExists(ossClient, containerName, blobName)); } - public async override Task GetOrNullAsync(BlobProviderGetArgs args) + public override async Task GetOrNullAsync(BlobProviderGetArgs args) { var containerName = GetContainerName(args); var blobName = AliyunBlobNameCalculator.Calculate(args); diff --git a/framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/AwsBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/AwsBlobProvider.cs index 191f9a0ac7..dd9c205d8b 100644 --- a/framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/AwsBlobProvider.cs +++ b/framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/AwsBlobProvider.cs @@ -20,7 +20,7 @@ namespace Volo.Abp.BlobStoring.Aws AmazonS3ClientFactory = amazonS3ClientFactory; } - public async override Task SaveAsync(BlobProviderSaveArgs args) + public override async Task SaveAsync(BlobProviderSaveArgs args) { var blobName = AwsBlobNameCalculator.Calculate(args); var configuration = args.Configuration.GetAwsConfiguration(); @@ -48,7 +48,7 @@ namespace Volo.Abp.BlobStoring.Aws } } - public async override Task DeleteAsync(BlobProviderDeleteArgs args) + public override async Task DeleteAsync(BlobProviderDeleteArgs args) { var blobName = AwsBlobNameCalculator.Calculate(args); var containerName = GetContainerName(args); @@ -70,7 +70,7 @@ namespace Volo.Abp.BlobStoring.Aws } } - public async override Task ExistsAsync(BlobProviderExistsArgs args) + public override async Task ExistsAsync(BlobProviderExistsArgs args) { var blobName = AwsBlobNameCalculator.Calculate(args); var containerName = GetContainerName(args); @@ -81,7 +81,7 @@ namespace Volo.Abp.BlobStoring.Aws } } - public async override Task GetOrNullAsync(BlobProviderGetArgs args) + public override async Task GetOrNullAsync(BlobProviderGetArgs args) { var blobName = AwsBlobNameCalculator.Calculate(args); var containerName = GetContainerName(args); diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs index 3a9a062e76..1afc3b6a53 100644 --- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs +++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs @@ -15,7 +15,7 @@ namespace Volo.Abp.BlobStoring.Azure AzureBlobNameCalculator = azureBlobNameCalculator; } - public async override Task SaveAsync(BlobProviderSaveArgs args) + public override async Task SaveAsync(BlobProviderSaveArgs args) { var blobName = AzureBlobNameCalculator.Calculate(args); var configuration = args.Configuration.GetAzureConfiguration(); @@ -33,7 +33,7 @@ namespace Volo.Abp.BlobStoring.Azure await GetBlobClient(args, blobName).UploadAsync(args.BlobStream, true); } - public async override Task DeleteAsync(BlobProviderDeleteArgs args) + public override async Task DeleteAsync(BlobProviderDeleteArgs args) { var blobName = AzureBlobNameCalculator.Calculate(args); @@ -45,14 +45,14 @@ namespace Volo.Abp.BlobStoring.Azure return false; } - public async override Task ExistsAsync(BlobProviderExistsArgs args) + public override async Task ExistsAsync(BlobProviderExistsArgs args) { var blobName = AzureBlobNameCalculator.Calculate(args); return await BlobExistsAsync(args, blobName); } - public async override Task GetOrNullAsync(BlobProviderGetArgs args) + public override async Task GetOrNullAsync(BlobProviderGetArgs args) { var blobName = AzureBlobNameCalculator.Calculate(args); diff --git a/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProvider.cs index 3a512a0ba3..cbfe4bcaf7 100644 --- a/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProvider.cs +++ b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProvider.cs @@ -16,7 +16,7 @@ namespace Volo.Abp.BlobStoring.FileSystem FilePathCalculator = filePathCalculator; } - public async override Task SaveAsync(BlobProviderSaveArgs args) + public override async Task SaveAsync(BlobProviderSaveArgs args) { var filePath = FilePathCalculator.Calculate(args); @@ -59,7 +59,7 @@ namespace Volo.Abp.BlobStoring.FileSystem return ExistsAsync(filePath); } - public async override Task GetOrNullAsync(BlobProviderGetArgs args) + public override async Task GetOrNullAsync(BlobProviderGetArgs args) { var filePath = FilePathCalculator.Calculate(args); diff --git a/framework/src/Volo.Abp.BlobStoring.Minio/Volo/Abp/BlobStoring/Minio/MinioBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.Minio/Volo/Abp/BlobStoring/Minio/MinioBlobProvider.cs index fca23324dc..8e18f9dedb 100644 --- a/framework/src/Volo.Abp.BlobStoring.Minio/Volo/Abp/BlobStoring/Minio/MinioBlobProvider.cs +++ b/framework/src/Volo.Abp.BlobStoring.Minio/Volo/Abp/BlobStoring/Minio/MinioBlobProvider.cs @@ -16,7 +16,7 @@ namespace Volo.Abp.BlobStoring.Minio MinioBlobNameCalculator = minioBlobNameCalculator; } - public async override Task SaveAsync(BlobProviderSaveArgs args) + public override async Task SaveAsync(BlobProviderSaveArgs args) { var blobName = MinioBlobNameCalculator.Calculate(args); var configuration = args.Configuration.GetMinioConfiguration(); @@ -36,7 +36,7 @@ namespace Volo.Abp.BlobStoring.Minio await client.PutObjectAsync(containerName, blobName, args.BlobStream, args.BlobStream.Length); } - public async override Task DeleteAsync(BlobProviderDeleteArgs args) + public override async Task DeleteAsync(BlobProviderDeleteArgs args) { var blobName = MinioBlobNameCalculator.Calculate(args); var client = GetMinioClient(args); @@ -51,7 +51,7 @@ namespace Volo.Abp.BlobStoring.Minio return false; } - public async override Task ExistsAsync(BlobProviderExistsArgs args) + public override async Task ExistsAsync(BlobProviderExistsArgs args) { var blobName = MinioBlobNameCalculator.Calculate(args); var client = GetMinioClient(args); @@ -60,7 +60,7 @@ namespace Volo.Abp.BlobStoring.Minio return await BlobExistsAsync(client, containerName, blobName); } - public async override Task GetOrNullAsync(BlobProviderGetArgs args) + public override async Task GetOrNullAsync(BlobProviderGetArgs args) { var blobName = MinioBlobNameCalculator.Calculate(args); var client = GetMinioClient(args); diff --git a/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs b/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs index 7a99859d3a..433fde192f 100644 --- a/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs +++ b/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs @@ -18,7 +18,7 @@ namespace Volo.Abp.Castle.DynamicProxy Proceed = proceed; } - public async override Task ProceedAsync() + public override async Task ProceedAsync() { await Proceed(Invocation, ProceedInfo); } diff --git a/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterWithReturnValue.cs b/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterWithReturnValue.cs index a0babad231..ef1c0ae54d 100644 --- a/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterWithReturnValue.cs +++ b/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterWithReturnValue.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.Castle.DynamicProxy Proceed = proceed; } - public async override Task ProceedAsync() + public override async Task ProceedAsync() { ReturnValue = await Proceed(Invocation, ProceedInfo); } diff --git a/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAsyncAbpInterceptorAdapter.cs b/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAsyncAbpInterceptorAdapter.cs index 6d08e8f6a6..8a0c4fdd45 100644 --- a/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAsyncAbpInterceptorAdapter.cs +++ b/framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAsyncAbpInterceptorAdapter.cs @@ -15,14 +15,14 @@ namespace Volo.Abp.Castle.DynamicProxy _abpInterceptor = abpInterceptor; } - protected async override Task InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func proceed) + protected override async Task InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func proceed) { await _abpInterceptor.InterceptAsync( new CastleAbpMethodInvocationAdapter(invocation, proceedInfo, proceed) ); } - protected async override Task InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func> proceed) + protected override async Task InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func> proceed) { var adapter = new CastleAbpMethodInvocationAdapterWithReturnValue(invocation, proceedInfo, proceed); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs index c4942d04ab..55247c71bb 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs @@ -64,6 +64,10 @@ namespace Volo.Abp.Cli.Commands { Logger.LogInformation("Template: " + template); } + else + { + template = (await TemplateInfoProvider.GetDefaultAsync()).Name; + } var version = commandLineArgs.Options.GetOrNull(Options.Version.Short, Options.Version.Long); if (version != null) @@ -107,6 +111,12 @@ namespace Volo.Abp.Cli.Commands Logger.LogInformation("UI Framework: " + uiFramework); } + var publicWebSite = uiFramework != UiFramework.None && commandLineArgs.Options.ContainsKey(Options.PublicWebSite.Long); + if (publicWebSite) + { + Logger.LogInformation("Public Web Site: yes"); + } + var mobileApp = GetMobilePreference(commandLineArgs); if (mobileApp != MobileApp.None) { @@ -168,6 +178,7 @@ namespace Volo.Abp.Cli.Commands databaseManagementSystem, uiFramework, mobileApp, + publicWebSite, gitHubAbpLocalRepositoryPath, gitHubVoloLocalRepositoryPath, templateSource, @@ -219,7 +230,8 @@ namespace Volo.Abp.Cli.Commands Logger.LogInformation($"'{projectName}' has been successfully created to '{outputFolder}'"); - if (AppTemplateBase.IsAppTemplate(template ?? (await TemplateInfoProvider.GetDefaultAsync()).Name)) + + if (AppTemplateBase.IsAppTemplate(template)) { var isCommercial = template == AppProTemplate.TemplateName; OpenThanksPage(uiFramework, databaseProvider, isTiered || commandLineArgs.Options.ContainsKey("separate-identity-server"), isCommercial); @@ -489,6 +501,11 @@ namespace Volo.Abp.Cli.Commands public const string Long = "mobile"; } + public static class PublicWebSite + { + public const string Long = "with-public-website"; + } + public static class TemplateSource { public const string Short = "ts"; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/SourceCodeDownloadService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/SourceCodeDownloadService.cs index 28f41e55d8..6306619e56 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/SourceCodeDownloadService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/SourceCodeDownloadService.cs @@ -40,6 +40,7 @@ namespace Volo.Abp.Cli.Commands.Services DatabaseManagementSystem.NotSpecified, UiFramework.NotSpecified, null, + false, gitHubAbpLocalRepositoryPath, gitHubVoloLocalRepositoryPath, null, diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildContextExtensions.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildContextExtensions.cs index e793c77011..80fb6db058 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildContextExtensions.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildContextExtensions.cs @@ -16,5 +16,10 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building return file; } + + public static FileEntry FindFile(this ProjectBuildContext context, string filePath) + { + return context.Files.FirstOrDefault(f => f.Name == filePath); + } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeDbMigratorPublicPortStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeDbMigratorPublicPortStep.cs new file mode 100644 index 0000000000..72e05b74b0 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeDbMigratorPublicPortStep.cs @@ -0,0 +1,15 @@ +using System.Linq; + +namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps +{ + public class ChangeDbMigratorPublicPortStep: ProjectBuildPipelineStep + { + public override void Execute(ProjectBuildContext context) + { + var dbMigratorAppSettings = context.Files + .FirstOrDefault(f => f.Name.Contains("MyCompanyName.MyProjectName.DbMigrator") && f.Name.EndsWith("appsettings.json")); + + dbMigratorAppSettings?.SetContent(dbMigratorAppSettings.Content.Replace("localhost:44304","localhost:44306")); + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangePublicAuthPortStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangePublicAuthPortStep.cs new file mode 100644 index 0000000000..0d33b16309 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangePublicAuthPortStep.cs @@ -0,0 +1,15 @@ +using System.Linq; + +namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps +{ + public class ChangePublicAuthPortStep: ProjectBuildPipelineStep + { + public override void Execute(ProjectBuildContext context) + { + var publicAppSettings = context.Files + .FirstOrDefault(f => f.Name.Contains("MyCompanyName.MyProjectName.Web.Public") && f.Name.EndsWith("appsettings.json")); + + publicAppSettings?.SetContent(publicAppSettings.Content.Replace("localhost:44303","localhost:44305")); + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs new file mode 100644 index 0000000000..4f63d377ea --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveCmsKitStep.cs @@ -0,0 +1,24 @@ +using System.Linq; +using Volo.Abp.Cli.ProjectBuilding.Files; + +namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps +{ + public class RemoveCmsKitStep : ProjectBuildPipelineStep + { + public override void Execute(ProjectBuildContext context) + { + var commonFiles = context.Files.Where(f => + f.Name.EndsWith(".csproj") || + f.Name.EndsWith("Module.cs") || + f.Name.EndsWith("MyProjectNameMigrationsDbContext.cs") || + f.Name.EndsWith("MyProjectNameGlobalFeatureConfigurator.cs") || + (f.Name.EndsWith(".cshtml") && f.Name.Contains("MyCompanyName.MyProjectName.Web.Public")) + ); + + foreach (var file in commonFiles) + { + file.RemoveTemplateCodeIfNot("CMS-KIT"); + } + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveEfCoreDependencyFromPublicStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveEfCoreDependencyFromPublicStep.cs new file mode 100644 index 0000000000..f9e906c902 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveEfCoreDependencyFromPublicStep.cs @@ -0,0 +1,14 @@ +using System.Linq; +using Volo.Abp.Cli.ProjectBuilding.Files; + +namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps +{ + public class RemoveEfCoreDependencyFromPublicStep : ProjectBuildPipelineStep + { + public override void Execute(ProjectBuildContext context) + { + context.Files.FirstOrDefault(f => f.Name.EndsWith("MyCompanyName.MyProjectName.Web.Public.csproj"))?.RemoveTemplateCodeIfNot("EFCORE"); + context.Files.FirstOrDefault(f => f.Name.EndsWith("MyProjectNameWebPublicModule.cs"))?.RemoveTemplateCodeIfNot("EFCORE"); + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveGlobalFeaturesPackageStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveGlobalFeaturesPackageStep.cs new file mode 100644 index 0000000000..06fd565353 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveGlobalFeaturesPackageStep.cs @@ -0,0 +1,14 @@ +using System.Linq; +using Volo.Abp.Cli.ProjectBuilding.Files; + +namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps +{ + public class RemoveGlobalFeaturesPackageStep : ProjectBuildPipelineStep + { + public override void Execute(ProjectBuildContext context) + { + context.Files.FirstOrDefault(f => f.Name.EndsWith("MyCompanyName.MyProjectName.Domain.Shared.csproj"))?.RemoveTemplateCodeIf("CMS-KIT"); + context.Files.FirstOrDefault(f => f.Name.EndsWith("MyProjectNameDomainSharedModule.cs"))?.RemoveTemplateCodeIf("CMS-KIT"); + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs index 7b48c780f1..942dd91067 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs @@ -7,8 +7,8 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps public class RemoveProjectFromSolutionStep : ProjectBuildPipelineStep { private readonly string _projectName; - private readonly string _solutionFilePath; - private readonly string _projectFolderPath; + private string _solutionFilePath; + private string _projectFolderPath; private string ProjectNameWithQuotes => $"\"{_projectName}\""; @@ -18,12 +18,19 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps string projectFolderPath = null) { _projectName = projectName; - _solutionFilePath = solutionFilePath ?? "/aspnet-core/MyCompanyName.MyProjectName.sln"; - _projectFolderPath = projectFolderPath ?? ("/aspnet-core/src/" + projectName); + _solutionFilePath = solutionFilePath; + _projectFolderPath = projectFolderPath; } public override void Execute(ProjectBuildContext context) { + SetSolutionAndProjectPathsIfNull(context); + + if (_solutionFilePath == null || _projectFolderPath == null) + { + return; + } + new RemoveFolderStep(_projectFolderPath).Execute(context); var solutionFile = context.GetFile(_solutionFilePath); solutionFile.NormalizeLineEndings(); @@ -75,5 +82,20 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps return null; } + + private void SetSolutionAndProjectPathsIfNull(ProjectBuildContext context) + { + + if (_solutionFilePath == null) + { + _solutionFilePath = context.FindFile("/aspnet-core/MyCompanyName.MyProjectName.sln")?.Name ?? + context.FindFile("/MyCompanyName.MyProjectName.sln")?.Name; + } + if (_projectFolderPath == null) + { + _projectFolderPath = context.FindFile("/aspnet-core/src/" + _projectName.EnsureEndsWith('/'))?.Name ?? + context.FindFile("/src/" + _projectName.EnsureEndsWith('/'))?.Name; + } + } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemovePublicRedisStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemovePublicRedisStep.cs new file mode 100644 index 0000000000..94056cbf5a --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemovePublicRedisStep.cs @@ -0,0 +1,17 @@ +using System.Linq; +using Volo.Abp.Cli.ProjectBuilding.Files; + +namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps +{ + public class RemovePublicRedisStep : ProjectBuildPipelineStep + { + public override void Execute(ProjectBuildContext context) + { + context.Files.FirstOrDefault(f => f.Name.EndsWith("MyCompanyName.MyProjectName.Web.csproj"))?.RemoveTemplateCodeIfNot("PUBLIC-REDIS"); + context.Files.FirstOrDefault(f => f.Name.EndsWith("MyProjectNameWebModule.cs"))?.RemoveTemplateCodeIfNot("PUBLIC-REDIS"); + context.Files.FirstOrDefault(f => f.Name.EndsWith("MyCompanyName.MyProjectName.HttpApi.HostWithIds.csproj"))?.RemoveTemplateCodeIfNot("PUBLIC-REDIS"); + context.Files.FirstOrDefault(f => f.Name.EndsWith("MyCompanyName.MyProjectName.HttpApi.Host.csproj"))?.RemoveTemplateCodeIfNot("PUBLIC-REDIS"); + context.Files.FirstOrDefault(f => f.Name.EndsWith("MyProjectNameHttpApiHostModule.cs"))?.RemoveTemplateCodeIfNot("PUBLIC-REDIS"); + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/TemplateCodeDeleteStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/TemplateCodeDeleteStep.cs index e673446d9f..8942103873 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/TemplateCodeDeleteStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/TemplateCodeDeleteStep.cs @@ -8,7 +8,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps { foreach (var file in context.Files) { - if (file.Name.EndsWith(".cs")) //TODO: Why only cs! + if (file.Name.EndsWith(".cs") || file.Name.EndsWith(".csproj") || file.Name.EndsWith(".cshtml")) { file.RemoveTemplateCode(); file.RemoveTemplateCodeMarkers(); @@ -16,4 +16,4 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps } } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateProjectBuildPipelineBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateProjectBuildPipelineBuilder.cs index 513c2b4198..7642a7d697 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateProjectBuildPipelineBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateProjectBuildPipelineBuilder.cs @@ -1,6 +1,6 @@ -using System; -using Volo.Abp.Cli.ProjectBuilding.Building.Steps; +using Volo.Abp.Cli.ProjectBuilding.Building.Steps; using Volo.Abp.Cli.ProjectBuilding.Templates.App; +using Volo.Abp.Cli.ProjectBuilding.Templates.Microservice; using Volo.Abp.Cli.ProjectBuilding.Templates.MvcModule; namespace Volo.Abp.Cli.ProjectBuilding.Building @@ -26,19 +26,20 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building pipeline.Steps.Add(new SolutionRenameStep()); if (context.Template.Name == AppProTemplate.TemplateName || + context.Template.Name == MicroserviceProTemplate.TemplateName || context.Template.Name == ModuleProTemplate.TemplateName) { - pipeline.Steps.Add(new LicenseCodeReplaceStep()); + pipeline.Steps.Add(new LicenseCodeReplaceStep()); // todo: move to custom steps? } if (context.Template.Name == AppTemplate.TemplateName || context.Template.Name == AppProTemplate.TemplateName) { - pipeline.Steps.Add(new DatabaseManagementSystemChangeStep()); + pipeline.Steps.Add(new DatabaseManagementSystemChangeStep()); // todo: move to custom steps? } if ((context.BuildArgs.UiFramework == UiFramework.Mvc || context.BuildArgs.UiFramework == UiFramework.Blazor) - && context.BuildArgs.MobileApp == MobileApp.None) + && context.BuildArgs.MobileApp == MobileApp.None && context.Template.Name != MicroserviceProTemplate.TemplateName) { pipeline.Steps.Add(new RemoveRootFolderStep()); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Files/FileEntryExtensions.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Files/FileEntryExtensions.cs index 900948ce9c..91180206bf 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Files/FileEntryExtensions.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Files/FileEntryExtensions.cs @@ -15,7 +15,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Files { RemoveMarkedTemplateCode(file, ""); } - + public static void RemoveTemplateCodeIf(this FileEntry file, string condition) { RemoveByCondition(file, "IF", condition); @@ -68,7 +68,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Files { if (lines[i].Contains(beginMark)) { - while (!lines[i].Contains("") && i < lines.Length) + while (i < lines.Length && !lines[i].Contains("")) { ++i; } @@ -85,4 +85,4 @@ namespace Volo.Abp.Cli.ProjectBuilding.Files file.SetLines(newLines); } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuildArgs.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuildArgs.cs index 1022f5f10e..71ccf96f7a 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuildArgs.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuildArgs.cs @@ -23,6 +23,8 @@ namespace Volo.Abp.Cli.ProjectBuilding public MobileApp? MobileApp { get; set; } + public bool PublicWebSite { get; set; } + [CanBeNull] public string AbpGitHubLocalRepositoryPath { get; set; } @@ -46,6 +48,7 @@ namespace Volo.Abp.Cli.ProjectBuilding DatabaseManagementSystem databaseManagementSystem = DatabaseManagementSystem.NotSpecified, UiFramework uiFramework = UiFramework.NotSpecified, MobileApp? mobileApp = null, + bool publicWebSite = false, [CanBeNull] string abpGitHubLocalRepositoryPath = null, [CanBeNull] string voloGitHubLocalRepositoryPath = null, [CanBeNull] string templateSource = null, @@ -59,6 +62,7 @@ namespace Volo.Abp.Cli.ProjectBuilding DatabaseManagementSystem = databaseManagementSystem; UiFramework = uiFramework; MobileApp = mobileApp; + PublicWebSite = publicWebSite; AbpGitHubLocalRepositoryPath = abpGitHubLocalRepositoryPath; VoloGitHubLocalRepositoryPath = voloGitHubLocalRepositoryPath; TemplateSource = templateSource; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateInfoProvider.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateInfoProvider.cs index 2aefcfd1a9..b9308dd707 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateInfoProvider.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateInfoProvider.cs @@ -8,6 +8,7 @@ using Volo.Abp.Cli.Http; using Volo.Abp.Cli.ProjectBuilding.Building; using Volo.Abp.Cli.ProjectBuilding.Templates.App; using Volo.Abp.Cli.ProjectBuilding.Templates.Console; +using Volo.Abp.Cli.ProjectBuilding.Templates.Microservice; using Volo.Abp.Cli.ProjectBuilding.Templates.MvcModule; using Volo.Abp.Cli.ProjectBuilding.Templates.Wpf; using Volo.Abp.DependencyInjection; @@ -49,6 +50,8 @@ namespace Volo.Abp.Cli.ProjectBuilding return new AppTemplate(); case AppProTemplate.TemplateName: return new AppProTemplate(); + case MicroserviceProTemplate.TemplateName: + return new MicroserviceProTemplate(); case ModuleTemplate.TemplateName: return new ModuleTemplate(); case ModuleProTemplate.TemplateName: diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs index b5976b403f..8f52e03203 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using NuGet.Versioning; +using Volo.Abp.Cli.Commands; using Volo.Abp.Cli.ProjectBuilding.Building; using Volo.Abp.Cli.ProjectBuilding.Building.Steps; @@ -24,11 +26,13 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.App SwitchDatabaseProvider(context, steps); DeleteUnrelatedProjects(context, steps); + ConfigurePublicWebSite(context, steps); RemoveUnnecessaryPorts(context, steps); RandomizeSslPorts(context, steps); RandomizeStringEncryption(context, steps); UpdateNuGetConfig(context, steps); CleanupFolderHierarchy(context, steps); + RemoveMigrations(context, steps); return steps; } @@ -92,6 +96,63 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.App { steps.Add(new RemoveFolderStep(MobileApp.ReactNative.GetFolderName().EnsureStartsWith('/'))); } + + if (!context.BuildArgs.PublicWebSite) + { + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web.Public")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web.Public.Host")); + } + else + { + if (context.BuildArgs.ExtraProperties.ContainsKey(NewCommand.Options.Tiered.Long) || context.BuildArgs.ExtraProperties.ContainsKey("separate-identity-server")) + { + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web.Public")); + } + else + { + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web.Public.Host")); + } + } + } + + private void ConfigurePublicWebSite(ProjectBuildContext context, List steps) + { + if (!context.BuildArgs.PublicWebSite) + { + if (!context.BuildArgs.ExtraProperties.ContainsKey(NewCommand.Options.Tiered.Long) && + !context.BuildArgs.ExtraProperties.ContainsKey("separate-identity-server")) + { + steps.Add(new RemovePublicRedisStep()); + } + + steps.Add(new RemoveCmsKitStep()); + return; + } + + if (context.BuildArgs.ExtraProperties.ContainsKey(NewCommand.Options.Tiered.Long) || context.BuildArgs.ExtraProperties.ContainsKey("separate-identity-server")) + { + steps.Add(new AppTemplateProjectRenameStep("MyCompanyName.MyProjectName.Web.Public.Host","MyCompanyName.MyProjectName.Web.Public")); + steps.Add(new ChangeDbMigratorPublicPortStep()); + } + else if (context.BuildArgs.UiFramework != UiFramework.NotSpecified && context.BuildArgs.UiFramework != UiFramework.Mvc) + { + steps.Add(new ChangePublicAuthPortStep()); + } + + if (context.BuildArgs.DatabaseProvider != DatabaseProvider.NotSpecified || context.BuildArgs.DatabaseProvider != DatabaseProvider.EntityFrameworkCore) + { + steps.Add(new RemoveEfCoreDependencyFromPublicStep()); + } + + // We disabled cms-kit for v4.2 release. + if (true || context.BuildArgs.ExtraProperties.ContainsKey("without-cms-kit")) + { + steps.Add(new RemoveCmsKitStep()); + } + else + { + steps.Add(new RemoveGlobalFeaturesPackageStep()); + } } private static void ConfigureWithoutUi(ProjectBuildContext context, List steps) @@ -216,6 +277,15 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.App steps.Add(new UpdateNuGetConfigStep("/aspnet-core/NuGet.Config")); } + private static void RemoveMigrations(ProjectBuildContext context, List steps) + { + if (string.IsNullOrWhiteSpace(context.BuildArgs.Version) || + SemanticVersion.Parse(context.BuildArgs.Version) > new SemanticVersion(4,1,99)) + { + steps.Add(new RemoveFolderStep("/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/Migrations")); + } + } + private static void CleanupFolderHierarchy(ProjectBuildContext context, List steps) { if (context.BuildArgs.UiFramework == UiFramework.Mvc && context.BuildArgs.MobileApp == MobileApp.None) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceProTemplate.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceProTemplate.cs new file mode 100644 index 0000000000..aef7ffec3b --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceProTemplate.cs @@ -0,0 +1,16 @@ +namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice +{ + public class MicroserviceProTemplate : MicroserviceTemplateBase + { + /// + /// "microservice-pro". + /// + public const string TemplateName = "microservice-pro"; + + public MicroserviceProTemplate() + : base(TemplateName) + { + DocumentUrl = null; // todo: set this + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs new file mode 100644 index 0000000000..13bfe3433e --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs @@ -0,0 +1,74 @@ +using System.Collections.Generic; +using JetBrains.Annotations; +using Volo.Abp.Cli.ProjectBuilding.Building; +using Volo.Abp.Cli.ProjectBuilding.Building.Steps; + +namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice +{ + public abstract class MicroserviceTemplateBase : TemplateInfo + { + protected MicroserviceTemplateBase([NotNull] string name) + : base(name) + { + } + + public override IEnumerable GetCustomSteps(ProjectBuildContext context) + { + var steps = new List(); + + DeleteUnrelatedProjects(context, steps); + RandomizeStringEncryption(context, steps); + UpdateNuGetConfig(context, steps); + + return steps; + } + + private static void DeleteUnrelatedProjects(ProjectBuildContext context, List steps) + { + switch (context.BuildArgs.UiFramework) + { + case UiFramework.None: + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.WebGateway")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor")); + steps.Add(new RemoveFolderStep("/angular")); + break; + + case UiFramework.Angular: + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.WebGateway")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor")); + break; + + + case UiFramework.Blazor: + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.WebGateway")); + steps.Add(new RemoveFolderStep("/angular")); + break; + + case UiFramework.Mvc: + case UiFramework.NotSpecified: + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor")); + steps.Add(new RemoveFolderStep("/angular")); + break; + } + + if (!context.BuildArgs.PublicWebSite) + { + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.PublicWeb")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.PublicWebGateway")); + } + } + + private static void RandomizeStringEncryption(ProjectBuildContext context, List steps) + { + steps.Add(new RandomizeStringEncryptionStep()); + } + + private static void UpdateNuGetConfig(ProjectBuildContext context, List steps) + { + steps.Add(new UpdateNuGetConfigStep("/NuGet.Config")); + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs index 5e8db9a346..ef8385d479 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs @@ -75,7 +75,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Module private static void UpdateNuGetConfig(ProjectBuildContext context, List steps) { - steps.Add(new UpdateNuGetConfigStep("/NuGet.Config")); + steps.Add(new UpdateNuGetConfigStep("/aspnet-core/NuGet.Config")); } private void CleanupFolderHierarchy(ProjectBuildContext context, List steps) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/RemoveUnnecessaryPortsStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/RemoveUnnecessaryPortsStep.cs index 4d44cf0b05..620fc5219e 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/RemoveUnnecessaryPortsStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/RemoveUnnecessaryPortsStep.cs @@ -4,12 +4,19 @@ using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Volo.Abp.Cli.ProjectBuilding.Building; +using Volo.Abp.Cli.ProjectBuilding.Files; namespace Volo.Abp.Cli.ProjectBuilding.Templates { public class RemoveUnnecessaryPortsStep : ProjectBuildPipelineStep { public override void Execute(ProjectBuildContext context) + { + RemoveUnnecessaryDbMigratorClients(context); + RemoveUnnecessaryHttpApiHostPorts(context); + } + + private static void RemoveUnnecessaryHttpApiHostPorts(ProjectBuildContext context) { var httpApiHostAppSettings = context.Files.FirstOrDefault(f => f.Name.EndsWith(".HttpApi.Host/appsettings.json")); @@ -28,6 +35,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates appJson.Property("ClientUrl")?.Remove(); portsToRemoveFromCors.Add("4200"); } + if (context.BuildArgs.UiFramework != UiFramework.Blazor) { portsToRemoveFromCors.Add("44307"); @@ -36,11 +44,33 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates if (appJson["CorsOrigins"] != null) { appJson["CorsOrigins"] = string.Join(",", - appJson["CorsOrigins"].ToString().Split(",").Where(u=> !portsToRemoveFromCors.Any(u.EndsWith)) - ); + appJson["CorsOrigins"].ToString().Split(",").Where(u => !portsToRemoveFromCors.Any(u.EndsWith)) + ); } httpApiHostAppSettings.SetContent(JsonConvert.SerializeObject(appSettingsJson, Formatting.Indented)); } + + private static void RemoveUnnecessaryDbMigratorClients(ProjectBuildContext context) + { + var dbMigratorAppSettings = context.Files + .FirstOrDefault(f => + f.Name.Contains("MyCompanyName.MyProjectName.DbMigrator") && f.Name.EndsWith("appsettings.json")); + + var appSettingsJsonObject = JObject.Parse(dbMigratorAppSettings.Content); + var identityServerJsonObject = (JObject) appSettingsJsonObject["IdentityServer"]; + var clientsJsonObject = (JObject) identityServerJsonObject["Clients"]; + + if (context.BuildArgs.UiFramework != UiFramework.Blazor) + { + clientsJsonObject.Remove("MyProjectName_Blazor"); + } + if (!context.BuildArgs.PublicWebSite) + { + clientsJsonObject.Remove("MyProjectName_Web_Public"); + } + + dbMigratorAppSettings.SetContent(appSettingsJsonObject.ToString(Formatting.Indented)); + } } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs new file mode 100644 index 0000000000..6c27cd212b --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; + +namespace Volo.Abp.DependencyInjection +{ + public class AbpLazyServiceProvider : IAbpLazyServiceProvider, ITransientDependency + { + protected IDictionary CachedServices { get; set; } + + protected IServiceProvider ServiceProvider { get; set; } + + public AbpLazyServiceProvider(IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + CachedServices = new Dictionary(); + } + + public virtual T LazyGetRequiredService() + { + return (T) LazyGetRequiredService(typeof(T)); + } + + public virtual object LazyGetRequiredService(Type serviceType) + { + return CachedServices.GetOrAdd(serviceType, () => ServiceProvider.GetRequiredService(serviceType)); + } + + public virtual T LazyGetService() + { + return (T) LazyGetService(typeof(T)); + } + + public virtual object LazyGetService(Type serviceType) + { + return CachedServices.GetOrAdd(serviceType, () => ServiceProvider.GetService(serviceType)); + } + + public virtual T LazyGetService(T defaultValue) + { + return (T) LazyGetService(typeof(T), defaultValue); + } + + public virtual object LazyGetService(Type serviceType, object defaultValue) + { + return LazyGetService(serviceType) ?? defaultValue; + } + + public virtual T LazyGetService(Func factory) + { + return (T) LazyGetService(typeof(T), factory); + } + + public virtual object LazyGetService(Type serviceType, Func factory) + { + return CachedServices.GetOrAdd(serviceType, () => factory(ServiceProvider)); + } + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs new file mode 100644 index 0000000000..cea6c05ebf --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs @@ -0,0 +1,23 @@ +using System; + +namespace Volo.Abp.DependencyInjection +{ + public interface IAbpLazyServiceProvider + { + T LazyGetRequiredService(); + + object LazyGetRequiredService(Type serviceType); + + T LazyGetService(); + + object LazyGetService(Type serviceType); + + T LazyGetService(T defaultValue); + + object LazyGetService(Type serviceType, object defaultValue); + + object LazyGetService(Type serviceType, Func factory); + + T LazyGetService(Func factory); + } +} diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs index 900343800f..232afb4280 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs @@ -33,86 +33,41 @@ namespace Volo.Abp.Application.Services IAuditingEnabled, ITransientDependency { - public IServiceProvider ServiceProvider { get; set; } - protected readonly object ServiceProviderLock = new object(); - - protected TService LazyGetRequiredService(ref TService reference) - => LazyGetRequiredService(typeof(TService), ref reference); + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } - protected TRef LazyGetRequiredService(Type serviceType, ref TRef reference) - { - if (reference == null) - { - lock (ServiceProviderLock) - { - if (reference == null) - { - reference = (TRef)ServiceProvider.GetRequiredService(serviceType); - } - } - } - - return reference; - } + public IServiceProvider ServiceProvider { get; set; } public static string[] CommonPostfixes { get; set; } = { "AppService", "ApplicationService", "Service" }; public List AppliedCrossCuttingConcerns { get; } = new List(); - protected IUnitOfWorkManager UnitOfWorkManager => LazyGetRequiredService(ref _unitOfWorkManager); - private IUnitOfWorkManager _unitOfWorkManager; - - protected IAsyncQueryableExecuter AsyncExecuter => LazyGetRequiredService(ref _asyncExecuter); - private IAsyncQueryableExecuter _asyncExecuter; + protected IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService(); - protected Type ObjectMapperContext { get; set; } - protected IObjectMapper ObjectMapper - { - get - { - if (_objectMapper != null) - { - return _objectMapper; - } - - if (ObjectMapperContext == null) - { - return LazyGetRequiredService(ref _objectMapper); - } + protected IAsyncQueryableExecuter AsyncExecuter => LazyServiceProvider.LazyGetRequiredService(); - return LazyGetRequiredService( - typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext), - ref _objectMapper - ); - } - } - private IObjectMapper _objectMapper; + protected Type ObjectMapperContext { get; set; } + protected IObjectMapper ObjectMapper => LazyServiceProvider.LazyGetService(provider => + ObjectMapperContext == null + ? provider.GetRequiredService() + : (IObjectMapper) provider.GetRequiredService(typeof(IObjectMapper<>).MakeGenericType(ObjectMapperContext))); - public IGuidGenerator GuidGenerator { get; set; } + public IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance); - protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); - private ILoggerFactory _loggerFactory; + protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService(); - protected ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant); - private ICurrentTenant _currentTenant; + protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService(); - protected ICurrentUser CurrentUser => LazyGetRequiredService(ref _currentUser); - private ICurrentUser _currentUser; + protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService(); - protected ISettingProvider SettingProvider => LazyGetRequiredService(ref _settingProvider); - private ISettingProvider _settingProvider; + protected ISettingProvider SettingProvider => LazyServiceProvider.LazyGetRequiredService(); - protected IClock Clock => LazyGetRequiredService(ref _clock); - private IClock _clock; + protected IClock Clock => LazyServiceProvider.LazyGetRequiredService(); - protected IAuthorizationService AuthorizationService => LazyGetRequiredService(ref _authorizationService); - private IAuthorizationService _authorizationService; + protected IAuthorizationService AuthorizationService => LazyServiceProvider.LazyGetRequiredService(); - protected IFeatureChecker FeatureChecker => LazyGetRequiredService(ref _featureChecker); - private IFeatureChecker _featureChecker; + protected IFeatureChecker FeatureChecker => LazyServiceProvider.LazyGetRequiredService(); - protected IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(ref _stringLocalizerFactory); - private IStringLocalizerFactory _stringLocalizerFactory; + protected IStringLocalizerFactory StringLocalizerFactory => LazyServiceProvider.LazyGetRequiredService(); protected IStringLocalizer L { @@ -141,13 +96,7 @@ namespace Volo.Abp.Application.Services protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current; - protected ILogger Logger => _lazyLogger.Value; - private Lazy _lazyLogger => new Lazy(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true); - - protected ApplicationService() - { - GuidGenerator = SimpleGuidGenerator.Instance; - } + protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance); /// /// Checks for given . diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs index 8bcf98dff1..65c2cc897b 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs @@ -19,21 +19,23 @@ namespace Volo.Abp.Domain.Repositories IUnitOfWorkEnabled where TEntity : class, IEntity { + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } + public IServiceProvider ServiceProvider { get; set; } - public IDataFilter DataFilter { get; set; } + public IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService(); - public ICurrentTenant CurrentTenant { get; set; } + public ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService(); - public IAsyncQueryableExecuter AsyncExecuter { get; set; } + public IAsyncQueryableExecuter AsyncExecuter => LazyServiceProvider.LazyGetRequiredService(); - public IUnitOfWorkManager UnitOfWorkManager { get; set; } + public IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService(); - public ICancellationTokenProvider CancellationTokenProvider { get; set; } + public ICancellationTokenProvider CancellationTokenProvider => LazyServiceProvider.LazyGetService(NullCancellationTokenProvider.Instance); protected BasicRepositoryBase() { - CancellationTokenProvider = NullCancellationTokenProvider.Instance; + } public abstract Task InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default); diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryAsyncExtensions.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryAsyncExtensions.cs index acc1c3a1bd..87f119016d 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryAsyncExtensions.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryAsyncExtensions.cs @@ -26,415 +26,458 @@ namespace Volo.Abp.Domain.Repositories #region Any/All - public static Task AnyAsync( + public static async Task AnyAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AnyAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AnyAsync(queryable, predicate, cancellationToken); } - public static Task AllAsync( + public static async Task AllAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AllAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AllAsync(queryable, predicate, cancellationToken); } #endregion #region Count/LongCount - public static Task CountAsync( + public static async Task CountAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.CountAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.CountAsync(queryable, cancellationToken); } - public static Task CountAsync( + public static async Task CountAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.CountAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.CountAsync(queryable, predicate, cancellationToken); } - public static Task LongCountAsync( + public static async Task LongCountAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.LongCountAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.LongCountAsync(queryable, cancellationToken); } - public static Task LongCountAsync( + public static async Task LongCountAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.LongCountAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.LongCountAsync(queryable, predicate, cancellationToken); } #endregion #region First/FirstOrDefault - public static Task FirstAsync( + public static async Task FirstAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.FirstAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.FirstAsync(queryable, cancellationToken); } - public static Task FirstAsync( + public static async Task FirstAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.FirstAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.FirstAsync(queryable, predicate, cancellationToken); } - public static Task FirstOrDefaultAsync( + public static async Task FirstOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.FirstOrDefaultAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.FirstOrDefaultAsync(queryable, cancellationToken); } - public static Task FirstOrDefaultAsync( + public static async Task FirstOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.FirstOrDefaultAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.FirstOrDefaultAsync(queryable, predicate, cancellationToken); } #endregion #region Last/LastOrDefault - public static Task LastAsync( + public static async Task LastAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.LastAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.LastAsync(queryable, cancellationToken); } - public static Task LastAsync( + public static async Task LastAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.LastAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.LastAsync(queryable, predicate, cancellationToken); } - public static Task LastOrDefaultAsync( + public static async Task LastOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.LastOrDefaultAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.LastOrDefaultAsync(queryable, cancellationToken); } - public static Task LastOrDefaultAsync( + public static async Task LastOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.LastOrDefaultAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.LastOrDefaultAsync(queryable, predicate, cancellationToken); } #endregion #region Single/SingleOrDefault - public static Task SingleAsync( + public static async Task SingleAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SingleAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SingleAsync(queryable, cancellationToken); } - public static Task SingleAsync( + public static async Task SingleAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SingleAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SingleAsync(queryable, predicate, cancellationToken); } - public static Task SingleOrDefaultAsync( + public static async Task SingleOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SingleOrDefaultAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SingleOrDefaultAsync(queryable, cancellationToken); } - public static Task SingleOrDefaultAsync( + public static async Task SingleOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SingleOrDefaultAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SingleOrDefaultAsync(queryable, predicate, cancellationToken); } #endregion #region Min - public static Task MinAsync( + public static async Task MinAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.MinAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.MinAsync(queryable, cancellationToken); } - public static Task MinAsync( + public static async Task MinAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.MinAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.MinAsync(queryable, selector, cancellationToken); } #endregion #region Max - public static Task MaxAsync( + public static async Task MaxAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.MaxAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.MaxAsync(queryable, cancellationToken); } - public static Task MaxAsync( + public static async Task MaxAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.MaxAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.MaxAsync(queryable, selector, cancellationToken); } #endregion #region Sum - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } #endregion #region Average - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } #endregion #region ToList/Array - public static Task> ToListAsync( + public static async Task> ToListAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.ToListAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.ToListAsync(queryable, cancellationToken); } - public static Task ToArrayAsync( + public static async Task ToArrayAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.ToArrayAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.ToArrayAsync(queryable, cancellationToken); } #endregion diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs index 8781fd9547..0b32d54d45 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs @@ -6,9 +6,7 @@ using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; -using Volo.Abp.Data; using Volo.Abp.Domain.Entities; -using Volo.Abp.Linq; using Volo.Abp.MultiTenancy; using Volo.Abp.Uow; diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs index ef44d6830d..168fe2b0c0 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs @@ -1,8 +1,11 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Data; using Volo.Abp.Domain.Entities; using Volo.Abp.DynamicProxy; using Volo.Abp.Uow; @@ -43,6 +46,65 @@ namespace Volo.Abp.Domain.Repositories } } + public static async Task HardDeleteAsync( + this IRepository repository, + Expression> predicate, + bool autoSave = false, + CancellationToken cancellationToken = default + ) + where TEntity : class, IEntity, ISoftDelete + { + if (!(ProxyHelper.UnProxy(repository) is IUnitOfWorkManagerAccessor unitOfWorkManagerAccessor)) + { + throw new AbpException($"The given repository (of type {repository.GetType().AssemblyQualifiedName}) should implement the {typeof(IUnitOfWorkManagerAccessor).AssemblyQualifiedName} interface in order to invoke the {nameof(HardDeleteAsync)} method!"); + } + + var uowManager = unitOfWorkManagerAccessor.UnitOfWorkManager; + if (uowManager == null) + { + throw new AbpException($"{nameof(unitOfWorkManagerAccessor.UnitOfWorkManager)} property of the given {nameof(repository)} object is null!"); + } + + if (uowManager.Current == null) + { + using (var uow = uowManager.Begin()) + { + await HardDeleteWithUnitOfWorkAsync(repository, predicate, autoSave, cancellationToken, uowManager.Current); + await uow.CompleteAsync(cancellationToken); + } + } + else + { + await HardDeleteWithUnitOfWorkAsync(repository, predicate, autoSave, cancellationToken, uowManager.Current); + } + } + + private static async Task HardDeleteWithUnitOfWorkAsync( + IRepository repository, + Expression> predicate, + bool autoSave, + CancellationToken cancellationToken, IUnitOfWork currentUow + ) + where TEntity : class, IEntity, ISoftDelete + { + var hardDeleteEntities = (HashSet) currentUow.Items.GetOrAdd( + UnitOfWorkItemNames.HardDeletedEntities, + () => new HashSet() + ); + + List entities; + using (currentUow.ServiceProvider.GetRequiredService>().Disable()) + { + entities = await repository.AsyncExecuter.ToListAsync((await repository.GetQueryableAsync()).Where(predicate), cancellationToken); + } + + foreach (var entity in entities) + { + hardDeleteEntities.Add(entity); + await repository.DeleteAsync(entity, autoSave, cancellationToken); + } + } + public static async Task HardDeleteAsync( this IBasicRepository repository, TEntity entity, @@ -77,8 +139,8 @@ namespace Volo.Abp.Domain.Repositories } private static async Task HardDeleteWithUnitOfWorkAsync( - IBasicRepository repository, - TEntity entity, + IBasicRepository repository, + TEntity entity, bool autoSave, CancellationToken cancellationToken, IUnitOfWork currentUow ) @@ -90,7 +152,6 @@ namespace Volo.Abp.Domain.Repositories ); hardDeleteEntities.Add(entity); - await repository.DeleteAsync(entity, autoSave, cancellationToken); } } diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Services/DomainService.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Services/DomainService.cs index 9792cbd0e6..751b938f1d 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Services/DomainService.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Services/DomainService.cs @@ -1,7 +1,7 @@ using System; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.DependencyInjection; using Volo.Abp.Guids; using Volo.Abp.Linq; using Volo.Abp.MultiTenancy; @@ -11,44 +11,20 @@ namespace Volo.Abp.Domain.Services { public abstract class DomainService : IDomainService { + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } + public IServiceProvider ServiceProvider { get; set; } - protected readonly object ServiceProviderLock = new object(); - protected TService LazyGetRequiredService(ref TService reference) - { - if (reference == null) - { - lock (ServiceProviderLock) - { - if (reference == null) - { - reference = ServiceProvider.GetRequiredService(); - } - } - } - - return reference; - } - - protected IClock Clock => LazyGetRequiredService(ref _clock); - private IClock _clock; - - public IGuidGenerator GuidGenerator { get; set; } - - protected ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); - private ILoggerFactory _loggerFactory; - - protected ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant); - private ICurrentTenant _currentTenant; - - protected IAsyncQueryableExecuter AsyncExecuter => LazyGetRequiredService(ref _asyncExecuter); - private IAsyncQueryableExecuter _asyncExecuter; - - protected ILogger Logger => _lazyLogger.Value; - private Lazy _lazyLogger => new Lazy(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true); - - protected DomainService() - { - GuidGenerator = SimpleGuidGenerator.Instance; - } + + protected IClock Clock => LazyServiceProvider.LazyGetRequiredService(); + + public IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance); + + protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService(); + + protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService(); + + protected IAsyncQueryableExecuter AsyncExecuter => LazyServiceProvider.LazyGetRequiredService(); + + protected ILogger Logger => LazyServiceProvider.LazyGetService(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance); } } diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs index 5c704f74f0..a81bfb8c7f 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs @@ -14,7 +14,7 @@ namespace Volo.Abp.Emailing EmailSender = emailSender; } - public async override Task ExecuteAsync(BackgroundEmailSendingJobArgs args) + public override async Task ExecuteAsync(BackgroundEmailSendingJobArgs args) { if (args.From.IsNullOrWhiteSpace()) { diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/nl.json b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/nl.json index 923671e885..3130094f62 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/nl.json +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/nl.json @@ -1,23 +1,25 @@ { "culture": "nl", "texts": { - "DisplayName:Abp.Mailing.DefaultFromAddress": "Standard vanaf adres", - "DisplayName:Abp.Mailing.DefaultFromDisplayName": "Standaard vanaf weergave naam", + "DisplayName:Abp.Mailing.DefaultFromAddress": "Standaard vanaf adres", + "DisplayName:Abp.Mailing.DefaultFromDisplayName": "Standaard vanaf weergavenaam", "DisplayName:Abp.Mailing.Smtp.Host": "Host", "DisplayName:Abp.Mailing.Smtp.Port": "Poort", - "DisplayName:Abp.Mailing.Smtp.UserName": "Gebruiker naam", - "DisplayName:Abp.Mailing.Smtp.Password": "wachtwoord", + "DisplayName:Abp.Mailing.Smtp.UserName": "Gebruikersnaam", + "DisplayName:Abp.Mailing.Smtp.Password": "Wachtwoord", "DisplayName:Abp.Mailing.Smtp.Domain": "Domein", "DisplayName:Abp.Mailing.Smtp.EnableSsl": "SSL toestaan", "DisplayName:Abp.Mailing.Smtp.UseDefaultCredentials": "Gebruik standaard inloggegevens", - "Description:Abp.Mailing.DefaultFromAddress": "Standard vanaf adres", - "Description:Abp.Mailing.DefaultFromDisplayName": "Standaard vanaf weergave naam", + "Description:Abp.Mailing.DefaultFromAddress": "Standaard vanaf adres", + "Description:Abp.Mailing.DefaultFromDisplayName": "Standaard vanaf weergavenaam", "Description:Abp.Mailing.Smtp.Host": "De naam of het IP-adres van de host die wordt gebruikt voor SMTP-transacties.", "Description:Abp.Mailing.Smtp.Port": "De poort die wordt gebruikt voor SMTP-transacties.", "Description:Abp.Mailing.Smtp.UserName": "Gebruikersnaam gekoppeld aan de inloggegevens.", "Description:Abp.Mailing.Smtp.Password": "Het wachtwoord voor de gebruikersnaam die bij de inloggegevens hoort.", "Description:Abp.Mailing.Smtp.Domain": "Het domein of de computernaam die de inloggegevens verifieert.", "Description:Abp.Mailing.Smtp.EnableSsl": "Of de SmtpClient Secure Sockets Layer (SSL) gebruikt om de verbinding te versleutelen.", - "Description:Abp.Mailing.Smtp.UseDefaultCredentials": "Of de standaard inloggegevens worden verzonden met verzoeken." + "Description:Abp.Mailing.Smtp.UseDefaultCredentials": "Of de standaard inloggegevens worden verzonden met verzoeken.", + "TextTemplate:StandardEmailTemplates.Layout": "Standaard sjabloon voor e-mail lay-out", + "TextTemplate:StandardEmailTemplates.Message": "Eenvoudig berichtsjabloon voor e-mails" } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Smtp/SmtpEmailSender.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Smtp/SmtpEmailSender.cs index 710febff9d..24ca7d6a34 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Smtp/SmtpEmailSender.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Smtp/SmtpEmailSender.cs @@ -67,7 +67,7 @@ namespace Volo.Abp.Emailing.Smtp } } - protected async override Task SendEmailAsync(MailMessage mail) + protected override async Task SendEmailAsync(MailMessage mail) { using (var smtpClient = await BuildClientAsync()) { diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs index a95ec00e34..e2a9871a22 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs @@ -1,4 +1,5 @@ -using Microsoft.EntityFrameworkCore; +using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using System; @@ -53,14 +54,13 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore private readonly IDbContextProvider _dbContextProvider; private readonly Lazy> _entityOptionsLazy; - public IGuidGenerator GuidGenerator { get; set; } + public virtual IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance); - public IEfCoreBulkOperationProvider BulkOperationProvider { get; set; } + public IEfCoreBulkOperationProvider BulkOperationProvider => LazyServiceProvider.LazyGetService(); public EfCoreRepository(IDbContextProvider dbContextProvider) { _dbContextProvider = dbContextProvider; - GuidGenerator = SimpleGuidGenerator.Instance; _entityOptionsLazy = new Lazy>( () => ServiceProvider @@ -103,7 +103,7 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore this, entityArray, autoSave, - cancellationToken + GetCancellationToken(cancellationToken) ); return; } @@ -142,7 +142,7 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore this, entities, autoSave, - cancellationToken + GetCancellationToken(cancellationToken) ); return; diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs index a17aab8621..42423cbf3b 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs @@ -23,7 +23,6 @@ using Volo.Abp.EntityFrameworkCore.EntityHistory; using Volo.Abp.EntityFrameworkCore.Modeling; using Volo.Abp.EntityFrameworkCore.ValueConverters; using Volo.Abp.Guids; -using Volo.Abp.Localization; using Volo.Abp.MultiTenancy; using Volo.Abp.ObjectExtending; using Volo.Abp.Reflection; @@ -35,31 +34,33 @@ namespace Volo.Abp.EntityFrameworkCore public abstract class AbpDbContext : DbContext, IAbpEfCoreDbContext, ITransientDependency where TDbContext : DbContext { + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } + protected virtual Guid? CurrentTenantId => CurrentTenant?.Id; protected virtual bool IsMultiTenantFilterEnabled => DataFilter?.IsEnabled() ?? false; protected virtual bool IsSoftDeleteFilterEnabled => DataFilter?.IsEnabled() ?? false; - public ICurrentTenant CurrentTenant { get; set; } + public ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService(); - public IGuidGenerator GuidGenerator { get; set; } + public IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance); - public IDataFilter DataFilter { get; set; } + public IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService(); - public IEntityChangeEventHelper EntityChangeEventHelper { get; set; } + public IEntityChangeEventHelper EntityChangeEventHelper => LazyServiceProvider.LazyGetService(NullEntityChangeEventHelper.Instance); - public IAuditPropertySetter AuditPropertySetter { get; set; } + public IAuditPropertySetter AuditPropertySetter => LazyServiceProvider.LazyGetRequiredService(); - public IEntityHistoryHelper EntityHistoryHelper { get; set; } + public IEntityHistoryHelper EntityHistoryHelper => LazyServiceProvider.LazyGetService(NullEntityHistoryHelper.Instance); - public IAuditingManager AuditingManager { get; set; } + public IAuditingManager AuditingManager => LazyServiceProvider.LazyGetRequiredService(); - public IUnitOfWorkManager UnitOfWorkManager { get; set; } + public IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService(); - public IClock Clock { get; set; } + public IClock Clock => LazyServiceProvider.LazyGetRequiredService(); - public ILogger> Logger { get; set; } + public ILogger> Logger => LazyServiceProvider.LazyGetService>>(NullLogger>.Instance); private static readonly MethodInfo ConfigureBasePropertiesMethodInfo = typeof(AbpDbContext) @@ -85,10 +86,7 @@ namespace Volo.Abp.EntityFrameworkCore protected AbpDbContext(DbContextOptions options) : base(options) { - GuidGenerator = SimpleGuidGenerator.Instance; - EntityChangeEventHelper = NullEntityChangeEventHelper.Instance; - EntityHistoryHelper = NullEntityHistoryHelper.Instance; - Logger = NullLogger>.Instance; + } protected override void OnModelCreating(ModelBuilder modelBuilder) @@ -148,7 +146,7 @@ namespace Volo.Abp.EntityFrameworkCore } } - public async override Task SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default) + public override async Task SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default) { try { @@ -564,7 +562,7 @@ namespace Volo.Abp.EntityFrameworkCore !typeof(TEntity).IsDefined(typeof(OwnedAttribute), true) && !mutableEntityType.IsOwned()) { - if (Clock == null || !Clock.SupportsMultipleTimezone) + if (LazyServiceProvider == null || Clock == null || !Clock.SupportsMultipleTimezone) { return; } diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs index 143a5659cc..364a29fb07 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs @@ -39,12 +39,15 @@ namespace Volo.Abp.Uow.EntityFrameworkCore [Obsolete("Use GetDbContextAsync method.")] public TDbContext GetDbContext() { - Logger.LogWarning( - "UnitOfWorkDbContextProvider.GetDbContext is deprecated. Use GetDbContextAsync instead! " + - "You are probably using LINQ (LINQ extensions) directly on a repository. In this case, use repository.GetQueryableAsync() method " + - "to obtain an IQueryable instance and use LINQ (LINQ extensions) on this object. " - ); - Logger.LogWarning(Environment.StackTrace.Truncate(2048)); + if (!UnitOfWork.DisableObsoleteDbContextCreationWarning.Value) + { + Logger.LogWarning( + "UnitOfWorkDbContextProvider.GetDbContext is deprecated. Use GetDbContextAsync instead! " + + "You are probably using LINQ (LINQ extensions) directly on a repository. In this case, use repository.GetQueryableAsync() method " + + "to obtain an IQueryable instance and use LINQ (LINQ extensions) on this object. " + ); + Logger.LogWarning(Environment.StackTrace.Truncate(2048)); + } var unitOfWork = _unitOfWorkManager.Current; if (unitOfWork == null) @@ -142,8 +145,6 @@ namespace Volo.Abp.Uow.EntityFrameworkCore private async Task CreateDbContextAsync(IUnitOfWork unitOfWork) { - Logger.LogDebug($"Creating a new DbContext of type {typeof(TDbContext).FullName}"); - return unitOfWork.Options.IsTransactional ? await CreateDbContextWithTransactionAsync(unitOfWork) : unitOfWork.ServiceProvider.GetRequiredService(); diff --git a/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs index 363744c1d4..fd6d773952 100644 --- a/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs @@ -146,7 +146,7 @@ namespace Volo.Abp.EventBus.Kafka GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Clear()); } - public async override Task PublishAsync(Type eventType, object eventData) + public override async Task PublishAsync(Type eventType, object eventData) { var eventName = EventNameAttribute.GetNameOrDefault(eventType); var body = Serializer.Serialize(eventData); diff --git a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs index 44d229ee94..ce3549646e 100644 --- a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs @@ -124,7 +124,7 @@ namespace Volo.Abp.EventBus.Rebus return Subscribe(typeof(TEvent), handler); } - public async override Task PublishAsync(Type eventType, object eventData) + public override async Task PublishAsync(Type eventType, object eventData) { await AbpRebusEventBusOptions.Publish(Rebus, eventType, eventData); } diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs index 828bd4f5c7..8c7bef6f2d 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs @@ -117,7 +117,7 @@ namespace Volo.Abp.EventBus.Local GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Clear()); } - public async override Task PublishAsync(Type eventType, object eventData) + public override async Task PublishAsync(Type eventType, object eventData) { var exceptions = new List(); diff --git a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/ExceptionHandling/Localization/nl.json b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/ExceptionHandling/Localization/nl.json index f96c1f9a9c..f9e28a142e 100644 --- a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/ExceptionHandling/Localization/nl.json +++ b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/ExceptionHandling/Localization/nl.json @@ -4,7 +4,7 @@ "InternalServerErrorMessage": "Er is een interne fout opgetreden tijdens uw verzoek!", "ValidationErrorMessage": "Uw verzoek is niet geldig!", "ValidationNarrativeErrorMessageTitle": "Tijdens de validatie zijn de volgende fouten gedetecteerd.", - "DefaultErrorMessage": "er is een fout opgetreden!", + "DefaultErrorMessage": "Er is een fout opgetreden!", "DefaultErrorMessageDetail": "Foutdetails niet verzonden door server.", "DefaultErrorMessage401": "U bent niet geverifieerd!", "DefaultErrorMessage401Detail": "U moet inloggen om deze bewerking uit te voeren.", @@ -18,6 +18,8 @@ "401Message": "Ongeautoriseerd", "403Message": "Verboden", "404Message": "Pagina niet gevonden", - "500Message": "Interne Server Fout" + "500Message": "Interne Server Fout", + "403MessageDetail": "U bent niet bevoegd om deze handeling uit te voeren!", + "404MessageDetail": "Sorry, op dit adres is niks gevonden." } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/EditionFeatureValueProvider.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/EditionFeatureValueProvider.cs index 3bb039f7b2..db8ec4774f 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/EditionFeatureValueProvider.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/EditionFeatureValueProvider.cs @@ -18,7 +18,7 @@ namespace Volo.Abp.Features PrincipalAccessor = principalAccessor; } - public async override Task GetOrNullAsync(FeatureDefinition feature) + public override async Task GetOrNullAsync(FeatureDefinition feature) { var editionId = PrincipalAccessor.Principal?.FindEditionId(); if (editionId == null) diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureChecker.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureChecker.cs index b52ffe355e..84257df293 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureChecker.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureChecker.cs @@ -35,7 +35,7 @@ namespace Volo.Abp.Features ); } - public async override Task GetOrNullAsync(string name) + public override async Task GetOrNullAsync(string name) { var featureDefinition = FeatureDefinitionManager.Get(name); var providers = Enumerable diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptor.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptor.cs index 7b84593378..8c0936bede 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptor.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptor.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Aspects; using Volo.Abp.DependencyInjection; using Volo.Abp.DynamicProxy; @@ -7,15 +9,14 @@ namespace Volo.Abp.Features { public class FeatureInterceptor : AbpInterceptor, ITransientDependency { - private readonly IMethodInvocationFeatureCheckerService _methodInvocationFeatureCheckerService; + private readonly IServiceScopeFactory _serviceScopeFactory; - public FeatureInterceptor( - IMethodInvocationFeatureCheckerService methodInvocationFeatureCheckerService) + public FeatureInterceptor(IServiceScopeFactory serviceScopeFactory) { - _methodInvocationFeatureCheckerService = methodInvocationFeatureCheckerService; + _serviceScopeFactory = serviceScopeFactory; } - public async override Task InterceptAsync(IAbpMethodInvocation invocation) + public override async Task InterceptAsync(IAbpMethodInvocation invocation) { if (AbpCrossCuttingConcerns.IsApplied(invocation.TargetObject, AbpCrossCuttingConcerns.FeatureChecking)) { @@ -29,11 +30,14 @@ namespace Volo.Abp.Features protected virtual async Task CheckFeaturesAsync(IAbpMethodInvocation invocation) { - await _methodInvocationFeatureCheckerService.CheckAsync( - new MethodInvocationFeatureCheckerContext( - invocation.Method - ) - ); + using (var scope = _serviceScopeFactory.CreateScope()) + { + await scope.ServiceProvider.GetRequiredService().CheckAsync( + new MethodInvocationFeatureCheckerContext( + invocation.Method + ) + ); + } } } } diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/nl.json b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/nl.json new file mode 100644 index 0000000000..0c43d02c08 --- /dev/null +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/nl.json @@ -0,0 +1,8 @@ +{ + "culture": "nl", + "texts": { + "Volo.Feature:010001": "Functie '{FeatureName}' is niet ingeschakeld", + "Volo.Feature:010002": "Vereiste functies zijn niet ingeschakeld. Al deze functies moeten zijn ingeschakeld: {FeatureNames}", + "Volo.Feature:010003": "Vereiste functies zijn niet ingeschakeld. Ten minste een van deze functies moet zijn ingeschakeld: {FeatureNames}" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/TenantFeatureValueProvider.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/TenantFeatureValueProvider.cs index 6e4dc669fa..2e6f72a9c6 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/TenantFeatureValueProvider.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/TenantFeatureValueProvider.cs @@ -17,7 +17,7 @@ namespace Volo.Abp.Features CurrentTenant = currentTenant; } - public async override Task GetOrNullAsync(FeatureDefinition feature) + public override async Task GetOrNullAsync(FeatureDefinition feature) { return await FeatureStore.GetOrNullAsync(feature.Name, Name, CurrentTenant.Id?.ToString()); } diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextIdentityModelRemoteServiceHttpClientAuthenticator.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextIdentityModelRemoteServiceHttpClientAuthenticator.cs index f3001eb443..a829a630d6 100644 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextIdentityModelRemoteServiceHttpClientAuthenticator.cs +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextIdentityModelRemoteServiceHttpClientAuthenticator.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.Http.Client.IdentityModel.Web { } - public async override Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) + public override async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) { if (context.RemoteService.GetUseCurrentAccessToken() != false) { diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs index 0e0b659ef1..c86fc095c7 100644 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs @@ -20,7 +20,7 @@ namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly AccessTokenProvider = accessTokenProvider; } - public async override Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) + public override async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) { if (context.RemoteService.GetUseCurrentAccessToken() != false) { diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs index 48ba2f1a4f..7eb4e5ad78 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs @@ -75,7 +75,7 @@ namespace Volo.Abp.Http.Client.DynamicProxying Logger = NullLogger>.Instance; } - public async override Task InterceptAsync(IAbpMethodInvocation invocation) + public override async Task InterceptAsync(IAbpMethodInvocation invocation) { if (invocation.Method.ReturnType.GenericTypeArguments.IsNullOrEmpty()) { diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Localization/nl.json b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Localization/nl.json new file mode 100644 index 0000000000..ce321ab712 --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Localization/nl.json @@ -0,0 +1,15 @@ +{ + "culture": "nl", + "texts": { + "DisplayName:Abp.Ldap.ServerHost": "Serverhost", + "Description:Abp.Ldap.ServerHost": "Serverhost", + "DisplayName:Abp.Ldap.ServerPort": "Server poort", + "Description:Abp.Ldap.ServerPort": "Server poort", + "DisplayName:Abp.Ldap.BaseDc": "Basisdomein component", + "Description:Abp.Ldap.BaseDc": "Basisdomein component", + "DisplayName:Abp.Ldap.UserName": "Gebruikersnaam", + "Description:Abp.Ldap.UserName": "Gebruikersnaam", + "DisplayName:Abp.Ldap.Password": "Wachtwoord", + "Description:Abp.Ldap.Password": "Wachtwoord" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/MailKitSmtpEmailSender.cs b/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/MailKitSmtpEmailSender.cs index d089f7b684..0fb93e8f40 100644 --- a/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/MailKitSmtpEmailSender.cs +++ b/framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/MailKitSmtpEmailSender.cs @@ -28,7 +28,7 @@ namespace Volo.Abp.MailKit SmtpConfiguration = smtpConfiguration; } - protected async override Task SendEmailAsync(MailMessage mail) + protected override async Task SendEmailAsync(MailMessage mail) { using (var client = await BuildClientAsync()) { diff --git a/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs b/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs index 811c51ed5f..8ab6753de3 100644 --- a/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs +++ b/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs @@ -39,23 +39,19 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb protected IMemoryDatabaseProvider DatabaseProvider { get; } - public ILocalEventBus LocalEventBus { get; set; } + public ILocalEventBus LocalEventBus => LazyServiceProvider.LazyGetService(NullLocalEventBus.Instance); - public IDistributedEventBus DistributedEventBus { get; set; } + public IDistributedEventBus DistributedEventBus => LazyServiceProvider.LazyGetService(NullDistributedEventBus.Instance); - public IEntityChangeEventHelper EntityChangeEventHelper { get; set; } + public IEntityChangeEventHelper EntityChangeEventHelper => LazyServiceProvider.LazyGetService(NullEntityChangeEventHelper.Instance); - public IAuditPropertySetter AuditPropertySetter { get; set; } + public IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance); - public IGuidGenerator GuidGenerator { get; set; } + public IAuditPropertySetter AuditPropertySetter => LazyServiceProvider.LazyGetRequiredService(); public MemoryDbRepository(IMemoryDatabaseProvider databaseProvider) { DatabaseProvider = databaseProvider; - - LocalEventBus = NullLocalEventBus.Instance; - DistributedEventBus = NullDistributedEventBus.Instance; - EntityChangeEventHelper = NullEntityChangeEventHelper.Instance; } [Obsolete("This method will be removed in future versions.")] diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbBulkOperationProvider.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbBulkOperationProvider.cs index fda7f291c7..cdb91aa4a7 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbBulkOperationProvider.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbBulkOperationProvider.cs @@ -3,9 +3,8 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Volo.Abp.Domain.Entities; -using Volo.Abp.Domain.Repositories.MongoDB; -namespace Volo.Abp.MongoDB.Volo.Abp.Domain.Repositories.MongoDB +namespace Volo.Abp.Domain.Repositories.MongoDB { public interface IMongoDbBulkOperationProvider { diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs index 53c291a178..b252c48999 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs @@ -16,7 +16,6 @@ using Volo.Abp.EventBus.Distributed; using Volo.Abp.EventBus.Local; using Volo.Abp.Guids; using Volo.Abp.MongoDB; -using Volo.Abp.MongoDB.Volo.Abp.Domain.Repositories.MongoDB; namespace Volo.Abp.Domain.Repositories.MongoDB { @@ -61,26 +60,21 @@ namespace Volo.Abp.Domain.Repositories.MongoDB protected IMongoDbContextProvider DbContextProvider { get; } - public ILocalEventBus LocalEventBus { get; set; } + public ILocalEventBus LocalEventBus => LazyServiceProvider.LazyGetService(NullLocalEventBus.Instance); - public IDistributedEventBus DistributedEventBus { get; set; } + public IDistributedEventBus DistributedEventBus => LazyServiceProvider.LazyGetService(NullDistributedEventBus.Instance); - public IEntityChangeEventHelper EntityChangeEventHelper { get; set; } + public IEntityChangeEventHelper EntityChangeEventHelper => LazyServiceProvider.LazyGetService(NullEntityChangeEventHelper.Instance); - public IGuidGenerator GuidGenerator { get; set; } + public IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService(SimpleGuidGenerator.Instance); - public IAuditPropertySetter AuditPropertySetter { get; set; } + public IAuditPropertySetter AuditPropertySetter => LazyServiceProvider.LazyGetRequiredService(); - public IMongoDbBulkOperationProvider BulkOperationProvider { get; set; } + public IMongoDbBulkOperationProvider BulkOperationProvider => LazyServiceProvider.LazyGetService(); public MongoDbRepository(IMongoDbContextProvider dbContextProvider) { DbContextProvider = dbContextProvider; - - LocalEventBus = NullLocalEventBus.Instance; - DistributedEventBus = NullDistributedEventBus.Instance; - EntityChangeEventHelper = NullEntityChangeEventHelper.Instance; - GuidGenerator = SimpleGuidGenerator.Instance; } public override async Task InsertAsync( diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs index ff367dc554..90605f416e 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs @@ -22,7 +22,7 @@ namespace Volo.Abp.Domain.Repositories return repository.ToMongoDbRepository().GetDatabaseAsync(); } - [Obsolete("Use GetCollection method.")] + [Obsolete("Use GetCollectionAsync method.")] public static IMongoCollection GetCollection(this IBasicRepository repository) where TEntity : class, IEntity { diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs index 724e7673fc..6db6aec6b5 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs @@ -36,12 +36,15 @@ namespace Volo.Abp.Uow.MongoDB [Obsolete("Use CreateDbContextAsync")] public TMongoDbContext GetDbContext() { - Logger.LogWarning( - "UnitOfWorkDbContextProvider.GetDbContext is deprecated. Use GetDbContextAsync instead! " + - "You are probably using LINQ (LINQ extensions) directly on a repository. In this case, use repository.GetQueryableAsync() method " + - "to obtain an IQueryable instance and use LINQ (LINQ extensions) on this object. " - ); - Logger.LogWarning(Environment.StackTrace.Truncate(2048)); + if (!UnitOfWork.DisableObsoleteDbContextCreationWarning.Value) + { + Logger.LogWarning( + "UnitOfWorkDbContextProvider.GetDbContext is deprecated. Use GetDbContextAsync instead! " + + "You are probably using LINQ (LINQ extensions) directly on a repository. In this case, use repository.GetQueryableAsync() method " + + "to obtain an IQueryable instance and use LINQ (LINQ extensions) on this object. " + ); + Logger.LogWarning(Environment.StackTrace.Truncate(2048)); + } var unitOfWork = _unitOfWorkManager.Current; if (unitOfWork == null) diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/AbpRabbitMqModule.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/AbpRabbitMqModule.cs index a96309a1a8..feeb3a0431 100644 --- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/AbpRabbitMqModule.cs +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/AbpRabbitMqModule.cs @@ -15,6 +15,13 @@ namespace Volo.Abp.RabbitMQ { var configuration = context.Services.GetConfiguration(); Configure(configuration.GetSection("RabbitMQ")); + Configure(options => + { + foreach (var connectionFactory in options.Connections.Values) + { + connectionFactory.DispatchConsumersAsync = true; + } + }); } public override void OnApplicationShutdown(ApplicationShutdownContext context) diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqConnections.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqConnections.cs index f2b5168d82..a725291df8 100644 --- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqConnections.cs +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqConnections.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.RabbitMQ public RabbitMqConnections() { - Default = new ConnectionFactory() { DispatchConsumersAsync = true }; + Default = new ConnectionFactory(); } public ConnectionFactory GetOrDefault(string connectionName) diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/TenantSettingValueProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/TenantSettingValueProvider.cs index 6286356a04..9c1d34b741 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/TenantSettingValueProvider.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/TenantSettingValueProvider.cs @@ -19,12 +19,12 @@ namespace Volo.Abp.Settings CurrentTenant = currentTenant; } - public async override Task GetOrNullAsync(SettingDefinition setting) + public override async Task GetOrNullAsync(SettingDefinition setting) { return await SettingStore.GetOrNullAsync(setting.Name, Name, CurrentTenant.Id?.ToString()); } - public async override Task> GetAllAsync(SettingDefinition[] settings) + public override async Task> GetAllAsync(SettingDefinition[] settings) { return await SettingStore.GetAllAsync(settings.Select(x => x.Name).ToArray(), Name, CurrentTenant.Id?.ToString()); } diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/UserSettingValueProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/UserSettingValueProvider.cs index 8c337bbee4..08ac6cc471 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/UserSettingValueProvider.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/UserSettingValueProvider.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.Settings CurrentUser = currentUser; } - public async override Task GetOrNullAsync(SettingDefinition setting) + public override async Task GetOrNullAsync(SettingDefinition setting) { if (CurrentUser.Id == null) { @@ -29,7 +29,7 @@ namespace Volo.Abp.Settings return await SettingStore.GetOrNullAsync(setting.Name, Name, CurrentUser.Id.ToString()); } - public async override Task> GetAllAsync(SettingDefinition[] settings) + public override async Task> GetAllAsync(SettingDefinition[] settings) { if (CurrentUser.Id == null) { diff --git a/framework/src/Volo.Abp.Swashbuckle/Microsoft/AspNetCore/Builder/AbpSwaggerUIBuilderExtensions.cs b/framework/src/Volo.Abp.Swashbuckle/Microsoft/AspNetCore/Builder/AbpSwaggerUIBuilderExtensions.cs index 0f19345038..5b5d3a4a52 100644 --- a/framework/src/Volo.Abp.Swashbuckle/Microsoft/AspNetCore/Builder/AbpSwaggerUIBuilderExtensions.cs +++ b/framework/src/Volo.Abp.Swashbuckle/Microsoft/AspNetCore/Builder/AbpSwaggerUIBuilderExtensions.cs @@ -15,8 +15,8 @@ namespace Microsoft.AspNetCore.Builder return app.UseSwaggerUI(options => { - options.InjectJavascript("/swagger/ui/abp.js"); - options.InjectJavascript("/swagger/ui/abp.swagger.js"); + options.InjectJavascript("ui/abp.js"); + options.InjectJavascript("ui/abp.swagger.js"); options.IndexStream = () => resolver.Resolver(); setupAction?.Invoke(options); diff --git a/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/AsyncLocalSimpleScopeExtensions.cs b/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/AsyncLocalSimpleScopeExtensions.cs new file mode 100644 index 0000000000..cb58ea26f9 --- /dev/null +++ b/framework/src/Volo.Abp.Threading/Volo/Abp/Threading/AsyncLocalSimpleScopeExtensions.cs @@ -0,0 +1,18 @@ +using System; +using System.Threading; + +namespace Volo.Abp.Threading +{ + public static class AsyncLocalSimpleScopeExtensions + { + public static IDisposable SetScoped(this AsyncLocal asyncLocal, T value) + { + var previousValue = asyncLocal.Value; + asyncLocal.Value = value; + return new DisposeAction(() => + { + asyncLocal.Value = previousValue; + }); + } + } +} diff --git a/framework/src/Volo.Abp.Timing/Volo.Abp.Timing.csproj b/framework/src/Volo.Abp.Timing/Volo.Abp.Timing.csproj index c0a9f0b271..20a4521445 100644 --- a/framework/src/Volo.Abp.Timing/Volo.Abp.Timing.csproj +++ b/framework/src/Volo.Abp.Timing/Volo.Abp.Timing.csproj @@ -20,7 +20,6 @@ - diff --git a/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/AbpTimingModule.cs b/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/AbpTimingModule.cs index 3db42c2e55..670eef0fe6 100644 --- a/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/AbpTimingModule.cs +++ b/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/AbpTimingModule.cs @@ -8,7 +8,7 @@ using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.Timing { [DependsOn( - typeof(AbpVirtualFileSystemModule), + typeof(AbpLocalizationModule), typeof(AbpSettingsModule) )] public class AbpTimingModule : AbpModule diff --git a/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Localization/nl.json b/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Localization/nl.json new file mode 100644 index 0000000000..ae4c8c72a0 --- /dev/null +++ b/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Localization/nl.json @@ -0,0 +1,7 @@ +{ + "culture": "nl", + "texts": { + "DisplayName:Abp.Timing.Timezone": "Tijdzone", + "Description:Abp.Timing.Timezone": "Tijdzone van applicatie" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuConfigurationContext.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuConfigurationContext.cs index e5550d2d09..d5c6ebe468 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuConfigurationContext.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuConfigurationContext.cs @@ -4,35 +4,19 @@ using JetBrains.Annotations; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; +using Volo.Abp.DependencyInjection; namespace Volo.Abp.UI.Navigation { public class MenuConfigurationContext : IMenuConfigurationContext { public IServiceProvider ServiceProvider { get; } - private readonly object _serviceProviderLock = new object(); - private TRef LazyGetRequiredService(Type serviceType, ref TRef reference) - { - if (reference == null) - { - lock (_serviceProviderLock) - { - if (reference == null) - { - reference = (TRef)ServiceProvider.GetRequiredService(serviceType); - } - } - } - - return reference; - } + private readonly IAbpLazyServiceProvider _lazyServiceProvider; - public IAuthorizationService AuthorizationService => LazyGetRequiredService(typeof(IAuthorizationService), ref _authorizationService); - private IAuthorizationService _authorizationService; + public IAuthorizationService AuthorizationService => _lazyServiceProvider.LazyGetRequiredService(); - private IStringLocalizerFactory _stringLocalizerFactory; - public IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(typeof(IStringLocalizerFactory),ref _stringLocalizerFactory); + public IStringLocalizerFactory StringLocalizerFactory => _lazyServiceProvider.LazyGetRequiredService(); public ApplicationMenu Menu { get; } @@ -40,6 +24,7 @@ namespace Volo.Abp.UI.Navigation { Menu = menu; ServiceProvider = serviceProvider; + _lazyServiceProvider = ServiceProvider.GetRequiredService(); } public Task IsGrantedAsync(string policyName) @@ -58,7 +43,7 @@ namespace Volo.Abp.UI.Navigation { return StringLocalizerFactory.Create(); } - + [NotNull] public IStringLocalizer GetLocalizer(Type resourceType) { diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json index 4f0906ee3e..52402db298 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json @@ -30,7 +30,7 @@ "PagerPrevious": "Anterior", "PagerFirst": "Primero", "PagerLast": "Último", - "PagerInfo": "Mostrando de la _START a la _END_ de _TOTAL_ entradas", + "PagerInfo": "Mostrando de la _START_ a la _END_ de _TOTAL_ entradas", "PagerInfo{0}{1}{2}": "Mostrando de la {0} a la {1} de {2} entradas", "PagerInfoEmpty": "Mostrando de la 0 a la 0 de 0 entradas", "PagerInfoFiltered": "(filtrado desde _MAX_ entradas totales)", diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/nl.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/nl.json index c65715f8a5..69ad662be1 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/nl.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/nl.json @@ -4,9 +4,10 @@ "Languages": "Talen", "AreYouSure": "Bent u zeker?", "Cancel": "Annuleren", + "Clear": "Wissen", "Yes": "Ja", "No": "Nee", - "Ok": "Ok", + "Ok": "Ok", "Close": "Sluiten", "Save": "Opslaan", "SavingWithThreeDot": "Opslaan...", @@ -34,6 +35,8 @@ "PagerInfoEmpty": "Toont 0 tot 0 van 0 vermeldingen", "PagerInfoFiltered": "(gefilterd uit in totaal _MAX_ vermeldingen)", "NoDataAvailableInDatatable": "Geen gegevens beschikbaar", + "Total": "totaal", + "Selected": "geselecteed", "PagerShowMenuEntries": "Toon _MENU_-vermeldingen", "DatatableActionDropdownDefaultText": "Acties", "ChangePassword": "Verander wachtwoord", @@ -41,6 +44,9 @@ "AreYouSureYouWantToCancelEditingWarningMessage": "U heeft nog niet-opgeslagen wijzigingen.", "GoHomePage": "Ga naar de homepage", "GoBack": "Ga terug", - "Search": "Zoeken" + "Search": "Zoeken", + "ItemWillBeDeletedMessageWithFormat": "{0} wordt verwijderd!", + "ItemWillBeDeletedMessage": "Dit item wordt verwijderd!", + "ManageYourAccount": "Beheer uw account" } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs index d53acc8f66..2e4b40877f 100644 --- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs +++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs @@ -11,6 +11,9 @@ namespace Volo.Abp.Uow { public class UnitOfWork : IUnitOfWork, ITransientDependency { + [Obsolete("This will be removed in next versions.")] + public static AsyncLocal DisableObsoleteDbContextCreationWarning { get; } = new AsyncLocal(); + public const string UnitOfWorkReservationName = "_AbpActionUnitOfWork"; public Guid Id { get; } = Guid.NewGuid(); diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptor.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptor.cs index 464b6bb871..3d8654adb0 100644 --- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptor.cs +++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptor.cs @@ -1,6 +1,7 @@ using System; using System.Threading.Tasks; using JetBrains.Annotations; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; using Volo.Abp.DynamicProxy; @@ -9,18 +10,11 @@ namespace Volo.Abp.Uow { public class UnitOfWorkInterceptor : AbpInterceptor, ITransientDependency { - private readonly IUnitOfWorkManager _unitOfWorkManager; - private readonly IUnitOfWorkTransactionBehaviourProvider _transactionBehaviourProvider; - private readonly AbpUnitOfWorkDefaultOptions _defaultOptions; + private readonly IServiceScopeFactory _serviceScopeFactory; - public UnitOfWorkInterceptor( - IUnitOfWorkManager unitOfWorkManager, - IOptions options, - IUnitOfWorkTransactionBehaviourProvider transactionBehaviourProvider) + public UnitOfWorkInterceptor(IServiceScopeFactory serviceScopeFactory) { - _unitOfWorkManager = unitOfWorkManager; - _transactionBehaviourProvider = transactionBehaviourProvider; - _defaultOptions = options.Value; + _serviceScopeFactory = serviceScopeFactory; } public override async Task InterceptAsync(IAbpMethodInvocation invocation) @@ -31,23 +25,28 @@ namespace Volo.Abp.Uow return; } - var options = CreateOptions(invocation, unitOfWorkAttribute); - - //Trying to begin a reserved UOW by AbpUnitOfWorkMiddleware - if (_unitOfWorkManager.TryBeginReserved(UnitOfWork.UnitOfWorkReservationName, options)) + using (var scope = _serviceScopeFactory.CreateScope()) { - await invocation.ProceedAsync(); - return; - } + var options = CreateOptions(scope.ServiceProvider, invocation, unitOfWorkAttribute); - using (var uow = _unitOfWorkManager.Begin(options)) - { - await invocation.ProceedAsync(); - await uow.CompleteAsync(); + var unitOfWorkManager = scope.ServiceProvider.GetRequiredService(); + + //Trying to begin a reserved UOW by AbpUnitOfWorkMiddleware + if (unitOfWorkManager.TryBeginReserved(UnitOfWork.UnitOfWorkReservationName, options)) + { + await invocation.ProceedAsync(); + return; + } + + using (var uow = unitOfWorkManager.Begin(options)) + { + await invocation.ProceedAsync(); + await uow.CompleteAsync(); + } } } - private AbpUnitOfWorkOptions CreateOptions(IAbpMethodInvocation invocation, [CanBeNull] UnitOfWorkAttribute unitOfWorkAttribute) + private AbpUnitOfWorkOptions CreateOptions(IServiceProvider serviceProvider, IAbpMethodInvocation invocation, [CanBeNull] UnitOfWorkAttribute unitOfWorkAttribute) { var options = new AbpUnitOfWorkOptions(); @@ -55,8 +54,9 @@ namespace Volo.Abp.Uow if (unitOfWorkAttribute?.IsTransactional == null) { - options.IsTransactional = _defaultOptions.CalculateIsTransactional( - autoValue: _transactionBehaviourProvider.IsTransactional + var defaultOptions = serviceProvider.GetRequiredService>().Value; + options.IsTransactional = defaultOptions.CalculateIsTransactional( + autoValue: serviceProvider.GetRequiredService().IsTransactional ?? !invocation.Method.Name.StartsWith("Get", StringComparison.InvariantCultureIgnoreCase) ); } diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptor.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptor.cs index d0d9e7594d..b4ce642471 100644 --- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptor.cs +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptor.cs @@ -13,7 +13,7 @@ namespace Volo.Abp.Validation _methodInvocationValidator = methodInvocationValidator; } - public async override Task InterceptAsync(IAbpMethodInvocation invocation) + public override async Task InterceptAsync(IAbpMethodInvocation invocation) { Validate(invocation); await invocation.ProceedAsync(); diff --git a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_WithDomainResolver_Tests.cs b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_WithDomainResolver_Tests.cs index e2ac111f5d..7a7244aa69 100644 --- a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_WithDomainResolver_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_WithDomainResolver_Tests.cs @@ -38,7 +38,7 @@ namespace Volo.Abp.AspNetCore.MultiTenancy services.Configure(options => { - options.AddDomainTenantResolver("{0}.abp.io"); + options.AddDomainTenantResolver("{0}.abp.io:8080"); }); }); } @@ -46,14 +46,14 @@ namespace Volo.Abp.AspNetCore.MultiTenancy [Fact] public async Task Should_Use_Host_If_Tenant_Is_Not_Specified() { - var result = await GetResponseAsObjectAsync>("http://abp.io"); + var result = await GetResponseAsObjectAsync>("http://abp.io:8080"); result["TenantId"].ShouldBe(""); } [Fact] public async Task Should_Use_Domain_If_Specified() { - var result = await GetResponseAsObjectAsync>("http://acme.abp.io"); + var result = await GetResponseAsObjectAsync>("http://acme.abp.io:8080"); result["TenantId"].ShouldBe(_testTenantId.ToString()); } @@ -62,8 +62,8 @@ namespace Volo.Abp.AspNetCore.MultiTenancy { Client.DefaultRequestHeaders.Add(_options.TenantKey, Guid.NewGuid().ToString()); - var result = await GetResponseAsObjectAsync>("http://acme.abp.io"); + var result = await GetResponseAsObjectAsync>("http://acme.abp.io:8080"); result["TenantId"].ShouldBe(_testTenantId.ToString()); } } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.BlobStoring.Minio.Tests/Volo/Abp/BlobStoring/Minio/AbpBlobStoringMinioTestModule.cs b/framework/test/Volo.Abp.BlobStoring.Minio.Tests/Volo/Abp/BlobStoring/Minio/AbpBlobStoringMinioTestModule.cs index a448c2160e..776cc32c36 100644 --- a/framework/test/Volo.Abp.BlobStoring.Minio.Tests/Volo/Abp/BlobStoring/Minio/AbpBlobStoringMinioTestModule.cs +++ b/framework/test/Volo.Abp.BlobStoring.Minio.Tests/Volo/Abp/BlobStoring/Minio/AbpBlobStoringMinioTestModule.cs @@ -60,7 +60,7 @@ namespace Volo.Abp.BlobStoring.Minio }); } - public async override void OnApplicationShutdown(ApplicationShutdownContext context) + public override async void OnApplicationShutdown(ApplicationShutdownContext context) { var minioClient = new MinioClient(_endPoint, _accessKey, _secretKey); if (await minioClient.BucketExistsAsync(_randomContainerName)) diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/SimpleAsyncInterceptor.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/SimpleAsyncInterceptor.cs index 7f38276df2..029073a310 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/SimpleAsyncInterceptor.cs +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/SimpleAsyncInterceptor.cs @@ -5,7 +5,7 @@ namespace Volo.Abp.DynamicProxy { public class SimpleAsyncInterceptor : AbpInterceptor { - public async override Task InterceptAsync(IAbpMethodInvocation invocation) + public override async Task InterceptAsync(IAbpMethodInvocation invocation) { await Task.Delay(5); (invocation.TargetObject as ICanLogOnObject)?.Logs?.Add($"{GetType().Name}_InterceptAsync_BeforeInvocation"); diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/SimpleResultCacheTestInterceptor.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/SimpleResultCacheTestInterceptor.cs index ebbf890b14..f19864f554 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/SimpleResultCacheTestInterceptor.cs +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DynamicProxy/SimpleResultCacheTestInterceptor.cs @@ -13,7 +13,7 @@ namespace Volo.Abp.DynamicProxy _cache = new ConcurrentDictionary(); } - public async override Task InterceptAsync(IAbpMethodInvocation invocation) + public override async Task InterceptAsync(IAbpMethodInvocation invocation) { if (_cache.ContainsKey(invocation.Method)) { diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/nl.json b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/nl.json new file mode 100644 index 0000000000..dfef28046b --- /dev/null +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/Localization/nl.json @@ -0,0 +1,6 @@ +{ + "culture": "nl", + "texts": { + "Volo.Abp.Http.DynamicProxying:10001": "Business-uitzondering met data: {0}" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs index f998da8528..09b1551e3d 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs @@ -51,7 +51,7 @@ namespace Volo.Abp.MongoDB.Repositories } [Fact] - public async override Task InsertAsync() + public override async Task InsertAsync() { var person = new Person(Guid.NewGuid(), "New Person", 35); person.Phones.Add(new Phone(person.Id, "1234567890")); diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/DistrictAppService.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/DistrictAppService.cs index 772db07e72..f7e7fde5e2 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/DistrictAppService.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/DistrictAppService.cs @@ -15,12 +15,12 @@ namespace Volo.Abp.TestApp.Application { } - protected async override Task DeleteByIdAsync(DistrictKey id) + protected override async Task DeleteByIdAsync(DistrictKey id) { await Repository.DeleteAsync(d => d.CityId == id.CityId && d.Name == id.Name); } - protected async override Task GetEntityByIdAsync(DistrictKey id) + protected override async Task GetEntityByIdAsync(DistrictKey id) { return await AsyncExecuter.FirstOrDefaultAsync( Repository.Where(d => d.CityId == id.CityId && d.Name == id.Name) diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HardDelete_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HardDelete_Tests.cs index 1eac79fd7c..3d9b324da8 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HardDelete_Tests.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HardDelete_Tests.cs @@ -30,8 +30,26 @@ namespace Volo.Abp.TestApp.Testing var douglas = await PersonRepository.GetAsync(TestDataBuilder.UserDouglasId); await PersonRepository.HardDeleteAsync(douglas); - douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); - douglas.ShouldBeNull(); + using (DataFilter.Disable()) + { + douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); + douglas.ShouldBeNull(); + } + } + + [Fact] + public async Task Should_HardDelete_Entities_With_Predicate() + { + await PersonRepository.HardDeleteAsync(x => x.Id == TestDataBuilder.UserDouglasId || x.Id == TestDataBuilder.UserJohnDeletedId); + + using (DataFilter.Disable()) + { + var douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); + douglas.ShouldBeNull(); + + var john = await PersonRepository.FindAsync(TestDataBuilder.UserJohnDeletedId); + john.ShouldBeNull(); + } } [Fact] @@ -62,8 +80,44 @@ namespace Volo.Abp.TestApp.Testing await uow.CompleteAsync(); } + using (DataFilter.Disable()) + { + douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); + douglas.ShouldBeNull(); + } + } + + [Fact] + public async Task Should_HardDelete_Soft_Deleted_Entities_With_Predicate() + { + var douglas = await PersonRepository.GetAsync(TestDataBuilder.UserDouglasId); + await PersonRepository.DeleteAsync(douglas); + douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); douglas.ShouldBeNull(); + + using (DataFilter.Disable()) + { + douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); + douglas.ShouldNotBeNull(); + douglas.IsDeleted.ShouldBeTrue(); + douglas.DeletionTime.ShouldNotBeNull(); + } + + using (var uow = UnitOfWorkManager.Begin()) + { + await PersonRepository.HardDeleteAsync(x => x.Id == TestDataBuilder.UserDouglasId || x.Id == TestDataBuilder.UserJohnDeletedId); + await uow.CompleteAsync(); + } + + using (DataFilter.Disable()) + { + douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); + douglas.ShouldBeNull(); + + var john = await PersonRepository.FindAsync(TestDataBuilder.UserJohnDeletedId); + john.ShouldBeNull(); + } } } } diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/nl.json b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/nl.json new file mode 100644 index 0000000000..c3c0818b03 --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/nl.json @@ -0,0 +1,7 @@ +{ + "culture": "nl", + "texts": { + "HelloText": "Hallo {0}", + "HowAreYou": "hoe is het met je?" + } +} \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/nl.json b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/nl.json index 64a1a70124..efd751859e 100644 --- a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/nl.json +++ b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/nl.json @@ -3,9 +3,9 @@ "texts": { "UserName": "Gebruikersnaam", "EmailAddress": "E-mailadres", - "UserNameOrEmailAddress": "Gebruikersnaam of e-mail adres", + "UserNameOrEmailAddress": "Gebruikersnaam of e-mailadres", "Password": "Wachtwoord", - "RememberMe": "Herinner me", + "RememberMe": "Onthoud me", "UseAnotherServiceToLogin": "Gebruik een andere dienst om in te loggen", "UserLockedOutMessage": "Het gebruikersaccount is geblokkeerd vanwege ongeldige inlogpogingen. Wacht even en probeer het opnieuw.", "InvalidUserNameOrPassword": "Ongeldige gebruikersnaam of wachtwoord!", @@ -29,17 +29,37 @@ "DisplayName:Name": "Naam", "DisplayName:Surname": "Achternaam", "DisplayName:Password": "Wachtwoord", - "DisplayName:EmailAddress": "E-mail adres", + "DisplayName:EmailAddress": "E-mailadres", "DisplayName:PhoneNumber": "Telefoonnummer", "PersonalSettings": "Persoonlijke instellingen", "PersonalSettingsSaved": "Persoonlijke instellingen opgeslagen", - "PasswordChanged": "wachtwoord veranderd", - "NewPasswordConfirmFailed": "Bevestig het nieuwe wachtwoord a.u.b..", + "PasswordChanged": "Wachtwoord veranderd", + "NewPasswordConfirmFailed": "Bevestig het nieuwe wachtwoord a.u.b.", "Manage": "Beheer", "ManageYourProfile": "Beheer uw profiel", "DisplayName:Abp.Account.IsSelfRegistrationEnabled": "Is zelfregistratie ingeschakeld", "Description:Abp.Account.IsSelfRegistrationEnabled": "Of een gebruiker het account zelf kan registreren.", "DisplayName:Abp.Account.EnableLocalLogin": "Verifieer met een lokaal account", - "Description:Abp.Account.EnableLocalLogin": "Geeft aan of de server gebruikers toestaat zich te verifiëren met een lokaal account." + "Description:Abp.Account.EnableLocalLogin": "Geeft aan of de server gebruikers toestaat zich te verifiëren met een lokaal account.", + "LoggedOutTitle": "Uitgelogd", + "LoggedOutText": "U bent uitgelogd en u wordt binnen enkele ogenblikken doorgestuurd.", + "ReturnToText": "Klik hier om doorgestuurd te worden naar {0}", + "OrLoginWith": "Of log in met:", + "ForgotPassword": "Wachtwoord vergeten?", + "SendPasswordResetLink_Information": "Er wordt een link voor het opnieuw instellen van uw wachtwoord naar uw e-mailadres gestuurd. Als u binnen een paar minuten geen e-mail ontvangt, probeer het dan opnieuw.", + "PasswordResetMailSentMessage": "Er is een link voor het opnieuw instellen van uw wachtwoord naar uw e-mailadres gestuurd. Als u deze e-mail niet binnen 15 minuten in uw inbox ziet, zoek hem dan in uw map met ongewenste e-mail. Als u de mail daar vindt, markeer hem dan als niet ongewenst.", + "ResetPassword": "Wachtwoord opnieuw instellen", + "ConfirmPassword": "Bevestig (herhaal) het wachtwoord", + "ResetPassword_Information": "Voer uw nieuwe wachtwoord in.", + "YourPasswordIsSuccessfullyReset": "Uw wachtwoord is succesvol opnieuw ingesteld.", + "GoToTheApplication": "Ga naar de applicatie", + "BackToLogin": "Terug naar Inloggen", + "ProfileTab:Password": "Wachtwoord wijzigen", + "ProfileTab:PersonalInfo": "Persoonlijke informatie", + "ReturnToApplication": "Ga terug naar de applicatie", + "Volo.Account:InvalidEmailAddress": "Kan het opgegeven e-mailadres '{0}' niet vinden", + "PasswordReset": "Wachtwoord opnieuw instellen", + "PasswordResetInfoInEmail": "We hebben een verzoek ontvangen om uw wachtwoord opnieuw in te stellen. Als u dit verzoek heeft ingediend, klikt u op de volgende link om een nieuw wachtwoord in te stellen.", + "ResetMyPassword": "Reset mijn wachtwoord" } -} +} \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AccountEmailer.cs b/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AccountEmailer.cs index baa762c840..1d7379bd04 100644 --- a/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AccountEmailer.cs +++ b/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AccountEmailer.cs @@ -72,7 +72,7 @@ namespace Volo.Abp.Account.Emailing ); } - private string NormalizeReturnUrl(string returnUrl) + protected virtual string NormalizeReturnUrl(string returnUrl) { if (returnUrl.IsNullOrEmpty()) { diff --git a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/Localization/nl.json b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/Localization/nl.json new file mode 100644 index 0000000000..0d295d59b3 --- /dev/null +++ b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/Localization/nl.json @@ -0,0 +1,6 @@ +{ + "culture": "nl", + "texts": { + "ManageYourProfile": "Beheer uw profiel" + } +} \ No newline at end of file diff --git a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs index 57b49409fc..d34f42aa6f 100644 --- a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs +++ b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/CmsKitHttpApiHostModule.cs @@ -22,6 +22,7 @@ using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; using Volo.Abp.AspNetCore.Serilog; using Volo.Abp.AuditLogging.EntityFrameworkCore; using Volo.Abp.Autofac; +using Volo.Abp.BlobStoring.Database.EntityFrameworkCore; using Volo.Abp.Caching; using Volo.Abp.Caching.StackExchangeRedis; using Volo.Abp.EntityFrameworkCore; @@ -47,7 +48,8 @@ namespace Volo.CmsKit typeof(AbpAuditLoggingEntityFrameworkCoreModule), typeof(AbpPermissionManagementEntityFrameworkCoreModule), typeof(AbpSettingManagementEntityFrameworkCoreModule), - typeof(AbpAspNetCoreSerilogModule) + typeof(AbpAspNetCoreSerilogModule), + typeof(BlobStoringDatabaseEntityFrameworkCoreModule) )] public class CmsKitHttpApiHostModule : AbpModule { diff --git a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/EntityFrameworkCore/CmsKitHttpApiHostMigrationsDbContext.cs b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/EntityFrameworkCore/CmsKitHttpApiHostMigrationsDbContext.cs index c31c977ebe..d833e84caa 100644 --- a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/EntityFrameworkCore/CmsKitHttpApiHostMigrationsDbContext.cs +++ b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/EntityFrameworkCore/CmsKitHttpApiHostMigrationsDbContext.cs @@ -1,4 +1,5 @@ using Microsoft.EntityFrameworkCore; +using Volo.Abp.BlobStoring.Database.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; namespace Volo.CmsKit.EntityFrameworkCore @@ -16,6 +17,7 @@ namespace Volo.CmsKit.EntityFrameworkCore base.OnModelCreating(modelBuilder); modelBuilder.ConfigureCmsKit(); + modelBuilder.ConfigureBlobStoring(); } } } diff --git a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Migrations/20201231111745_Initial.Designer.cs b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Migrations/20201231111745_Initial.Designer.cs new file mode 100644 index 0000000000..28e6976776 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Migrations/20201231111745_Initial.Designer.cs @@ -0,0 +1,531 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Migrations +{ + [DbContext(typeof(CmsKitHttpApiHostMigrationsDbContext))] + [Migration("20201231111745_Initial")] + partial class Initial + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseIdentityColumns() + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.1"); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ContainerId") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasMaxLength(2147483647) + .HasColumnType("varbinary(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ContainerId"); + + b.HasIndex("TenantId", "ContainerId", "Name"); + + b.ToTable("AbpBlobs"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("AbpBlobContainers"); + }); + + modelBuilder.Entity("Volo.CmsKit.Comments.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("RepliedCommentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "RepliedCommentId"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsComments"); + }); + + modelBuilder.Entity("Volo.CmsKit.Contents.Content", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2147483647) + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsContents"); + }); + + modelBuilder.Entity("Volo.CmsKit.Pages.Page", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Url") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Url"); + + b.ToTable("CmsPages"); + }); + + modelBuilder.Entity("Volo.CmsKit.Ratings.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("StarCount") + .HasColumnType("smallint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "CreatorId"); + + b.ToTable("CmsRatings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Reactions.UserReaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ReactionName") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "ReactionName"); + + b.HasIndex("TenantId", "CreatorId", "EntityType", "EntityId", "ReactionName"); + + b.ToTable("CmsUserReactions"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.EntityTag", b => + { + b.Property("EntityId") + .HasColumnType("nvarchar(450)"); + + b.Property("TagId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("EntityId", "TagId"); + + b.HasIndex("TenantId", "EntityId", "TagId"); + + b.ToTable("CmsEntityTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("CmsTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Users.CmsUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Email"); + + b.HasIndex("TenantId", "UserName"); + + b.ToTable("CmsUsers"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.HasOne("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", null) + .WithMany() + .HasForeignKey("ContainerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Migrations/20201231111745_Initial.cs b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Migrations/20201231111745_Initial.cs new file mode 100644 index 0000000000..55f1ed7245 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Migrations/20201231111745_Initial.cs @@ -0,0 +1,309 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Volo.CmsKit.Migrations +{ + public partial class Initial : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AbpBlobContainers", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpBlobContainers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CmsComments", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + EntityType = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + EntityId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Text = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: false), + RepliedCommentId = table.Column(type: "uniqueidentifier", nullable: true), + CreatorId = table.Column(type: "uniqueidentifier", nullable: false), + CreationTime = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CmsComments", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CmsContents", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + EntityType = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + EntityId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Value = table.Column(type: "nvarchar(max)", maxLength: 2147483647, nullable: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_CmsContents", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CmsEntityTags", + columns: table => new + { + TagId = table.Column(type: "uniqueidentifier", nullable: false), + EntityId = table.Column(type: "nvarchar(450)", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_CmsEntityTags", x => new { x.EntityId, x.TagId }); + }); + + migrationBuilder.CreateTable( + name: "CmsPages", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Title = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Url = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Description = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_CmsPages", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CmsRatings", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + EntityType = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + EntityId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + StarCount = table.Column(type: "smallint", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: false), + CreationTime = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CmsRatings", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CmsTags", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + EntityType = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Name = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_CmsTags", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CmsUserReactions", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + EntityType = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + EntityId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + ReactionName = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: false), + CreationTime = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CmsUserReactions", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CmsUsers", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Name = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + Surname = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + EmailConfirmed = table.Column(type: "bit", nullable: false, defaultValue: false), + PhoneNumber = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: true), + PhoneNumberConfirmed = table.Column(type: "bit", nullable: false, defaultValue: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_CmsUsers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AbpBlobs", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + ContainerId = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Content = table.Column(type: "varbinary(max)", maxLength: 2147483647, nullable: true), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpBlobs", x => x.Id); + table.ForeignKey( + name: "FK_AbpBlobs_AbpBlobContainers_ContainerId", + column: x => x.ContainerId, + principalTable: "AbpBlobContainers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AbpBlobContainers_TenantId_Name", + table: "AbpBlobContainers", + columns: new[] { "TenantId", "Name" }); + + migrationBuilder.CreateIndex( + name: "IX_AbpBlobs_ContainerId", + table: "AbpBlobs", + column: "ContainerId"); + + migrationBuilder.CreateIndex( + name: "IX_AbpBlobs_TenantId_ContainerId_Name", + table: "AbpBlobs", + columns: new[] { "TenantId", "ContainerId", "Name" }); + + migrationBuilder.CreateIndex( + name: "IX_CmsComments_TenantId_EntityType_EntityId", + table: "CmsComments", + columns: new[] { "TenantId", "EntityType", "EntityId" }); + + migrationBuilder.CreateIndex( + name: "IX_CmsComments_TenantId_RepliedCommentId", + table: "CmsComments", + columns: new[] { "TenantId", "RepliedCommentId" }); + + migrationBuilder.CreateIndex( + name: "IX_CmsContents_TenantId_EntityType_EntityId", + table: "CmsContents", + columns: new[] { "TenantId", "EntityType", "EntityId" }); + + migrationBuilder.CreateIndex( + name: "IX_CmsEntityTags_TenantId_EntityId_TagId", + table: "CmsEntityTags", + columns: new[] { "TenantId", "EntityId", "TagId" }); + + migrationBuilder.CreateIndex( + name: "IX_CmsPages_TenantId_Url", + table: "CmsPages", + columns: new[] { "TenantId", "Url" }); + + migrationBuilder.CreateIndex( + name: "IX_CmsRatings_TenantId_EntityType_EntityId_CreatorId", + table: "CmsRatings", + columns: new[] { "TenantId", "EntityType", "EntityId", "CreatorId" }); + + migrationBuilder.CreateIndex( + name: "IX_CmsTags_TenantId_Name", + table: "CmsTags", + columns: new[] { "TenantId", "Name" }); + + migrationBuilder.CreateIndex( + name: "IX_CmsUserReactions_TenantId_CreatorId_EntityType_EntityId_ReactionName", + table: "CmsUserReactions", + columns: new[] { "TenantId", "CreatorId", "EntityType", "EntityId", "ReactionName" }); + + migrationBuilder.CreateIndex( + name: "IX_CmsUserReactions_TenantId_EntityType_EntityId_ReactionName", + table: "CmsUserReactions", + columns: new[] { "TenantId", "EntityType", "EntityId", "ReactionName" }); + + migrationBuilder.CreateIndex( + name: "IX_CmsUsers_TenantId_Email", + table: "CmsUsers", + columns: new[] { "TenantId", "Email" }); + + migrationBuilder.CreateIndex( + name: "IX_CmsUsers_TenantId_UserName", + table: "CmsUsers", + columns: new[] { "TenantId", "UserName" }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AbpBlobs"); + + migrationBuilder.DropTable( + name: "CmsComments"); + + migrationBuilder.DropTable( + name: "CmsContents"); + + migrationBuilder.DropTable( + name: "CmsEntityTags"); + + migrationBuilder.DropTable( + name: "CmsPages"); + + migrationBuilder.DropTable( + name: "CmsRatings"); + + migrationBuilder.DropTable( + name: "CmsTags"); + + migrationBuilder.DropTable( + name: "CmsUserReactions"); + + migrationBuilder.DropTable( + name: "CmsUsers"); + + migrationBuilder.DropTable( + name: "AbpBlobContainers"); + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Migrations/CmsKitHttpApiHostMigrationsDbContextModelSnapshot.cs b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Migrations/CmsKitHttpApiHostMigrationsDbContextModelSnapshot.cs new file mode 100644 index 0000000000..cd29086668 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Migrations/CmsKitHttpApiHostMigrationsDbContextModelSnapshot.cs @@ -0,0 +1,529 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Migrations +{ + [DbContext(typeof(CmsKitHttpApiHostMigrationsDbContext))] + partial class CmsKitHttpApiHostMigrationsDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseIdentityColumns() + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.1"); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ContainerId") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasMaxLength(2147483647) + .HasColumnType("varbinary(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ContainerId"); + + b.HasIndex("TenantId", "ContainerId", "Name"); + + b.ToTable("AbpBlobs"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("AbpBlobContainers"); + }); + + modelBuilder.Entity("Volo.CmsKit.Comments.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("RepliedCommentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "RepliedCommentId"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsComments"); + }); + + modelBuilder.Entity("Volo.CmsKit.Contents.Content", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2147483647) + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsContents"); + }); + + modelBuilder.Entity("Volo.CmsKit.Pages.Page", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Url") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Url"); + + b.ToTable("CmsPages"); + }); + + modelBuilder.Entity("Volo.CmsKit.Ratings.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("StarCount") + .HasColumnType("smallint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "CreatorId"); + + b.ToTable("CmsRatings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Reactions.UserReaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ReactionName") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "ReactionName"); + + b.HasIndex("TenantId", "CreatorId", "EntityType", "EntityId", "ReactionName"); + + b.ToTable("CmsUserReactions"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.EntityTag", b => + { + b.Property("EntityId") + .HasColumnType("nvarchar(450)"); + + b.Property("TagId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("EntityId", "TagId"); + + b.HasIndex("TenantId", "EntityId", "TagId"); + + b.ToTable("CmsEntityTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("CmsTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Users.CmsUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Email"); + + b.HasIndex("TenantId", "UserName"); + + b.ToTable("CmsUsers"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.HasOne("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", null) + .WithMany() + .HasForeignKey("ContainerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Volo.CmsKit.HttpApi.Host.csproj b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Volo.CmsKit.HttpApi.Host.csproj index 688c47bc87..2fc36d2f4b 100644 --- a/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Volo.CmsKit.HttpApi.Host.csproj +++ b/modules/cms-kit/host/Volo.CmsKit.HttpApi.Host/Volo.CmsKit.HttpApi.Host.csproj @@ -24,6 +24,7 @@ + diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs index 2055266d20..b9f562bf98 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs @@ -15,6 +15,7 @@ using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; using Volo.Abp.AspNetCore.Serilog; using Volo.Abp.AuditLogging.EntityFrameworkCore; using Volo.Abp.Autofac; +using Volo.Abp.BlobStoring.Database.EntityFrameworkCore; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore.SqlServer; @@ -63,8 +64,9 @@ namespace Volo.CmsKit typeof(AbpTenantManagementApplicationModule), typeof(AbpTenantManagementEntityFrameworkCoreModule), typeof(AbpAspNetCoreMvcUiBasicThemeModule), - typeof(AbpAspNetCoreSerilogModule) - )] + typeof(AbpAspNetCoreSerilogModule), + typeof(BlobStoringDatabaseEntityFrameworkCoreModule) + )] public class CmsKitWebUnifiedModule : AbpModule { public override void PreConfigureServices(ServiceConfigurationContext context) diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContext.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContext.cs index d1b31e0ae7..fe6c11b300 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContext.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/EntityFrameworkCore/UnifiedDbContext.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using Volo.Abp.AuditLogging.EntityFrameworkCore; +using Volo.Abp.BlobStoring.Database.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.FeatureManagement.EntityFrameworkCore; using Volo.Abp.Identity.EntityFrameworkCore; @@ -28,6 +29,7 @@ namespace Volo.CmsKit.EntityFrameworkCore modelBuilder.ConfigureTenantManagement(); modelBuilder.ConfigureFeatureManagement(); modelBuilder.ConfigureCmsKit(); + modelBuilder.ConfigureBlobStoring(); } } } diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20201231111657_Added_Blob_Storing.Designer.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20201231111657_Added_Blob_Storing.Designer.cs new file mode 100644 index 0000000000..15e01fa673 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20201231111657_Added_Blob_Storing.Designer.cs @@ -0,0 +1,1725 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Migrations +{ + [DbContext(typeof(UnifiedDbContext))] + [Migration("20201231111657_Added_Blob_Storing")] + partial class Added_Blob_Storing + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseIdentityColumns() + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.1"); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)") + .HasColumnName("ApplicationName"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("BrowserInfo"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientId"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientIpAddress"); + + b.Property("ClientName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("ClientName"); + + b.Property("Comments") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Comments"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("CorrelationId"); + + b.Property("Exceptions") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)") + .HasColumnName("Exceptions"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("HttpMethod") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("HttpMethod"); + + b.Property("HttpStatusCode") + .HasColumnType("int") + .HasColumnName("HttpStatusCode"); + + b.Property("ImpersonatorTenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorTenantId"); + + b.Property("ImpersonatorUserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorUserId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasColumnType("nvarchar(max)"); + + b.Property("Url") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Url"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("UserId"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ExecutionTime"); + + b.HasIndex("TenantId", "UserId", "ExecutionTime"); + + b.ToTable("AbpAuditLogs"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2") + .HasColumnName("ExecutionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("MethodName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("MethodName"); + + b.Property("Parameters") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)") + .HasColumnName("Parameters"); + + b.Property("ServiceName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("ServiceName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); + + b.ToTable("AbpAuditLogActions"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ChangeTime") + .HasColumnType("datetime2") + .HasColumnName("ChangeTime"); + + b.Property("ChangeType") + .HasColumnType("tinyint") + .HasColumnName("ChangeType"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityId"); + + b.Property("EntityTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityTypeFullName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityTypeFullName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); + + b.ToTable("AbpEntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("EntityChangeId") + .HasColumnType("uniqueidentifier"); + + b.Property("NewValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("NewValue"); + + b.Property("OriginalValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("OriginalValue"); + + b.Property("PropertyName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("PropertyName"); + + b.Property("PropertyTypeFullName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("PropertyTypeFullName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("EntityChangeId"); + + b.ToTable("AbpEntityPropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ContainerId") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasMaxLength(2147483647) + .HasColumnType("varbinary(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ContainerId"); + + b.HasIndex("TenantId", "ContainerId", "Name"); + + b.ToTable("AbpBlobs"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("AbpBlobContainers"); + }); + + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpFeatureValues"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Regex") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RegexDescription") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ValueType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("SourceTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId") + .IsUnique() + .HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); + + b.ToTable("AbpLinkUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("bit") + .HasColumnName("IsDefault"); + + b.Property("IsPublic") + .HasColumnType("bit") + .HasColumnName("IsPublic"); + + b.Property("IsStatic") + .HasColumnType("bit") + .HasColumnName("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Action") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Identity") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Action"); + + b.HasIndex("TenantId", "ApplicationName"); + + b.HasIndex("TenantId", "Identity"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSecurityLogs"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0) + .HasColumnName("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsExternal") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsExternal"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("LockoutEnabled"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("NormalizedEmail") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedEmail"); + + b.Property("NormalizedUserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedUserName"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("PasswordHash"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("SecurityStamp"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("TwoFactorEnabled"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(196) + .HasColumnType("nvarchar(196)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "UserId"); + + b.HasIndex("UserId", "OrganizationUnitId"); + + b.ToTable("AbpUserOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(95) + .HasColumnType("nvarchar(95)") + .HasColumnName("Code"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("ParentId"); + + b.ToTable("AbpOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "RoleId"); + + b.HasIndex("RoleId", "OrganizationUnitId"); + + b.ToTable("AbpOrganizationUnitRoles"); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpPermissionGrants"); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpSettings"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AbpTenants"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.HasKey("TenantId", "Name"); + + b.ToTable("AbpTenantConnectionStrings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Comments.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("RepliedCommentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "RepliedCommentId"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsComments"); + }); + + modelBuilder.Entity("Volo.CmsKit.Contents.Content", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2147483647) + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsContents"); + }); + + modelBuilder.Entity("Volo.CmsKit.Pages.Page", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Url") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Url"); + + b.ToTable("CmsPages"); + }); + + modelBuilder.Entity("Volo.CmsKit.Ratings.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("StarCount") + .HasColumnType("smallint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "CreatorId"); + + b.ToTable("CmsRatings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Reactions.UserReaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ReactionName") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "ReactionName"); + + b.HasIndex("TenantId", "CreatorId", "EntityType", "EntityId", "ReactionName"); + + b.ToTable("CmsUserReactions"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.EntityTag", b => + { + b.Property("EntityId") + .HasColumnType("nvarchar(450)"); + + b.Property("TagId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("EntityId", "TagId"); + + b.HasIndex("TenantId", "EntityId", "TagId"); + + b.ToTable("CmsEntityTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("CmsTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Users.CmsUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Email"); + + b.HasIndex("TenantId", "UserName"); + + b.ToTable("CmsUsers"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("Actions") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("EntityChanges") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.EntityChange", null) + .WithMany("PropertyChanges") + .HasForeignKey("EntityChangeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.HasOne("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", null) + .WithMany() + .HasForeignKey("ContainerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("OrganizationUnits") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Tokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("ParentId"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany("Roles") + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.HasOne("Volo.Abp.TenantManagement.Tenant", null) + .WithMany("ConnectionStrings") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Navigation("Actions"); + + b.Navigation("EntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Navigation("PropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Navigation("Claims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Navigation("Claims"); + + b.Navigation("Logins"); + + b.Navigation("OrganizationUnits"); + + b.Navigation("Roles"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Navigation("ConnectionStrings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20201231111657_Added_Blob_Storing.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20201231111657_Added_Blob_Storing.cs new file mode 100644 index 0000000000..11cf1901fa --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20201231111657_Added_Blob_Storing.cs @@ -0,0 +1,95 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Volo.CmsKit.Migrations +{ + public partial class Added_Blob_Storing : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Description", + table: "CmsPages", + type: "nvarchar(512)", + maxLength: 512, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(515)", + oldMaxLength: 515, + oldNullable: true); + + migrationBuilder.CreateTable( + name: "AbpBlobContainers", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpBlobContainers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AbpBlobs", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + ContainerId = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Content = table.Column(type: "varbinary(max)", maxLength: 2147483647, nullable: true), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpBlobs", x => x.Id); + table.ForeignKey( + name: "FK_AbpBlobs_AbpBlobContainers_ContainerId", + column: x => x.ContainerId, + principalTable: "AbpBlobContainers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AbpBlobContainers_TenantId_Name", + table: "AbpBlobContainers", + columns: new[] { "TenantId", "Name" }); + + migrationBuilder.CreateIndex( + name: "IX_AbpBlobs_ContainerId", + table: "AbpBlobs", + column: "ContainerId"); + + migrationBuilder.CreateIndex( + name: "IX_AbpBlobs_TenantId_ContainerId_Name", + table: "AbpBlobs", + columns: new[] { "TenantId", "ContainerId", "Name" }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AbpBlobs"); + + migrationBuilder.DropTable( + name: "AbpBlobContainers"); + + migrationBuilder.AlterColumn( + name: "Description", + table: "CmsPages", + type: "nvarchar(515)", + maxLength: 515, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(512)", + oldMaxLength: 512, + oldNullable: true); + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs index 37622217c5..074d655f16 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs @@ -273,6 +273,79 @@ namespace Volo.CmsKit.Migrations b.ToTable("AbpEntityPropertyChanges"); }); + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ContainerId") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasMaxLength(2147483647) + .HasColumnType("varbinary(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ContainerId"); + + b.HasIndex("TenantId", "ContainerId", "Name"); + + b.ToTable("AbpBlobs"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("AbpBlobContainers"); + }); + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b => { b.Property("Id") @@ -1197,8 +1270,8 @@ namespace Volo.CmsKit.Migrations .HasColumnName("DeletionTime"); b.Property("Description") - .HasMaxLength(515) - .HasColumnType("nvarchar(515)"); + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); b.Property("ExtraProperties") .HasColumnType("nvarchar(max)") @@ -1499,6 +1572,15 @@ namespace Volo.CmsKit.Migrations .IsRequired(); }); + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.HasOne("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", null) + .WithMany() + .HasForeignKey("ContainerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => { b.HasOne("Volo.Abp.Identity.IdentityRole", null) diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Volo.CmsKit.Web.Unified.csproj b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Volo.CmsKit.Web.Unified.csproj index 152d740864..1dbafb4ad6 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Volo.CmsKit.Web.Unified.csproj +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Volo.CmsKit.Web.Unified.csproj @@ -32,6 +32,7 @@ + diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CheckUrlInputDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CheckUrlInputDto.cs deleted file mode 100644 index abb1d81c12..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CheckUrlInputDto.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Volo.CmsKit.Admin.Pages -{ - public class CheckUrlInputDto - { - [Required] - public string Url { get; set; } - } -} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageInputDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageInputDto.cs index 50c7a68f32..d2ddfe6e88 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageInputDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageInputDto.cs @@ -1,15 +1,21 @@ using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; +using Volo.CmsKit.Contents; +using Volo.CmsKit.Pages; namespace Volo.CmsKit.Admin.Pages { public class CreatePageInputDto { [Required] + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))] public string Title { get; set; } [Required] + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxUrlLength))] public string Url { get; set; } + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxDescriptionLength))] public string Description { get; set; } } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageWithContentInputDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageWithContentInputDto.cs deleted file mode 100644 index bff09b595b..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageWithContentInputDto.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Volo.CmsKit.Admin.Pages -{ - public class CreatePageWithContentInputDto - { - [Required] - public string Title { get; set; } - - [Required] - public string Url { get; set; } - - public string Description { get; set; } - - [Required] - public string Content { get; set; } - } -} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/GetPagesInputDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/GetPagesInputDto.cs new file mode 100644 index 0000000000..8523eeeffa --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/GetPagesInputDto.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Application.Dtos; + +namespace Volo.CmsKit.Admin.Pages +{ + public class GetPagesInputDto : PagedAndSortedResultRequestDto + { + public string Filter { get; set; } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/IPageAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/IPageAdminAppService.cs index 048d2d89c7..6ac96bbbfa 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/IPageAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/IPageAdminAppService.cs @@ -1,22 +1,11 @@ using System; using System.Threading.Tasks; +using Volo.Abp.Application.Services; +using Volo.Abp.Content; namespace Volo.CmsKit.Admin.Pages { - public interface IPageAdminAppService + public interface IPageAdminAppService : ICrudAppService { - Task GetAsync(Guid id); - - Task CreatePageAsync(CreatePageInputDto input); - - Task CreatePageWithContentAsync(CreatePageWithContentInputDto input); - - Task UpdatePageAsync(Guid id, UpdatePageInputDto input); - - Task DoesUrlExistAsync(CheckUrlInputDto input); - - Task UpdatePageContentAsync(Guid id, UpdatePageContentInputDto input); - - Task DeleteAsync(Guid id); } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/PageWithContentDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/PageWithContentDto.cs deleted file mode 100644 index 119dedb041..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/PageWithContentDto.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using Volo.Abp.Application.Dtos; -using Volo.CmsKit.Admin.Contents; - -namespace Volo.CmsKit.Admin.Pages -{ - public class PageWithContentDto : EntityDto - { - public string Title { get; set; } - - public string Url { get; set; } - - public string Description { get; set; } - - public ContentDto Content { get; set; } - } -} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageContentInputDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageContentInputDto.cs deleted file mode 100644 index f6d46167c8..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageContentInputDto.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Volo.CmsKit.Admin.Pages -{ - public class UpdatePageContentInputDto - { - [Required] - public string Content { get; set; } - } -} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageInputDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageInputDto.cs index eb831fee45..17b3c948bd 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageInputDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageInputDto.cs @@ -1,15 +1,21 @@ using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; +using Volo.CmsKit.Contents; +using Volo.CmsKit.Pages; namespace Volo.CmsKit.Admin.Pages { public class UpdatePageInputDto { [Required] + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))] public string Title { get; set; } [Required] + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxUrlLength))] public string Url { get; set; } + [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxDescriptionLength))] public string Description { get; set; } } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs index 34c7947d67..bc55cc14e1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs @@ -27,6 +27,14 @@ namespace Volo.CmsKit.Permissions tagGroup.AddChild(CmsKitAdminPermissions.Tags.Update, L("Permission:TagManagement.Update")); tagGroup.AddChild(CmsKitAdminPermissions.Tags.Delete, L("Permission:TagManagement.Delete")); } + + if (GlobalFeatureManager.Instance.IsEnabled()) + { + var pageManagement = cmsGroup.AddPermission(CmsKitAdminPermissions.Pages.Default, L("Permission:PageManagement")); + pageManagement.AddChild(CmsKitAdminPermissions.Pages.Create, L("Permission:PageManagement:Create")); + pageManagement.AddChild(CmsKitAdminPermissions.Pages.Update, L("Permission:PageManagement:Update")); + pageManagement.AddChild(CmsKitAdminPermissions.Pages.Delete, L("Permission:PageManagement:Delete")); + } } private static LocalizableString L(string name) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs index 55bffff67f..a08ba9d6c8 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs @@ -5,6 +5,7 @@ namespace Volo.CmsKit.Permissions public class CmsKitAdminPermissions { public const string GroupName = "CmsKit"; + public static class Tags { public const string Default = GroupName + ".Tags"; @@ -12,7 +13,7 @@ namespace Volo.CmsKit.Permissions public const string Update = Default + ".Update"; public const string Delete = Default + ".Delete"; } - + public static class Contents { public const string Default = GroupName + ".Contents"; @@ -20,5 +21,13 @@ namespace Volo.CmsKit.Permissions public const string Update = Default + ".Update"; public const string Delete = Default + ".Delete"; } + + public static class Pages + { + public const string Default = GroupName + ".Pages"; + public const string Create = Default + ".Create"; + public const string Update = Default + ".Update"; + public const string Delete = Default + ".Delete"; + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs index 6778dd7916..6223ed9c2e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs @@ -1,21 +1,24 @@ using System; -using System.Threading; +using System.Collections.Generic; using System.Threading.Tasks; -using Volo.Abp; -using Volo.CmsKit.Contents; +using Microsoft.AspNetCore.Authorization; +using Volo.Abp.Application.Dtos; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Pages; +using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.Pages { + [RequiresGlobalFeature(typeof(PagesFeature))] + [Authorize(CmsKitAdminPermissions.Pages.Default)] public class PageAdminAppService : CmsKitAdminAppServiceBase, IPageAdminAppService { protected readonly IPageRepository PageRepository; - protected readonly IContentRepository ContentRepository; - - public PageAdminAppService(IPageRepository pageRepository, IContentRepository contentRepository) + + public PageAdminAppService(IPageRepository pageRepository) { PageRepository = pageRepository; - ContentRepository = contentRepository; } public virtual async Task GetAsync(Guid id) @@ -25,34 +28,37 @@ namespace Volo.CmsKit.Admin.Pages return ObjectMapper.Map(page); } - public virtual async Task CreatePageAsync(CreatePageInputDto input) + public virtual async Task> GetListAsync(GetPagesInputDto input) { - var page = await CreatePageAsync(input.Title, input.Url, input.Description); - - await PageRepository.InsertAsync(page); + var count = await PageRepository.GetCountAsync(input.Filter); - return ObjectMapper.Map(page); + var pages = await PageRepository.GetListAsync( + input.Filter, + input.MaxResultCount, + input.SkipCount, + input.Sorting + ); + + return new PagedResultDto( + count, + ObjectMapper.Map, List>(pages) + ); } - public virtual async Task CreatePageWithContentAsync(CreatePageWithContentInputDto input) + [Authorize(CmsKitAdminPermissions.Pages.Create)] + public virtual async Task CreateAsync(CreatePageInputDto input) { - var page = await CreatePageAsync(input.Title, input.Url, input.Description); + await CheckPageUrlAsync(input.Url); - await PageRepository.InsertAsync(page); - - var content = new Content( - GuidGenerator.Create(), - nameof(Page), - page.Id.ToString(), - input.Content, - page.TenantId); + var page = new Page(GuidGenerator.Create(), input.Title, input.Url, input.Description, CurrentTenant?.Id); - await ContentRepository.InsertAsync(content); + await PageRepository.InsertAsync(page); return ObjectMapper.Map(page); } - public virtual async Task UpdatePageAsync(Guid id, UpdatePageInputDto input) + [Authorize(CmsKitAdminPermissions.Pages.Update)] + public virtual async Task UpdateAsync(Guid id, UpdatePageInputDto input) { var page = await PageRepository.GetAsync(id); @@ -66,42 +72,21 @@ namespace Volo.CmsKit.Admin.Pages page.Description = input.Description; await PageRepository.UpdateAsync(page); - - return ObjectMapper.Map(page); - } - - public virtual Task DoesUrlExistAsync(CheckUrlInputDto input) - { - return PageRepository.DoesExistAsync(input.Url); - } - - public virtual async Task UpdatePageContentAsync(Guid id, UpdatePageContentInputDto input) - { - var pageContent = await ContentRepository.GetAsync(nameof(Page), id.ToString()); - pageContent.SetValue(input.Content); - - await ContentRepository.UpdateAsync(pageContent); + return ObjectMapper.Map(page); } + [Authorize(CmsKitAdminPermissions.Pages.Delete)] public virtual async Task DeleteAsync(Guid id) { - await ContentRepository.DeleteAsync(nameof(Page), id.ToString(), CurrentTenant?.Id, CancellationToken.None); - await PageRepository.DeleteAsync(id, cancellationToken: CancellationToken.None); - } - - protected virtual async Task CreatePageAsync(string title, string url, string description) - { - await CheckPageUrlAsync(url); - - return new Page(GuidGenerator.Create(), title, url, description, CurrentTenant?.Id); + await PageRepository.DeleteAsync(id); } protected virtual async Task CheckPageUrlAsync(string url) { - if (await PageRepository.DoesExistAsync(url)) + if (await PageRepository.ExistsAsync(url)) { - throw new UserFriendlyException("Url exist"); + throw new PageUrlAlreadyExistException(url); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Page/PageAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Page/PageAdminController.cs deleted file mode 100644 index 4e37848e37..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Page/PageAdminController.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Volo.Abp; -using Volo.CmsKit.Admin.Pages; - -namespace Volo.CmsKit.Admin.Page -{ - [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] - [Area("cms-kit")] - [Route("api/cms-kit-admin/pages")] - public class PageAdminController : CmsKitAdminController, IPageAdminAppService - { - protected readonly IPageAdminAppService PageAdminAppService; - - public PageAdminController(IPageAdminAppService pageAdminAppService) - { - PageAdminAppService = pageAdminAppService; - } - - [HttpGet] - [Route("{id}")] - public virtual Task GetAsync(Guid id) - { - return PageAdminAppService.GetAsync(id); - } - - [HttpPost] - [Route("create")] - public virtual Task CreatePageAsync(CreatePageInputDto input) - { - return PageAdminAppService.CreatePageAsync(input); - } - - [HttpPost] - [Route("create-with-content")] - public virtual Task CreatePageWithContentAsync(CreatePageWithContentInputDto input) - { - return PageAdminAppService.CreatePageWithContentAsync(input); - } - - [HttpPut] - [Route("{id}")] - public virtual Task UpdatePageAsync(Guid id, UpdatePageInputDto input) - { - return PageAdminAppService.UpdatePageAsync(id, input); - } - - [HttpPost] - [Route("does-url-exist")] - public virtual Task DoesUrlExistAsync(CheckUrlInputDto input) - { - return PageAdminAppService.DoesUrlExistAsync(input); - } - - [HttpPut] - [Route("update-content/{id}")] - public virtual Task UpdatePageContentAsync(Guid id, UpdatePageContentInputDto input) - { - return PageAdminAppService.UpdatePageContentAsync(id, input); - } - - [HttpDelete] - [Route("{id}")] - public virtual Task DeleteAsync(Guid id) - { - return PageAdminAppService.DeleteAsync(id); - } - } -} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Pages/PageAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Pages/PageAdminController.cs new file mode 100644 index 0000000000..810f09330f --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Pages/PageAdminController.cs @@ -0,0 +1,63 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.GlobalFeatures; +using Volo.CmsKit.Permissions; + +namespace Volo.CmsKit.Admin.Pages +{ + [RequiresGlobalFeature(typeof(PagesFeature))] + [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] + [Area("cms-kit")] + [Authorize(CmsKitAdminPermissions.Pages.Default)] + [Route("api/cms-kit-admin/pages")] + public class PageAdminController : CmsKitAdminController, IPageAdminAppService + { + protected readonly IPageAdminAppService PageAdminAppService; + + public PageAdminController(IPageAdminAppService pageAdminAppService) + { + PageAdminAppService = pageAdminAppService; + } + + [HttpGet] + [Route("{id}")] + public virtual Task GetAsync(Guid id) + { + return PageAdminAppService.GetAsync(id); + } + + [HttpGet] + public virtual Task> GetListAsync(GetPagesInputDto input) + { + return PageAdminAppService.GetListAsync(input); + } + + [HttpPost] + [Authorize(CmsKitAdminPermissions.Pages.Create)] + public virtual Task CreateAsync(CreatePageInputDto input) + { + return PageAdminAppService.CreateAsync(input); + } + + [HttpPut] + [Authorize(CmsKitAdminPermissions.Pages.Update)] + [Route("{id}")] + public virtual Task UpdateAsync(Guid id, UpdatePageInputDto input) + { + return PageAdminAppService.UpdateAsync(id, input); + } + + [HttpDelete] + [Authorize(CmsKitAdminPermissions.Pages.Delete)] + [Route("{id}")] + public virtual Task DeleteAsync(Guid id) + { + return PageAdminAppService.DeleteAsync(id); + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs index 4b57a5a52e..67042b5cc6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs @@ -3,6 +3,12 @@ public static class CmsKitErrorCodes { public const string TagAlreadyExist = "CmsKit:0001"; + public const string ContentAlreadyExist = "CmsKit:0002"; + + public static class Pages + { + public const string UrlAlreadyExist = "CmsKit:Page:0001"; + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json index 8ad45af0ff..7ed510da10 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json @@ -17,9 +17,13 @@ "Permission:Contents.Delete": "Delete Content", "Permission:Contents.Update": "Update Content", "Permission:TagManagement": "Tag Management", - "Permission:TagManagement.Create": "Create Tag", - "Permission:TagManagement.Delete": "Delete Tag", - "Permission:TagManagement.Update": "Update Tag", + "Permission:TagManagement.Create": "Create", + "Permission:TagManagement.Delete": "Delete", + "Permission:TagManagement.Update": "Update", + "Permission:PageManagement": "Page Management", + "Permission:PageManagement:Create": "Create", + "Permission:PageManagement:Delete": "Delete", + "Permission:PageManagement:Update": "Update", "PickYourReaction": "Pick your reaction", "RatingUndoMessage": "Your rating will be undo.", "Reply": "Reply", @@ -30,6 +34,7 @@ "Undo": "Undo", "Update": "Update", "YourComment": "Your comment", - "YourReply": "Your reply" + "YourReply": "Your reply", + "CmsKit:Page:0001": "The given url ({0}) already exists." } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/nl.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/nl.json new file mode 100644 index 0000000000..164ffd9138 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/nl.json @@ -0,0 +1,35 @@ +{ + "culture": "nl", + "texts": { + "CmsKit:0002": "Inhoud bestaat al!", + "CommentAuthorizationExceptionMessage": "Die opmerkingen zijn niet toegestaan voor openbare vertoning.", + "Comments": "Opmerkingen", + "Delete": "Verwijderen", + "Edit": "Bewerken", + "LoginToAddComment": "Log in om een opmerking toe te voegen", + "LoginToRate": "Log in om te beoordelen", + "LoginToReply": "Log in om te antwoorden", + "Menu:CMS": "CMS", + "MessageDeletionConfirmationMessage": "Deze opmerking wordt volledig verwijderd.", + "Permission:CmsKit": "CMS-Kit", + "Permission:Contents": "Inhoud beheer", + "Permission:Contents.Create": "Creëer inhoud", + "Permission:Contents.Delete": "Inhoud verwijderen", + "Permission:Contents.Update": "Bewerk inhoud", + "Permission:TagManagement": "Tagbeheer", + "Permission:TagManagement.Create": "Tag Creëer", + "Permission:TagManagement.Delete": "Tag verwijderen", + "Permission:TagManagement.Update": "Tag bewerken", + "PickYourReaction": "Kies uw reactie", + "RatingUndoMessage": "Uw beoordeling wordt ongedaan gemaakt.", + "Reply": "Beantwoorden", + "Send": "verzenden", + "Star": "Star", + "TagDeletionConfirmationMessage": "Weet u zeker dat u de tag '{0}' wilt verwijderen?", + "Tags": "Tags", + "Undo": "Ongedaan maken", + "Update": "Bijwerken", + "YourComment": "Jouw opmerking", + "YourReply": "Uw antwoord" + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json index c081b86fc7..40494fbb39 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json @@ -30,6 +30,7 @@ "Undo": "Geri al", "Update": "Güncelle", "YourComment": "Yorumunuz", - "YourReply": "Cevabınız" + "YourReply": "Cevabınız", + "CmsKit:Page:0001": "Girilen url ({0}) kullanımdadır." } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Pages/PageConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Pages/PageConsts.cs index 105566c2bd..dcafb6a466 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Pages/PageConsts.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Pages/PageConsts.cs @@ -2,10 +2,10 @@ { public class PageConsts { - public static int MaxTitleLength = 256; + public static int MaxTitleLength { get; set; } = 256; + + public static int MaxUrlLength { get; set; } = 256; - public static int MaxUrlLength = 256; - - public static int MaxDescriptionLength = 515; + public static int MaxDescriptionLength { get; set; } = 512; } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/IPageRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/IPageRepository.cs index 95c09474aa..931618f774 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/IPageRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/IPageRepository.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; @@ -6,10 +8,19 @@ namespace Volo.CmsKit.Pages { public interface IPageRepository : IBasicRepository { - Task GetByUrlAsync(string url); + Task GetCountAsync(string filter = null, CancellationToken cancellationToken = default); - Task FindByUrlAsync(string url); + Task> GetListAsync( + string filter = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + string sorting = null, + CancellationToken cancellationToken = default); + + Task GetByUrlAsync(string url, CancellationToken cancellationToken = default); - Task DoesExistAsync(string url); + Task FindByUrlAsync(string url, CancellationToken cancellationToken = default); + + Task ExistsAsync(string url, CancellationToken cancellationToken = default); } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/PageUrlAlreadyExistException.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/PageUrlAlreadyExistException.cs new file mode 100644 index 0000000000..142d03c441 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/PageUrlAlreadyExistException.cs @@ -0,0 +1,23 @@ +using System; +using System.Runtime.Serialization; +using JetBrains.Annotations; +using Volo.Abp; + +namespace Volo.CmsKit.Pages +{ + [Serializable] + public class PageUrlAlreadyExistException : BusinessException + { + public PageUrlAlreadyExistException([NotNull] string url) + { + Code = CmsKitErrorCodes.Pages.UrlAlreadyExist; + WithData(nameof(Page.Url), url); + } + + public PageUrlAlreadyExistException(SerializationInfo serializationInfo, StreamingContext context) + : base(serializationInfo, context) + { + + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Pages/EfCorePageRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Pages/EfCorePageRepository.cs index 93a7df00d2..2fc6d92c52 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Pages/EfCorePageRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Pages/EfCorePageRepository.cs @@ -1,4 +1,8 @@ using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; @@ -13,19 +17,44 @@ namespace Volo.CmsKit.Pages { } - public Task GetByUrlAsync(string url) + public virtual async Task GetCountAsync(string filter = null, CancellationToken cancellationToken = default) { - return GetAsync(x => x.Url == url); + return await (await GetDbSetAsync()).WhereIf( + !filter.IsNullOrWhiteSpace(), + x => + x.Title.Contains(filter) + ).CountAsync(GetCancellationToken(cancellationToken)); } - public Task FindByUrlAsync(string url) + public virtual async Task> GetListAsync( + string filter = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + string sorting = null, + CancellationToken cancellationToken = default) { - return FindAsync(x => x.Url == url); + return await (await GetDbSetAsync()).WhereIf( + !filter.IsNullOrWhiteSpace(), + x => + x.Title.Contains(filter)) + .OrderBy(sorting ?? nameof(Page.Title)) + .PageBy(skipCount, maxResultCount) + .ToListAsync(GetCancellationToken(cancellationToken)); } - public async Task DoesExistAsync(string url) + public virtual Task GetByUrlAsync(string url, CancellationToken cancellationToken = default) { - return await (await GetDbSetAsync()).AnyAsync(x => x.Url == url); + return GetAsync(x => x.Url == url, cancellationToken: GetCancellationToken(cancellationToken)); + } + + public virtual Task FindByUrlAsync(string url, CancellationToken cancellationToken = default) + { + return FindAsync(x => x.Url == url, cancellationToken: GetCancellationToken(cancellationToken)); + } + + public virtual async Task ExistsAsync(string url, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()).AnyAsync(x => x.Url == url, GetCancellationToken(cancellationToken)); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Pages/MongoPageRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Pages/MongoPageRepository.cs index 8537500c96..cc07afcd4b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Pages/MongoPageRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Pages/MongoPageRepository.cs @@ -1,5 +1,10 @@ using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Threading; using System.Threading.Tasks; +using MongoDB.Driver; using MongoDB.Driver.Linq; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.MongoDB; @@ -13,19 +18,52 @@ namespace Volo.CmsKit.MongoDB.Pages { } - public Task GetByUrlAsync(string url) + public virtual async Task GetCountAsync(string filter = null, CancellationToken cancellationToken = default) { - return GetAsync(x => x.Url == url); + var cancellation = GetCancellationToken(cancellationToken); + + return await (await GetMongoQueryableAsync(cancellation)) + .WhereIf>( + !filter.IsNullOrWhiteSpace(), + u => + u.Title.Contains(filter) + ).CountAsync(cancellation); } - public Task FindByUrlAsync(string url) + public virtual async Task> GetListAsync( + string filter = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + string sorting = null, + CancellationToken cancellationToken = default) { - return FindAsync(x => x.Url == url); + var cancellation = GetCancellationToken(cancellationToken); + + return await (await GetMongoQueryableAsync(cancellation)) + .WhereIf>( + !filter.IsNullOrWhiteSpace(), + u => + u.Title.Contains(filter) + ) + .OrderBy(sorting ?? nameof(Page.Title)) + .As>() + .PageBy>(skipCount, maxResultCount) + .ToListAsync(cancellation); } - public async Task DoesExistAsync(string url) + public virtual Task GetByUrlAsync(string url, CancellationToken cancellationToken = default) { - return await (await GetMongoQueryableAsync()).AnyAsync(x => x.Url == url); + return GetAsync(x => x.Url == url, cancellationToken: GetCancellationToken(cancellationToken)); + } + + public virtual Task FindByUrlAsync(string url, CancellationToken cancellationToken = default) + { + return FindAsync(x => x.Url == url, cancellationToken: GetCancellationToken(cancellationToken)); + } + + public virtual async Task ExistsAsync(string url, CancellationToken cancellationToken = default) + { + return await (await GetMongoQueryableAsync(GetCancellationToken(cancellationToken))).AnyAsync(x => x.Url == url, GetCancellationToken(cancellationToken)); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/PageDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/PageDto.cs index 49798d5202..ab8ee9ee80 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/PageDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/PageDto.cs @@ -8,7 +8,5 @@ namespace Volo.CmsKit.Public.Pages public string Title { get; set; } public string Url { get; set; } - - public string Description { get; set; } } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml index 47e73b8b19..c31edaaba8 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml @@ -9,6 +9,5 @@ new { pageId = Model.Page.Id, - title = Model.Page.Title, - description = Model.Page.Description + title = Model.Page.Title }) \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/Default.cshtml index 1f90458ee7..28af196e39 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/Default.cshtml @@ -12,10 +12,11 @@ -

- @Model.Description -

- - @await Component.InvokeAsync(typeof(ContentViewComponent), new { entityType = nameof(Page), entityId = Model.Id.ToString() }) + @await Component.InvokeAsync(typeof(ContentViewComponent), + new + { + entityType = nameof(Page), + entityId = Model.Id.ToString() + })
diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/DefaultPageViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/DefaultPageViewComponent.cs index 450b7ad97e..c3e02b1f90 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/DefaultPageViewComponent.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/DefaultPageViewComponent.cs @@ -21,8 +21,7 @@ namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Pages var model = new PageViewModel { Id = pageId, - Title = title, - Description = description + Title = title }; return View("~/Pages/CmsKit/Shared/Components/Pages/Default.cshtml", model); @@ -34,7 +33,5 @@ namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Pages public Guid Id { get; set; } public string Title { get; set; } - - public string Description { get; set; } } } \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Pages/PageAdminAppService_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Pages/PageAdminAppService_Tests.cs index 59fcc8c8bd..7fa0d934fb 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Pages/PageAdminAppService_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Pages/PageAdminAppService_Tests.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Threading.Tasks; using Shouldly; using Volo.Abp.Uow; @@ -14,16 +15,41 @@ namespace Volo.CmsKit.Pages private readonly IPageAdminAppService _pageAdminAppService; private readonly IPageRepository _pageRepository; - private readonly IContentRepository _contentRepository; public PageAdminAppService_Tests() { _data = GetRequiredService(); _pageAdminAppService = GetRequiredService(); _pageRepository = GetRequiredService(); - _contentRepository = GetRequiredService(); } + [Fact] + public async Task ShouldGetListAsync() + { + var input = new GetPagesInputDto(); + + var pages = await _pageAdminAppService.GetListAsync(input); + + pages.TotalCount.ShouldBe(2); + pages.Items.Count.ShouldBe(2); + + input.MaxResultCount = 1; + + var pages2 = await _pageAdminAppService.GetListAsync(input); + + pages2.TotalCount.ShouldBe(2); + pages2.Items.Count.ShouldBe(1); + pages2.Items.First().Title.ShouldBe(_data.Page_1_Title); + + input.SkipCount = 1; + + var pages3 = await _pageAdminAppService.GetListAsync(input); + + pages3.TotalCount.ShouldBe(2); + pages3.Items.Count.ShouldBe(1); + pages3.Items.First().Title.ShouldBe(_data.Page_2_Title); + } + [Fact] public async Task ShouldGetAsync() { @@ -41,7 +67,7 @@ namespace Volo.CmsKit.Pages Url = "test-url" }; - await Should.NotThrowAsync(async () => await _pageAdminAppService.CreatePageAsync(dto)); + await Should.NotThrowAsync(async () => await _pageAdminAppService.CreateAsync(dto)); var page = await _pageRepository.GetByUrlAsync(dto.Url); @@ -49,7 +75,7 @@ namespace Volo.CmsKit.Pages } [Fact] - public async Task ShouldNotCreateAsync() + public async Task ShouldNotCreateExistUrlAsync() { var dto = new CreatePageInputDto { @@ -57,39 +83,9 @@ namespace Volo.CmsKit.Pages Url = _data.Page_1_Url }; - await Should.ThrowAsync(async () => await _pageAdminAppService.CreatePageAsync(dto)); - } - - [Fact] - public async Task ShouldCreateWithContentAsync() - { - var dto = new CreatePageWithContentInputDto - { - Title = "test", - Url = "test-url", - Content = "my-test-content" - }; - - await Should.NotThrowAsync(async () => await _pageAdminAppService.CreatePageWithContentAsync(dto)); - - var page = await _pageRepository.GetByUrlAsync(dto.Url); - - var content = await _contentRepository.GetAsync(nameof(Page), page.Id.ToString()); + var exception = await Should.ThrowAsync(async () => await _pageAdminAppService.CreateAsync(dto)); - content.Value.ShouldBe(dto.Content); - } - - [Fact] - public async Task ShouldNotCreateWithContentAsync() - { - var dto = new CreatePageWithContentInputDto - { - Title = "test", - Url = _data.Page_1_Url, - Content = "my-test-content" - }; - - await Should.ThrowAsync(async () => await _pageAdminAppService.CreatePageWithContentAsync(dto)); + exception.Code.ShouldBe(CmsKitErrorCodes.Pages.UrlAlreadyExist); } [Fact] @@ -102,7 +98,7 @@ namespace Volo.CmsKit.Pages Url = _data.Page_1_Url+ "test" }; - await Should.NotThrowAsync(async () => await _pageAdminAppService.UpdatePageAsync(_data.Page_1_Id, dto)); + await Should.NotThrowAsync(async () => await _pageAdminAppService.UpdateAsync(_data.Page_1_Id, dto)); var updatedPage = await _pageRepository.GetAsync(_data.Page_1_Id); @@ -117,7 +113,7 @@ namespace Volo.CmsKit.Pages } [Fact] - public async Task ShouldNotUpdatePageAsync() + public async Task ShouldNotUpdateWithExistUrlAsync() { var dto = new UpdatePageInputDto { @@ -126,58 +122,15 @@ namespace Volo.CmsKit.Pages Url = _data.Page_2_Url }; - await Should.ThrowAsync(async () => await _pageAdminAppService.UpdatePageAsync(_data.Page_1_Id, dto)); + await Should.ThrowAsync(async () => await _pageAdminAppService.UpdateAsync(_data.Page_1_Id, dto)); } - [Fact] - public async Task ShouldBeExistAsync() - { - var dto = new CheckUrlInputDto - { - Url = _data.Page_1_Url - }; - - var doesExist = await _pageAdminAppService.DoesUrlExistAsync(dto); - - doesExist.ShouldBeTrue(); - } - - [Fact] - public async Task ShouldNotBeExistAsync() - { - var dto = new CheckUrlInputDto - { - Url = _data.Page_1_Url+ "+" - }; - - var doesExist = await _pageAdminAppService.DoesUrlExistAsync(dto); - - doesExist.ShouldBeFalse(); - } - - [Fact] - public async Task ShouldUpdateContentAsync() - { - var dto = new UpdatePageContentInputDto - { - Content = "my-new-content" - }; - - await Should.NotThrowAsync(async () => await _pageAdminAppService.UpdatePageContentAsync(_data.Page_1_Id, dto)); - - var content = await _contentRepository.GetAsync(nameof(Page), _data.Page_1_Id.ToString()); - - content.Value.ShouldBe(dto.Content); - } - [Fact] public async Task ShouldDeleteAsync() { await _pageAdminAppService.DeleteAsync(_data.Page_1_Id); await Should.ThrowAsync(async () => await _pageRepository.GetAsync(_data.Page_1_Id)); - - await Should.ThrowAsync(async () => await _contentRepository.GetAsync(nameof(Page), _data.Page_1_Id.ToString())); } } } \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestBaseModule.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestBaseModule.cs index 8e5049f55e..e12f3d31e8 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestBaseModule.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestBaseModule.cs @@ -1,11 +1,14 @@ using Microsoft.Extensions.DependencyInjection; +using NSubstitute; using Volo.Abp; using Volo.Abp.Authorization; using Volo.Abp.Autofac; +using Volo.Abp.BlobStoring; using Volo.Abp.Data; using Volo.Abp.GlobalFeatures; using Volo.Abp.Modularity; using Volo.Abp.Threading; +using Volo.FileManagement; namespace Volo.CmsKit { @@ -26,6 +29,16 @@ namespace Volo.CmsKit GlobalFeatureManager.Instance.Modules.CmsKit().EnableAll(); }); + context.Services.AddSingleton(Substitute.For()); + + Configure(options => + { + options.Containers.ConfigureAll((containerName, containerConfiguration) => + { + containerConfiguration.ProviderType = typeof(FakeBlobProvider); + }); + }); + context.Services.AddAlwaysAllowAuthorization(); } diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/FakeBlobProvider.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/FakeBlobProvider.cs new file mode 100644 index 0000000000..1f3db06e6e --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/FakeBlobProvider.cs @@ -0,0 +1,34 @@ +using System.IO; +using System.Threading.Tasks; +using Volo.Abp.BlobStoring; + +namespace Volo.FileManagement +{ + public class FakeBlobProvider : IBlobProvider + { + public virtual Task SaveAsync(BlobProviderSaveArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task DeleteAsync(BlobProviderDeleteArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task ExistsAsync(BlobProviderExistsArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task GetAsync(BlobProviderGetArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task GetOrNullAsync(BlobProviderGetArgs args) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/Pages/PageRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/Pages/PageRepository_Test.cs index 68b91f72a9..67a691c5a8 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/Pages/PageRepository_Test.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/Pages/PageRepository_Test.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Linq; +using System.Threading.Tasks; using Shouldly; using Volo.Abp.Modularity; using Xunit; @@ -17,6 +18,38 @@ namespace Volo.CmsKit.Pages _pageRepository = GetRequiredService(); } + [Fact] + public async Task CountAsync() + { + var totalCount = await _pageRepository.GetCountAsync(); + + totalCount.ShouldBe(2); + + var filteredCount = await _pageRepository.GetCountAsync(_cmsKitTestData.Page_2_Title); + + filteredCount.ShouldBe(1); + } + + [Fact] + public async Task GetListAsync() + { + var list = await _pageRepository.GetListAsync(); + + list.ShouldNotBeNull(); + list.Count.ShouldBe(2); + + var list_page_1 = await _pageRepository.GetListAsync(maxResultCount: 1); + var list_page_2 = await _pageRepository.GetListAsync(maxResultCount: 1, skipCount: 1); + + list_page_1.ShouldNotBeNull(); + list_page_1.Count.ShouldBe(1); + list_page_1.First().Title.ShouldBe(_cmsKitTestData.Page_1_Title); + + list_page_2.ShouldNotBeNull(); + list_page_1.Count.ShouldBe(1); + list_page_2.First().Title.ShouldBe(_cmsKitTestData.Page_2_Title); + } + [Fact] public async Task ShouldGetByUrlAsync() { @@ -46,7 +79,7 @@ namespace Volo.CmsKit.Pages [Fact] public async Task ShouldBeExistAsync() { - var page = await _pageRepository.DoesExistAsync(_cmsKitTestData.Page_1_Url); + var page = await _pageRepository.ExistsAsync(_cmsKitTestData.Page_1_Url); page.ShouldBeTrue(); } @@ -54,7 +87,7 @@ namespace Volo.CmsKit.Pages [Fact] public async Task ShouldNotBeExistAsync() { - var page = await _pageRepository.DoesExistAsync("not-exist-lyrics"); + var page = await _pageRepository.ExistsAsync("not-exist-lyrics"); page.ShouldBeFalse(); } diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/Volo.CmsKit.TestBase.csproj b/modules/cms-kit/test/Volo.CmsKit.TestBase/Volo.CmsKit.TestBase.csproj index 35c8c151ea..66c009b9a9 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/Volo.CmsKit.TestBase.csproj +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/Volo.CmsKit.TestBase.csproj @@ -15,6 +15,7 @@ +
diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/nl.json b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/nl.json index fad3137f04..6451eed41e 100644 --- a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/nl.json +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/nl.json @@ -7,6 +7,7 @@ "Permission:Delete": "Verwijder", "Permission:Create": "Maak aan", "Permission:Documents": "Documenten", + "Menu:Documents": "Documenten", "Menu:DocumentManagement": "Documenten", "Menu:ProjectManagement": "Projecten", "CreateANewProject": "Maak een nieuw project", @@ -30,8 +31,29 @@ "DisplayName:GitHubRootUrl": "GitHub root URL", "DisplayName:GitHubAccessToken": "GitHub-toegangstoken", "DisplayName:GitHubUserAgent": "GitHub-gebruikersagent", + "DisplayName:GithubVersionProviderSource": "GitHub versieprovider bron", + "DisplayName:VersionBranchPrefix": "Versie branch prefix", "DisplayName:All": "Pull all", "DisplayName:LanguageCode": "Taalcode", - "DisplayName:Version": "Versie" + "DisplayName:Version": "Versie", + "Documents": "Documenten", + "RemoveFromCache": "Verwijderen uit cache", + "Reindex": "Opnieuw indexeren", + "ReindexCompleted": "Opnieuw indexeren voltooid", + "RemovedFromCache": "Verwijderen uit cache", + "RemoveFromCacheConfirmation": "Weet u zeker dat u dit item uit de cache wilt verwijderen?", + "ReIndexDocumentConfirmation": "Weet u zeker dat u dit item opnieuw wilt indexeren?", + "DeleteFromDatabase": "Verwijder uit database", + "Deleted": "Verwijderd", + "Search": "Zoeken", + "StartDate": "Startdatum", + "EndDate": "Einddatum", + "CreationTime": "Aanmaaktijd", + "LastUpdateTime": "Laatste update", + "LastSignificantUpdateTime": "Laatste significante update", + "Version": "Versie", + "LanguageCode": "Taalcode", + "FileName": "Bestandsnaam", + "LastCachedTime": "Cache tijd" } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.js b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.js index 29c55502d9..d3671e3758 100644 --- a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.js +++ b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.js @@ -51,14 +51,11 @@ visible: abp.auth.isGranted( 'Docs.Admin.Documents' ), - confirmMessage: function (data) { - return l('RemoveFromCacheConfirmation'); - }, action: function (data) { service .removeFromCache(data.record.id) .then(function () { - abp.message.success(l('RemovedFromCache')); + abp.notify.success(l('RemovedFromCache')); dataTable.ajax.reload(); }); }, diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/nl.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/nl.json index 26aa1b614c..7433361079 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/nl.json +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/nl.json @@ -11,11 +11,18 @@ "Delete": "Verwijder", "ClearCache": "Cache wissen", "ClearCacheConfirmationMessage": "Weet u zeker dat u alle caches voor het project \"{0}\" wilt wissen?", + "ReIndexAllProjects": "Alle Projecten opnieuw indexeren", + "ReIndexProject": "Project opnieuw indexeren", + "ReIndexProjectConfirmationMessage": "Weet u zeker dat u project \"{0}\" opnieuw wilt indexeren?", + "SuccessfullyReIndexProject": "Project \"{0}\" is succesvol opnieuw geïndexeerd", + "ReIndexAllProjectConfirmationMessage": "Weet u zeker dat u alle projecten opnieuw wilt indexeren?", + "SuccessfullyReIndexAllProject": "Alle projecten zijn succesvol opnieuw geïndexeerd", "InThisDocument": "In dit document", "GoToTop": "Ga naar boven", "Projects": "Project (en)", "NoProjectWarning": "Er zijn nog geen projecten!", "DocumentNotFound": "Oeps, het opgevraagde document is niet gevonden!", + "ProjectNotFound": "Oeps, het opgevraagde project is niet gevonden!", "NavigationDocumentNotFound": "Deze versie heeft geen navigatiedocument!", "DocumentNotFoundInSelectedLanguage": "Document in de gewenste taal is niet gevonden. Document in de standaardtaal wordt weergegeven.", "FilterTopics": "Filter onderwerpen", @@ -26,6 +33,7 @@ "Upd": "Bew", "NewExplanation": "Gemaakt in de afgelopen twee weken.", "UpdatedExplanation": "Bewerkt in de afgelopen twee weken.", - "Volo.Docs.Domain:010002": "KorteNaam {ShortName} bestaat al." + "Volo.Docs.Domain:010002": "KorteNaam {ShortName} bestaat al.", + "Preview": "voorbeeld" } -} +} \ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/nl.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/nl.json index 8bb07d32d4..c34ae5cc93 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/nl.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/nl.json @@ -2,6 +2,9 @@ "culture": "nl", "texts": { "Features": "Functies", - "NoFeatureFoundMessage": "Er is geen functie beschikbaar." + "NoFeatureFoundMessage": "Er is geen functie beschikbaar.", + "Permission:FeatureManagement": "Functiebeheer", + "Permission:FeatureManagement.ManageHostFeatures": "Beheer host functies", + "Volo.Abp.FeatureManagement:InvalidFeatureValue": "{0} functie-waarde is niet geldig!" } } \ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/EditionFeatureManagementProvider.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/EditionFeatureManagementProvider.cs index d904ef124a..0106e56af2 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/EditionFeatureManagementProvider.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/EditionFeatureManagementProvider.cs @@ -1,4 +1,5 @@ using System.Security.Principal; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.Features; using Volo.Abp.Security.Claims; @@ -12,21 +13,21 @@ namespace Volo.Abp.FeatureManagement protected ICurrentPrincipalAccessor PrincipalAccessor { get; } public EditionFeatureManagementProvider( - IFeatureManagementStore store, - ICurrentPrincipalAccessor principalAccessor) + IFeatureManagementStore store, + ICurrentPrincipalAccessor principalAccessor) : base(store) { PrincipalAccessor = principalAccessor; } - protected override string NormalizeProviderKey(string providerKey) + protected override Task NormalizeProviderKeyAsync(string providerKey) { if (providerKey != null) { - return providerKey; + return Task.FromResult(providerKey); } - return PrincipalAccessor.Principal?.FindEditionId()?.ToString("N"); + return Task.FromResult(PrincipalAccessor.Principal?.FindEditionId()?.ToString("N")); } } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManagementProvider.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManagementProvider.cs index 45e5f65b4c..42b275c01b 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManagementProvider.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManagementProvider.cs @@ -21,22 +21,22 @@ namespace Volo.Abp.FeatureManagement public virtual async Task GetOrNullAsync(FeatureDefinition feature, string providerKey) { - return await Store.GetOrNullAsync(feature.Name, Name, NormalizeProviderKey(providerKey)); + return await Store.GetOrNullAsync(feature.Name, Name, await NormalizeProviderKeyAsync(providerKey)); } public virtual async Task SetAsync(FeatureDefinition feature, string value, string providerKey) { - await Store.SetAsync(feature.Name, value, Name, NormalizeProviderKey(providerKey)); + await Store.SetAsync(feature.Name, value, Name, await NormalizeProviderKeyAsync(providerKey)); } public virtual async Task ClearAsync(FeatureDefinition feature, string providerKey) { - await Store.DeleteAsync(feature.Name, Name, NormalizeProviderKey(providerKey)); + await Store.DeleteAsync(feature.Name, Name, await NormalizeProviderKeyAsync(providerKey)); } - protected virtual string NormalizeProviderKey(string providerKey) + protected virtual Task NormalizeProviderKeyAsync(string providerKey) { - return providerKey; + return Task.FromResult(providerKey); } } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/TenantFeatureManagementProvider.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/TenantFeatureManagementProvider.cs index 91302580d2..4e822fd7e0 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/TenantFeatureManagementProvider.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/TenantFeatureManagementProvider.cs @@ -1,4 +1,5 @@ -using Volo.Abp.DependencyInjection; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; using Volo.Abp.Features; using Volo.Abp.MultiTenancy; @@ -18,14 +19,14 @@ namespace Volo.Abp.FeatureManagement CurrentTenant = currentTenant; } - protected override string NormalizeProviderKey(string providerKey) + protected override Task NormalizeProviderKeyAsync(string providerKey) { if (providerKey != null) { - return providerKey; + return Task.FromResult(providerKey); } - return CurrentTenant.Id?.ToString(); + return Task.FromResult(CurrentTenant.Id?.ToString()); } } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml.cs index 367268019c..d2ccc5a44d 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml.cs @@ -3,7 +3,9 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using Volo.Abp.EventBus.Local; using Volo.Abp.Features; using Volo.Abp.Validation.StringValues; @@ -27,11 +29,16 @@ namespace Volo.Abp.FeatureManagement.Web.Pages.FeatureManagement protected IFeatureAppService FeatureAppService { get; } - public FeatureManagementModal(IFeatureAppService featureAppService) + protected ILocalEventBus LocalEventBus { get; } + + public FeatureManagementModal( + IFeatureAppService featureAppService, + ILocalEventBus localEventBus) { ObjectMapperContext = typeof(AbpFeatureManagementWebModule); FeatureAppService = featureAppService; + LocalEventBus = localEventBus; } public virtual async Task OnGetAsync() @@ -56,6 +63,10 @@ namespace Volo.Abp.FeatureManagement.Web.Pages.FeatureManagement await FeatureAppService.UpdateAsync(ProviderName, ProviderKey, features); + await LocalEventBus.PublishAsync( + new CurrentApplicationConfigurationCacheResetEventData() + ); + return NoContent(); } diff --git a/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityRoleAppService.cs b/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityRoleAppService.cs index 9eecb1058e..070f55901e 100644 --- a/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityRoleAppService.cs +++ b/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityRoleAppService.cs @@ -40,7 +40,7 @@ namespace Volo.Abp.Identity public virtual async Task> GetListAsync(GetIdentityRolesInput input) { var list = await RoleRepository.GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount, input.Filter); - var totalCount = await RoleRepository.GetCountAsync(); + var totalCount = await RoleRepository.GetCountAsync(input.Filter); return new PagedResultDto( totalCount, diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json index 1ca863e935..4abc1394c7 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json @@ -11,7 +11,7 @@ "DisplayName:IsDefault": "Standaard", "DisplayName:IsStatic": "Statisch", "DisplayName:IsPublic": "Openbaar", - "Roles": "Roles", + "Roles": "Rollen", "Password": "Wachtwoord", "PersonalInfo": "Mijn profiel", "PersonalSettings": "Persoonlijke instellingen", @@ -24,7 +24,7 @@ "DisplayName:Password": "Wachtwoord", "DisplayName:Email": "E-mail adres", "DisplayName:PhoneNumber": "Telefoonnummer", - "DisplayName:TwoFactorEnabled": "Twee-factor-verificatie", + "DisplayName:TwoFactorEnabled": "Tweefactor authenticatie", "DisplayName:LockoutEnabled": "Account vergrendelen na mislukte inlogpogingen", "NewRole": "Nieuwe rol", "RoleName": "Rol naam", @@ -36,14 +36,14 @@ "PasswordChangedMessage": "Uw wachtwoord is met succes veranderd.", "PersonalSettingsSavedMessage": "Uw persoonlijke instellingen zijn succesvol opgeslagen.", "Volo.Abp.Identity:DefaultError": "Er is een onbekende fout opgetreden.", - "Volo.Abp.Identity:ConcurrencyFailure": "Optimistische gelijktijdigheidsfout, object is gewijzigd.", + "Volo.Abp.Identity:ConcurrencyFailure": "Optimistische gelijktijdigheidsfout, object is al gewijzigd.", "Volo.Abp.Identity:DuplicateEmail": "E-mail '{0}' is al in gebruik.", - "Volo.Abp.Identity:DuplicateRoleName": "De rolnaam '{0}' is al in gebruik.", + "Volo.Abp.Identity:DuplicateRoleName": "De rol naam '{0}' is al in gebruik.", "Volo.Abp.Identity:DuplicateUserName": "Gebruikersnaam '{0}' is al in gebruik.", - "Volo.Abp.Identity:InvalidEmail": "E-mail' {0} 'is ongeldig.", + "Volo.Abp.Identity:InvalidEmail": "E-mailadres '{0}' is ongeldig.", "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "De opgegeven PasswordHasherCompatibilityMode is ongeldig.", "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "De iteratietelling moet een positief geheel getal zijn.", - "Volo.Abp.Identity:InvalidRoleName": "Rolnaam '{0}' is ongeldig.", + "Volo.Abp.Identity:InvalidRoleName": "Rol naam '{0}' is ongeldig.", "Volo.Abp.Identity:InvalidToken": "Ongeldig token.", "Volo.Abp.Identity:InvalidUserName": "Gebruikersnaam '{0}' is ongeldig, mag alleen letters of cijfers bevatten.", "Volo.Abp.Identity:LoginAlreadyAssociated": "Er bestaat al een gebruiker met deze login.", @@ -61,9 +61,15 @@ "Volo.Abp.Identity:UserNameNotFound": "Gebruiker {0} bestaat niet.", "Volo.Abp.Identity:UserNotInRole": "Gebruiker speelt geen rol '{0}'.", "Volo.Abp.Identity:PasswordConfirmationFailed": "Wachtwoord komt niet overeen met de wachtwoord bevestiging.", + "Volo.Abp.Identity:010001": "U kunt uw eigen account niet verwijderen!", + "Volo.Abp.Identity:010002": "Kan niet meer dan {MaxUserMembershipCount} organisatie-eenheden koppelen aan een gebruiker!", + "Volo.Abp.Identity:010003": "Kan het wachtwoord van een extern ingelogde gebruiker niet wijzigen!", + "Volo.Abp.Identity:010004": "Er is al een organisatie-eenheid met naam {0}. Twee eenheden met dezelfde naam kunnen niet op hetzelfde niveau worden gemaakt.", "Volo.Abp.Identity:010005": "Statische rollen kunnen niet worden hernoemd.", "Volo.Abp.Identity:010006": "Statische rollen kunnen niet worden verwijderd.", - "Volo.Abp.Identity:010001": "U kunt uw eigen account niet verwijderen!", + "Volo.Abp.Identity:010007": "U kunt uw instelling voor tweefactor authenticatie niet wijzigen.", + "Volo.Abp.Identity:010008": "Het is niet toegestaan om de instelling van tweefactor authenticatie te wijzigen.", + "Identity.OrganizationUnit.MaxUserMembershipCount": "Maximaal toegestande aantal lidmaatschappen van organisatie-eenheden voor een gebruiker", "Permission:IdentityManagement": "Identiteitsbeheer", "Permission:RoleManagement": "Rolbeheer", "Permission:Create": "Maak aan", @@ -72,6 +78,12 @@ "Permission:ChangePermissions": "Wijzig de rechten", "Permission:UserManagement": "Gebruikersbeheer", "Permission:UserLookup": "Gebruiker opzoeken", + "Feature:IdentityGroup": "Identiteit", + "Feature:TwoFactor": "Tweefactor authenticatie gedrag", + "Feature:TwoFactorDescription": "Stel tweefactor authenticatie gedrag in. Mogelijke waardes: Optioneel,Uitgeschakeld,Afgedwongen", + "Feature:TwoFactor.Optional": "Optioneel", + "Feature:TwoFactor.Disabled": "Uitgeschakeld", + "Feature:TwoFactor.Forced": "Afgedwongen", "DisplayName:Abp.Identity.Password.RequiredLength": "Vereiste lengte", "DisplayName:Abp.Identity.Password.RequiredUniqueChars": "Vereist aantal unieke tekens", "DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "Vereist niet-alfanumeriek teken", @@ -99,6 +111,10 @@ "Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "Of het telefoonnummer kan worden bevestigd door de gebruiker.", "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "Of een bevestigd telefoonnummer vereist is om in te loggen.", "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "Of de gebruikersnaam kan worden bijgewerkt door de gebruiker.", - "Description:Abp.Identity.User.IsEmailUpdateEnabled": "Of de e-mail door de gebruiker kan worden veranderd." + "Description:Abp.Identity.User.IsEmailUpdateEnabled": "Of de e-mail door de gebruiker kan worden veranderd.", + "DisplayName:Abp.Identity.TwoFactorBehaviour": "Tweefactor authenticatie gedrag", + "Description:Abp.Identity.TwoFactorBehaviour": "Tweefactor authenticatie gedrag", + "DisplayName:Abp.Identity.UsersCanChange": "Sta gebruikers toe hun Tweefactor authenticatie te wijzigen.", + "Description:Abp.Identity.UsersCanChange": "Sta gebruikers toe hun Tweefactor authenticatie te wijzigen." } -} +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs index 91915cd9b8..c985680455 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs @@ -18,7 +18,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore } - public async Task> GetListAsync( + public virtual async Task> GetListAsync( string sorting = null, int maxResultCount = 50, int skipCount = 0, @@ -54,7 +54,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore .ToListAsync(cancellationToken); } - public async Task GetCountAsync( + public virtual async Task GetCountAsync( DateTime? startTime = null, DateTime? endTime = null, string applicationName = null, @@ -84,7 +84,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore return await query.LongCountAsync(cancellationToken); } - public async Task GetByUserIdAsync(Guid id, Guid userId, bool includeDetails = false, CancellationToken cancellationToken = default) + public virtual async Task GetByUserIdAsync(Guid id, Guid userId, bool includeDetails = false, CancellationToken cancellationToken = default) { return await (await GetDbSetAsync()) .OrderBy(x => x.Id) diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityClaimTypeRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityClaimTypeRepository.cs index 4cbdfb5725..f634050b23 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityClaimTypeRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityClaimTypeRepository.cs @@ -47,7 +47,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore return identityClaimTypes; } - public async Task GetCountAsync( + public virtual async Task GetCountAsync( string filter = null, CancellationToken cancellationToken = default) { diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityLinkUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityLinkUserRepository.cs index 6920d1081e..c7e81f327e 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityLinkUserRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityLinkUserRepository.cs @@ -17,7 +17,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore } - public async Task FindAsync(IdentityLinkUserInfo sourceLinkUserInfo, IdentityLinkUserInfo targetLinkUserInfo, CancellationToken cancellationToken = default) + public virtual async Task FindAsync(IdentityLinkUserInfo sourceLinkUserInfo, IdentityLinkUserInfo targetLinkUserInfo, CancellationToken cancellationToken = default) { return await (await GetDbSetAsync()) .OrderBy(x => x.Id).FirstOrDefaultAsync(x => @@ -28,7 +28,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore , cancellationToken: GetCancellationToken(cancellationToken)); } - public async Task> GetListAsync(IdentityLinkUserInfo linkUserInfo, CancellationToken cancellationToken = default) + public virtual async Task> GetListAsync(IdentityLinkUserInfo linkUserInfo, CancellationToken cancellationToken = default) { return await (await GetDbSetAsync()) .Where(x => diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs index b1389afd6a..aed6ed2232 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs @@ -64,7 +64,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore .ToListAsync(GetCancellationToken(cancellationToken)); } - public async Task GetCountAsync( + public virtual async Task GetCountAsync( string filter = null, CancellationToken cancellationToken = default) { diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs index 8fcce7c35a..57b625a816 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs @@ -231,7 +231,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore return await query.ToListAsync(GetCancellationToken(cancellationToken)); } - public async Task> GetUsersInOrganizationsListAsync( + public virtual async Task> GetUsersInOrganizationsListAsync( List organizationUnitIds, CancellationToken cancellationToken = default ) diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityClaimTypeRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityClaimTypeRepository.cs index 6795735793..3ad208efc0 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityClaimTypeRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityClaimTypeRepository.cs @@ -55,7 +55,7 @@ namespace Volo.Abp.Identity.MongoDB .ToListAsync(GetCancellationToken(cancellationToken)); } - public async Task GetCountAsync( + public virtual async Task GetCountAsync( string filter = null, CancellationToken cancellationToken = default) { diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityLinkUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityLinkUserRepository.cs index 43bad94271..e670759e5c 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityLinkUserRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityLinkUserRepository.cs @@ -17,7 +17,7 @@ namespace Volo.Abp.Identity.MongoDB { } - public async Task FindAsync(IdentityLinkUserInfo sourceLinkUserInfo, IdentityLinkUserInfo targetLinkUserInfo, CancellationToken cancellationToken = default) + public virtual async Task FindAsync(IdentityLinkUserInfo sourceLinkUserInfo, IdentityLinkUserInfo targetLinkUserInfo, CancellationToken cancellationToken = default) { return await (await GetMongoQueryableAsync(cancellationToken)) .OrderBy(x => x.Id).FirstOrDefaultAsync(x => @@ -28,7 +28,7 @@ namespace Volo.Abp.Identity.MongoDB , cancellationToken: GetCancellationToken(cancellationToken)); } - public async Task> GetListAsync(IdentityLinkUserInfo linkUserInfo, CancellationToken cancellationToken = default) + public virtual async Task> GetListAsync(IdentityLinkUserInfo linkUserInfo, CancellationToken cancellationToken = default) { return await (await GetMongoQueryableAsync(cancellationToken)).Where(x => x.SourceUserId == linkUserInfo.UserId && x.SourceTenantId == linkUserInfo.TenantId || diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs index 0731008f57..f4b5049b16 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs @@ -18,7 +18,7 @@ namespace Volo.Abp.Identity.MongoDB { } - public async Task FindByNormalizedNameAsync( + public virtual async Task FindByNormalizedNameAsync( string normalizedRoleName, bool includeDetails = true, CancellationToken cancellationToken = default) @@ -28,7 +28,7 @@ namespace Volo.Abp.Identity.MongoDB .FirstOrDefaultAsync(r => r.NormalizedName == normalizedRoleName, GetCancellationToken(cancellationToken)); } - public async Task> GetListAsync( + public virtual async Task> GetListAsync( string sorting = null, int maxResultCount = int.MaxValue, int skipCount = 0, @@ -64,7 +64,7 @@ namespace Volo.Abp.Identity.MongoDB .ToListAsync(GetCancellationToken(cancellationToken)); } - public async Task GetCountAsync( + public virtual async Task GetCountAsync( string filter = null, CancellationToken cancellationToken = default) { diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs index a0a8b9b103..cc926db139 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.Identity.MongoDB { } - public async Task> GetListAsync( + public virtual async Task> GetListAsync( string sorting = null, int maxResultCount = 50, int skipCount = 0, @@ -53,7 +53,7 @@ namespace Volo.Abp.Identity.MongoDB .ToListAsync(GetCancellationToken(cancellationToken)); } - public async Task GetCountAsync( + public virtual async Task GetCountAsync( DateTime? startTime = null, DateTime? endTime = null, string applicationName = null, @@ -82,7 +82,7 @@ namespace Volo.Abp.Identity.MongoDB } - public async Task GetByUserIdAsync(Guid id, Guid userId, bool includeDetails = false, + public virtual async Task GetByUserIdAsync(Guid id, Guid userId, bool includeDetails = false, CancellationToken cancellationToken = default) { return await (await GetMongoQueryableAsync(cancellationToken)).OrderBy(x => x.Id).FirstOrDefaultAsync(x => x.Id == id && x.UserId == userId, diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs index 0864f7b01c..1909b269cc 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs @@ -53,7 +53,7 @@ namespace Volo.Abp.Identity.MongoDB return await dbContext.Roles.AsQueryable().Where(r => allRoleIds.Contains(r.Id)).Select(r => r.Name).ToListAsync(GetCancellationToken(cancellationToken)); } - public async Task> GetRoleNamesInOrganizationUnitAsync( + public virtual async Task> GetRoleNamesInOrganizationUnitAsync( Guid id, CancellationToken cancellationToken = default) { @@ -178,7 +178,7 @@ namespace Volo.Abp.Identity.MongoDB return await dbContext.Roles.AsQueryable().Where(r => allRoleIds.Contains(r.Id)).ToListAsync(GetCancellationToken(cancellationToken)); } - public async Task> GetOrganizationUnitsAsync( + public virtual async Task> GetOrganizationUnitsAsync( Guid id, bool includeDetails = false, CancellationToken cancellationToken = default) @@ -210,7 +210,7 @@ namespace Volo.Abp.Identity.MongoDB .LongCountAsync(GetCancellationToken(cancellationToken)); } - public async Task> GetUsersInOrganizationUnitAsync( + public virtual async Task> GetUsersInOrganizationUnitAsync( Guid organizationUnitId, CancellationToken cancellationToken = default) { @@ -221,7 +221,7 @@ namespace Volo.Abp.Identity.MongoDB return result; } - public async Task> GetUsersInOrganizationsListAsync( + public virtual async Task> GetUsersInOrganizationsListAsync( List organizationUnitIds, CancellationToken cancellationToken = default) { @@ -232,7 +232,7 @@ namespace Volo.Abp.Identity.MongoDB return result; } - public async Task> GetUsersInOrganizationUnitWithChildrenAsync( + public virtual async Task> GetUsersInOrganizationUnitWithChildrenAsync( string code, CancellationToken cancellationToken = default) { diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs index de0afd8abc..6479bc4be0 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs @@ -112,7 +112,7 @@ namespace Volo.Abp.Identity.MongoDB .CountAsync(cancellationToken); } - public async Task> GetUnaddedRolesAsync( + public virtual async Task> GetUnaddedRolesAsync( OrganizationUnit organizationUnit, string sorting = null, int maxResultCount = int.MaxValue, @@ -132,7 +132,7 @@ namespace Volo.Abp.Identity.MongoDB .ToListAsync(cancellationToken); } - public async Task GetUnaddedRolesCountAsync( + public virtual async Task GetUnaddedRolesCountAsync( OrganizationUnit organizationUnit, string filter = null, CancellationToken cancellationToken = default) @@ -174,7 +174,7 @@ namespace Volo.Abp.Identity.MongoDB return await query.CountAsync(cancellationToken); } - public async Task> GetUnaddedUsersAsync( + public virtual async Task> GetUnaddedUsersAsync( OrganizationUnit organizationUnit, string sorting = null, int maxResultCount = int.MaxValue, @@ -199,7 +199,7 @@ namespace Volo.Abp.Identity.MongoDB .ToListAsync(GetCancellationToken(cancellationToken)); } - public async Task GetUnaddedUsersCountAsync(OrganizationUnit organizationUnit, string filter = null, + public virtual async Task GetUnaddedUsersCountAsync(OrganizationUnit organizationUnit, string filter = null, CancellationToken cancellationToken = default) { var dbContext = await GetDbContextAsync(cancellationToken); diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/nl.json b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/nl.json index 0ae2ba8cd9..9b6943c54f 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/nl.json +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/nl.json @@ -3,10 +3,12 @@ "texts": { "Volo.IdentityServer:DuplicateIdentityResourceName": "Identiteitsbronnaam bestaat al: {Name}", "Volo.IdentityServer:DuplicateApiResourceName": "API-bronnaam bestaat al: {Name}", + "Volo.IdentityServer:DuplicateApiScopeName": "Api-scope met naam: '{Name}' bestaat al", "Volo.IdentityServer:DuplicateClientId": "ClientId bestaat al: {ClientId}", "UserLockedOut": "Het gebruikersaccount is geblokkeerd vanwege ongeldige inlogpogingen. Wacht even en probeer het opnieuw.", "InvalidUserNameOrPassword": "ongeldige gebruikersnaam of wachtwoord!", "LoginIsNotAllowed": "U mag niet inloggen! U moet uw e-mailadres / telefoonnummer bevestigen.", - "InvalidUsername": "Ongeldige gebruikersnaam of wachtwoord!" + "InvalidUsername": "Ongeldige gebruikersnaam of wachtwoord!", + "TheTargetUserIsNotLinkedToYou": "De beoogde gebruiker is niet aan jou gekoppeld!" } } \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/IApiResourceRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/IApiResourceRepository.cs index 5d99666183..d1f60bcb7b 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/IApiResourceRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/IApiResourceRepository.cs @@ -35,6 +35,11 @@ namespace Volo.Abp.IdentityServer.ApiResources CancellationToken cancellationToken = default ); + Task GetCountAsync( + string filter = null, + CancellationToken cancellationToken = default + ); + Task CheckNameExistAsync( string name, Guid? expectedId = null, diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiScopes/IApiScopeRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiScopes/IApiScopeRepository.cs index a0aba8fe2a..a6736bdda6 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiScopes/IApiScopeRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiScopes/IApiScopeRepository.cs @@ -29,6 +29,11 @@ namespace Volo.Abp.IdentityServer.ApiScopes CancellationToken cancellationToken = default ); + Task GetCountAsync( + string filter = null, + CancellationToken cancellationToken = default + ); + Task CheckNameExistAsync( string name, Guid? expectedId = null, diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/IClientRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/IClientRepository.cs index 059882eb47..55d15a8c83 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/IClientRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/IClientRepository.cs @@ -24,6 +24,11 @@ namespace Volo.Abp.IdentityServer.Clients CancellationToken cancellationToken = default ); + Task GetCountAsync( + string filter = null, + CancellationToken cancellationToken = default + ); + Task> GetAllDistinctAllowedCorsOriginsAsync(CancellationToken cancellationToken = default); Task CheckClientIdExistAsync( diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IIdentityResourceRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IIdentityResourceRepository.cs index 4dd5472ea9..0ddf31e58e 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IIdentityResourceRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IIdentityResourceRepository.cs @@ -23,6 +23,11 @@ namespace Volo.Abp.IdentityServer.IdentityResources CancellationToken cancellationToken = default ); + Task GetCountAsync( + string filter = null, + CancellationToken cancellationToken = default + ); + Task FindByNameAsync( string name, bool includeDetails = true, diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiResources/ApiResourceRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiResources/ApiResourceRepository.cs index 16a789048d..eb3ecc2884 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiResources/ApiResourceRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiResources/ApiResourceRepository.cs @@ -68,6 +68,16 @@ namespace Volo.Abp.IdentityServer.ApiResources .ToListAsync(GetCancellationToken(cancellationToken)); } + public async Task GetCountAsync(string filter = null, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .WhereIf(!filter.IsNullOrWhiteSpace(), + x => x.Name.Contains(filter) || + x.Description.Contains(filter) || + x.DisplayName.Contains(filter)) + .LongCountAsync(GetCancellationToken(cancellationToken)); + } + public virtual async Task CheckNameExistAsync(string name, Guid? expectedId = null, CancellationToken cancellationToken = default) { return await (await GetDbSetAsync()).AnyAsync(ar => ar.Id != expectedId && ar.Name == name, GetCancellationToken(cancellationToken)); diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiScopes/ApiScopeRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiScopes/ApiScopeRepository.cs index 4cece3209e..6bea5a742f 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiScopes/ApiScopeRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiScopes/ApiScopeRepository.cs @@ -48,6 +48,16 @@ namespace Volo.Abp.IdentityServer.ApiScopes .ToListAsync(GetCancellationToken(cancellationToken)); } + public async Task GetCountAsync(string filter = null, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .WhereIf(!filter.IsNullOrWhiteSpace(), + x => x.Name.Contains(filter) || + x.Description.Contains(filter) || + x.DisplayName.Contains(filter)) + .LongCountAsync(GetCancellationToken(cancellationToken)); + } + public async Task CheckNameExistAsync(string name, Guid? expectedId = null, CancellationToken cancellationToken = default) { return await (await GetDbSetAsync()).AnyAsync(x => x.Id != expectedId && x.Name == name, GetCancellationToken(cancellationToken)); diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/Clients/ClientRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/Clients/ClientRepository.cs index 7607a189ca..9fbbc8195f 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/Clients/ClientRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/Clients/ClientRepository.cs @@ -41,6 +41,13 @@ namespace Volo.Abp.IdentityServer.Clients .ToListAsync(GetCancellationToken(cancellationToken)); } + public async Task GetCountAsync(string filter = null, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .WhereIf(!filter.IsNullOrWhiteSpace(), x => x.ClientId.Contains(filter)) + .LongCountAsync(GetCancellationToken(cancellationToken)); + } + public virtual async Task> GetAllDistinctAllowedCorsOriginsAsync(CancellationToken cancellationToken = default) { return await (await GetDbContextAsync()).ClientCorsOrigins diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceRepository.cs index 1b83b46158..22e68fca31 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceRepository.cs @@ -55,6 +55,16 @@ namespace Volo.Abp.IdentityServer.IdentityResources .ToListAsync(GetCancellationToken(cancellationToken)); } + public async Task GetCountAsync(string filter = null, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .WhereIf(!filter.IsNullOrWhiteSpace(), + x => x.Name.Contains(filter) || + x.Description.Contains(filter) || + x.DisplayName.Contains(filter)) + .LongCountAsync(GetCancellationToken(cancellationToken)); + } + public virtual async Task FindByNameAsync( string name, bool includeDetails = true, diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiResourceRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiResourceRepository.cs index 7db1bba8da..e5f7186440 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiResourceRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiResourceRepository.cs @@ -56,6 +56,16 @@ namespace Volo.Abp.IdentityServer.MongoDB .ToListAsync(GetCancellationToken(cancellationToken)); } + public async Task GetCountAsync(string filter = null, CancellationToken cancellationToken = default) + { + return await (await GetMongoQueryableAsync(cancellationToken)) + .WhereIf>(!filter.IsNullOrWhiteSpace(), + x => x.Name.Contains(filter) || + x.Description.Contains(filter) || + x.DisplayName.Contains(filter)) + .LongCountAsync(GetCancellationToken(cancellationToken)); + } + public virtual async Task CheckNameExistAsync(string name, Guid? expectedId = null, CancellationToken cancellationToken = default) { return await (await GetMongoQueryableAsync(cancellationToken)) diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiScopeRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiScopeRepository.cs index 69faed9dc3..f1372dd6c0 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiScopeRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiScopeRepository.cs @@ -53,6 +53,16 @@ namespace Volo.Abp.IdentityServer.MongoDB .ToListAsync(GetCancellationToken(cancellationToken)); } + public async Task GetCountAsync(string filter = null, CancellationToken cancellationToken = default) + { + return await (await GetMongoQueryableAsync(cancellationToken)) + .WhereIf>(!filter.IsNullOrWhiteSpace(), + x => x.Name.Contains(filter) || + x.Description.Contains(filter) || + x.DisplayName.Contains(filter)) + .LongCountAsync(GetCancellationToken(cancellationToken)); + } + public async Task CheckNameExistAsync(string name, Guid? expectedId = null, CancellationToken cancellationToken = default) { return await (await GetMongoQueryableAsync(cancellationToken)) diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoClientRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoClientRepository.cs index bd99461997..22cc7b6388 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoClientRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoClientRepository.cs @@ -48,6 +48,14 @@ namespace Volo.Abp.IdentityServer.MongoDB .ToListAsync(GetCancellationToken(cancellationToken)); } + public async Task GetCountAsync(string filter = null, CancellationToken cancellationToken = default) + { + return await (await GetMongoQueryableAsync(cancellationToken)) + .WhereIf>(!filter.IsNullOrWhiteSpace(), + x => x.ClientId.Contains(filter)) + .LongCountAsync(GetCancellationToken(cancellationToken)); + } + public virtual async Task> GetAllDistinctAllowedCorsOriginsAsync( CancellationToken cancellationToken = default) { diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoIdentityResourceRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoIdentityResourceRepository.cs index 84cc5cca0f..f8ccb9dd97 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoIdentityResourceRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoIdentityResourceRepository.cs @@ -30,6 +30,16 @@ namespace Volo.Abp.IdentityServer.MongoDB .ToListAsync(GetCancellationToken(cancellationToken)); } + public async Task GetCountAsync(string filter = null, CancellationToken cancellationToken = default) + { + return await (await GetMongoQueryableAsync(cancellationToken)) + .WhereIf>(!filter.IsNullOrWhiteSpace(), + x => x.Name.Contains(filter) || + x.Description.Contains(filter) || + x.DisplayName.Contains(filter)) + .LongCountAsync(GetCancellationToken(cancellationToken)); + } + public virtual async Task FindByNameAsync( string name, bool includeDetails = true, diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml.cs index 041121b8cb..a990437464 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml.cs @@ -3,7 +3,9 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using Volo.Abp.EventBus.Local; using Volo.Abp.PermissionManagement.Web.Utils; namespace Volo.Abp.PermissionManagement.Web.Pages.AbpPermissionManagement @@ -31,11 +33,16 @@ namespace Volo.Abp.PermissionManagement.Web.Pages.AbpPermissionManagement protected IPermissionAppService PermissionAppService { get; } - public PermissionManagementModal(IPermissionAppService permissionAppService) + protected ILocalEventBus LocalEventBus { get; } + + public PermissionManagementModal( + IPermissionAppService permissionAppService, + ILocalEventBus localEventBus) { ObjectMapperContext = typeof(AbpPermissionManagementWebModule); PermissionAppService = permissionAppService; + LocalEventBus = localEventBus; } public virtual async Task OnGetAsync() @@ -88,6 +95,10 @@ namespace Volo.Abp.PermissionManagement.Web.Pages.AbpPermissionManagement } ); + await LocalEventBus.PublishAsync( + new CurrentApplicationConfigurationCacheResetEventData() + ); + return NoContent(); } @@ -155,4 +166,4 @@ namespace Volo.Abp.PermissionManagement.Web.Pages.AbpPermissionManagement public string ProviderKey { get; set; } } } -} \ No newline at end of file +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.cshtml.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.cshtml.cs index 7f9c332e13..87eb2e5bf4 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.cshtml.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.cshtml.cs @@ -2,7 +2,9 @@ using System; using System.Threading.Tasks; using Microsoft.Extensions.Options; using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using Volo.Abp.EventBus.Local; namespace Volo.Abp.SettingManagement.Web.Pages.SettingManagement { @@ -10,10 +12,14 @@ namespace Volo.Abp.SettingManagement.Web.Pages.SettingManagement { public SettingPageCreationContext SettingPageCreationContext { get; private set; } + protected ILocalEventBus LocalEventBus { get; } protected SettingManagementPageOptions Options { get; } - public IndexModel(IOptions options) + public IndexModel( + IOptions options, + ILocalEventBus localEventBus) { + LocalEventBus = localEventBus; Options = options.Value; } @@ -25,7 +31,7 @@ namespace Volo.Abp.SettingManagement.Web.Pages.SettingManagement { await contributor.ConfigureAsync(SettingPageCreationContext); } - + return Page(); } @@ -33,5 +39,14 @@ namespace Volo.Abp.SettingManagement.Web.Pages.SettingManagement { return Task.FromResult(Page()); } + + public virtual async Task OnPostRefreshConfigurationAsync() + { + await LocalEventBus.PublishAsync( + new CurrentApplicationConfigurationCacheResetEventData() + ); + + return NoContent(); + } } -} \ No newline at end of file +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.js b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.js index 32ea1a27cc..fdd63bd4fd 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.js +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.js @@ -3,5 +3,9 @@ $(document).on('AbpSettingSaved', function () { abp.notify.success(l('SuccessfullySaved')); + + abp.ajax({ + url: abp.appPath + 'SettingManagement?handler=RefreshConfiguration' + }); }); })(jQuery); diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/nl.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/nl.json index 1aeb208560..d4c45b8aad 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/nl.json +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/nl.json @@ -10,6 +10,7 @@ "ConnectionStrings": "Connection Strings", "DisplayName:DefaultConnectionString": "Standaard Connection String", "DisplayName:UseSharedDatabase": "Gebruik de gedeelde database", + "ManageHostFeatures": "Beheer host functies", "Permission:TenantManagement": "Klanten beheer", "Permission:Create": "Maak aan", "Permission:Edit": "Bewerk", diff --git a/modules/virtual-file-explorer/src/Volo.Abp.VirtualFileExplorer.Web/Localization/Resources/nl.json b/modules/virtual-file-explorer/src/Volo.Abp.VirtualFileExplorer.Web/Localization/Resources/nl.json new file mode 100644 index 0000000000..4f00849893 --- /dev/null +++ b/modules/virtual-file-explorer/src/Volo.Abp.VirtualFileExplorer.Web/Localization/Resources/nl.json @@ -0,0 +1,14 @@ +{ + "culture": "nl", + "texts": { + "VirtualFileExplorer": "Virtuele bestandsverkenner", + "VirtualFileType": "Virtueel bestandstype", + "Menu:VirtualFileExplorer": "Virtuele bestandsverkenner", + "LastUpdateTime": "Tijdstip laatste update", + "VirtualFileName": "Virtuele bestandsnaam", + "FileContent": "Bestandsinhoud", + "Size": "Grootte", + "BackToRoot": "Terug naar hoofdmap", + "EmptyFileInfoList": "Er zijn geen virtuele bestanden" + } +} \ No newline at end of file diff --git a/npm/ng-packs/package.json b/npm/ng-packs/package.json index d604dd533b..8fb4c748b4 100644 --- a/npm/ng-packs/package.json +++ b/npm/ng-packs/package.json @@ -80,7 +80,7 @@ "just-compare": "^1.3.0", "lerna": "^3.19.0", "ng-packagr": "^11.0.1", - "ng-zorro-antd": "^10.1.1", + "ng-zorro-antd": "^11.0.1", "ngxs-schematic": "^1.1.9", "prettier": "^2.2.0", "protractor": "~7.0.0", diff --git a/npm/ng-packs/packages/components/package.json b/npm/ng-packs/packages/components/package.json index 68b26abf8c..243deddcd0 100644 --- a/npm/ng-packs/packages/components/package.json +++ b/npm/ng-packs/packages/components/package.json @@ -11,7 +11,7 @@ "@ng-bootstrap/ng-bootstrap": ">=6.0.0" }, "dependencies": { - "ng-zorro-antd": "^9.3.0", + "ng-zorro-antd": "^11.0.0", "tslib": "^2.0.0" }, "publishConfig": { diff --git a/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts b/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts index 387437cc04..87ad976491 100644 --- a/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts +++ b/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts @@ -1,5 +1,6 @@ import { Component, Injector, Optional, SkipSelf, Type } from '@angular/core'; import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; +import { filter } from 'rxjs/operators'; import { eLayoutType } from '../enums/common'; import { ABP } from '../models'; import { ReplaceableComponents } from '../models/replaceable-components'; @@ -23,6 +24,7 @@ import { TreeNode } from '../utils/tree-utils'; }) export class DynamicLayoutComponent { layout: Type; + layoutKey: eLayoutType; // TODO: Consider a shared enum (eThemeSharedComponents) for known layouts readonly layouts = new Map([ @@ -33,6 +35,10 @@ export class DynamicLayoutComponent { isLayoutVisible = true; + private router: Router; + private route: ActivatedRoute; + private routes: RoutesService; + constructor( injector: Injector, private localizationService: LocalizationService, @@ -41,36 +47,45 @@ export class DynamicLayoutComponent { @Optional() @SkipSelf() dynamicLayoutComponent: DynamicLayoutComponent, ) { if (dynamicLayoutComponent) return; - const route = injector.get(ActivatedRoute); - const router = injector.get(Router); - const routes = injector.get(RoutesService); - - this.subscription.addOne(router.events, event => { - if (event instanceof NavigationEnd) { - let expectedLayout = (route.snapshot.data || {}).layout; - - if (!expectedLayout) { - let node = findRoute(routes, getRoutePath(router)); - node = { parent: node } as TreeNode; - - while (node.parent) { - node = node.parent; - - if (node.layout) { - expectedLayout = node.layout; - break; - } - } - } + this.route = injector.get(ActivatedRoute); + this.router = injector.get(Router); + this.routes = injector.get(RoutesService); + + this.getLayout(); + this.subscription.addOne( + this.router.events.pipe(filter(event => event instanceof NavigationEnd)), + () => { + this.getLayout(); + }, + ); + + this.listenToLanguageChange(); + } + + private getLayout() { + let expectedLayout = (this.route.snapshot.data || {}).layout; - if (!expectedLayout) expectedLayout = eLayoutType.empty; + if (!expectedLayout) { + let node = findRoute(this.routes, getRoutePath(this.router)); + node = { parent: node } as TreeNode; - const key = this.layouts.get(expectedLayout); - this.layout = this.getComponent(key)?.component; + while (node.parent) { + node = node.parent; + + if (node.layout) { + expectedLayout = node.layout; + break; + } } - }); + } - this.listenToLanguageChange(); + if (!expectedLayout) expectedLayout = eLayoutType.empty; + + if (this.layoutKey === expectedLayout) return; + + const key = this.layouts.get(expectedLayout); + this.layout = this.getComponent(key)?.component; + this.layoutKey = expectedLayout; } private listenToLanguageChange() { diff --git a/npm/ng-packs/packages/core/src/lib/guards/auth.guard.ts b/npm/ng-packs/packages/core/src/lib/guards/auth.guard.ts index acd7417560..c95b890239 100644 --- a/npm/ng-packs/packages/core/src/lib/guards/auth.guard.ts +++ b/npm/ng-packs/packages/core/src/lib/guards/auth.guard.ts @@ -17,6 +17,6 @@ export class AuthGuard implements CanActivate { } this.authService.initLogin(); - return true; + return false; } } diff --git a/npm/ng-packs/packages/core/src/lib/tests/auth.guard.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/auth.guard.spec.ts index 18bf53ede8..f34f503227 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/auth.guard.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/auth.guard.spec.ts @@ -26,7 +26,7 @@ describe('AuthGuard', () => { spectator.inject(OAuthService).hasValidAccessToken.andReturn(false); const initLoginSpy = jest.spyOn(authService, 'initLogin'); - expect(guard.canActivate()).toBe(true); + expect(guard.canActivate()).toBe(false); expect(initLoginSpy).toHaveBeenCalled(); }); }); diff --git a/npm/ng-packs/packages/core/src/lib/tests/multi-tenancy-utils.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/multi-tenancy-utils.spec.ts index 5af037b7d0..66188f0bb3 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/multi-tenancy-utils.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/multi-tenancy-utils.spec.ts @@ -20,11 +20,10 @@ const environment = { }, oAuthConfig: { issuer: 'https://{0}.api.volosoft.com', + redirectUri: 'https://{0}.volosoft.com', clientId: 'MyProjectName_App', - dummyClientSecret: '1q2w3e*', - scope: 'MyProjectName', - oidc: false, - requireHttps: true, + responseType: 'code', + scope: 'offline_access MyProjectName', }, apis: { default: { @@ -91,7 +90,11 @@ describe('MultiTenancyUtils', () => { const replacedEnv = { ...environment, application: { ...environment.application, baseUrl: 'https://abp.volosoft.com' }, - oAuthConfig: { ...environment.oAuthConfig, issuer: 'https://abp.api.volosoft.com' }, + oAuthConfig: { + ...environment.oAuthConfig, + issuer: 'https://abp.api.volosoft.com', + redirectUri: 'https://abp.volosoft.com', + }, apis: { default: { url: 'https://abp.api.volosoft.com', diff --git a/npm/ng-packs/packages/core/src/lib/utils/multi-tenancy-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/multi-tenancy-utils.ts index abfc33d723..390a46db8e 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/multi-tenancy-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/multi-tenancy-utils.ts @@ -58,6 +58,13 @@ function setEnvironment(injector: Injector, tenancyName: string) { ); } + if (environment.oAuthConfig.redirectUri) { + environment.oAuthConfig.redirectUri = environment.oAuthConfig.redirectUri.replace( + tenancyPlaceholder, + tenancyName, + ); + } + environment.oAuthConfig.issuer = environment.oAuthConfig.issuer.replace( tenancyPlaceholder, tenancyName, diff --git a/npm/ng-packs/packages/core/testing/src/lib/core-testing.module.ts b/npm/ng-packs/packages/core/testing/src/lib/core-testing.module.ts index 1718946cab..1f07423779 100644 --- a/npm/ng-packs/packages/core/testing/src/lib/core-testing.module.ts +++ b/npm/ng-packs/packages/core/testing/src/lib/core-testing.module.ts @@ -1,8 +1,8 @@ import { ABP, BaseCoreModule, - CORE_OPTIONS, coreOptionsFactory, + CORE_OPTIONS, LIST_QUERY_DEBOUNCE_TIME, LOADER_DELAY, PermissionService, @@ -34,7 +34,10 @@ export class CoreTestingModule { { provide: APP_BASE_HREF, useValue: baseHref }, { provide: 'CORE_OPTIONS', - useValue: options, + useValue: { + skipGetAppConfiguration: true, + ...options, + }, }, { provide: CORE_OPTIONS, diff --git a/npm/ng-packs/packages/schematics/src/models/method.ts b/npm/ng-packs/packages/schematics/src/models/method.ts index c2833a7bfd..7dca1668f5 100644 --- a/npm/ng-packs/packages/schematics/src/models/method.ts +++ b/npm/ng-packs/packages/schematics/src/models/method.ts @@ -54,7 +54,7 @@ export class Body { this.body = value; break; case eBindingSourceId.Path: - const regex = new RegExp('{' + camelName + '}', 'g'); + const regex = new RegExp('{(' + camelName + '|' + name + ')}', 'g'); this.url = this.url.replace(regex, '${' + value + '}'); break; default: diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/application-layout/application-layout.component.html b/npm/ng-packs/packages/theme-basic/src/lib/components/application-layout/application-layout.component.html index eb68dc7df0..7892d43a00 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/application-layout/application-layout.component.html +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/application-layout/application-layout.component.html @@ -1,7 +1,7 @@