From c73a3942d5e43fa7ed131ebd5db3074111fa4512 Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 6 Dec 2022 20:23:44 +0800 Subject: [PATCH 1/5] Fix namespace problem. --- .../CSharp/CSharpServiceProxyGenerator.cs | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ServiceProxying/CSharp/CSharpServiceProxyGenerator.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ServiceProxying/CSharp/CSharpServiceProxyGenerator.cs index 49c8899bc4..c2016a4ba2 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ServiceProxying/CSharp/CSharpServiceProxyGenerator.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ServiceProxying/CSharp/CSharpServiceProxyGenerator.cs @@ -19,7 +19,7 @@ public class CSharpServiceProxyGenerator : ServiceProxyGeneratorBase" + $"{Environment.NewLine}" + $"{Environment.NewLine}// ReSharper disable once CheckNamespace" + @@ -44,7 +44,7 @@ public class CSharpServiceProxyGenerator : ServiceProxyGeneratorBase;" + $"{Environment.NewLine}" + @@ -53,7 +53,7 @@ public class CSharpServiceProxyGenerator : ServiceProxyGeneratorBase" + $"{Environment.NewLine}" + $"{Environment.NewLine}// ReSharper disable once CheckNamespace" + @@ -65,24 +65,22 @@ public class CSharpServiceProxyGenerator : ServiceProxyGeneratorBase" + - $"{Environment.NewLine}" + - $"{Environment.NewLine}// ReSharper disable once CheckNamespace" + - $"{Environment.NewLine}namespace ;" + - $"{Environment.NewLine}" + - $"{Environment.NewLine}public " + - $"{Environment.NewLine}{{" + - $"{Environment.NewLine} " + - $"{Environment.NewLine}}}" + - $"{Environment.NewLine}"; - private static readonly List ClassUsingNamespaceList = new() + private readonly static string DtoTemplate = "// This file is automatically generated by ABP framework to use MVC Controllers from CSharp" + + $"{Environment.NewLine}" + + $"{Environment.NewLine}" + + $"{Environment.NewLine}// ReSharper disable once CheckNamespace" + + $"{Environment.NewLine}namespace ;" + + $"{Environment.NewLine}" + + $"{Environment.NewLine}public " + + $"{Environment.NewLine}{{" + + $"{Environment.NewLine} " + + $"{Environment.NewLine}}}" + + $"{Environment.NewLine}"; + + private readonly static List ClassUsingNamespaceList = new() { "using System;", + "using System.Collections.Generic;", "using System.Threading.Tasks;", "using Volo.Abp.Application.Dtos;", "using Volo.Abp.Http.Client;", @@ -91,14 +89,23 @@ public class CSharpServiceProxyGenerator : ServiceProxyGeneratorBase InterfaceUsingNamespaceList = new() + private readonly static List InterfaceUsingNamespaceList = new() { "using System;", + "using System.Collections.Generic;", "using System.Threading.Tasks;", "using Volo.Abp.Application.Dtos;", "using Volo.Abp.Application.Services;" }; + private readonly static List DtoUsingNamespaceList = new() + { + "using System;", + "using System.Collections.Generic;", + "using Volo.Abp.Application.Dtos;", + "using Volo.Abp.ObjectExtending;", + }; + public CSharpServiceProxyGenerator( CliHttpClientFactory cliHttpClientFactory, IJsonSerializer jsonSerializer) : @@ -106,7 +113,7 @@ public class CSharpServiceProxyGenerator : ServiceProxyGeneratorBase types.Contains(x.Key))) { var dto = new StringBuilder(DtoTemplate); - var dtoUsingNamespaceList = new List() + var dtoUsingNamespaceList = new List(DtoUsingNamespaceList) { $"using {GetTypeNamespace(type.Key)};" }; @@ -478,7 +485,7 @@ public class CSharpServiceProxyGenerator : ServiceProxyGeneratorBase x).Select(x => x))); + dto.Replace($"{UsingPlaceholder}", string.Join(Environment.NewLine, dtoUsingNamespaceList.Distinct().OrderBy(x => x).Select(x => x))); dto.Replace(PropertyPlaceholder, properties.ToString()); var folder = args.Folder.IsNullOrWhiteSpace() From ff353676f9e9d84b76704f5d8534943df27979bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 6 Dec 2022 16:44:40 +0300 Subject: [PATCH 2/5] Added section: "Using a Distributed Event Bus" --- docs/en/Deployment/Distributed-Microservice.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/en/Deployment/Distributed-Microservice.md b/docs/en/Deployment/Distributed-Microservice.md index 39c9e8b70d..758a41ba0d 100644 --- a/docs/en/Deployment/Distributed-Microservice.md +++ b/docs/en/Deployment/Distributed-Microservice.md @@ -30,6 +30,16 @@ await builder.AddApplicationAsync(options => }); ```` +## Using a Distributed Event Bus +ABP's [Distributed Event Bus](../Distributed-Event-Bus.md) system provides a standard interface to communicate to other applications and services. While the name is "distributed", the default implementation is in-process. That means, your applications / services can not communicate to each other unless you explicitly configure a distributed event bus provider. -s +If you are building a distributed system, then the applications should communicate through an external distributed messaging server. Please follow the [Distributed Event Bus](../Distributed-Event-Bus.md) document to learn how to install and configure your distributed event bus provider. + +> **Warning**: Even if you don't use the distributed event bus directly in your application code, the ABP Framework and some of the modules you are using may use it. So, if you are building a distributed system, always configure a distributed event bus provider. + +> **Info**: [Clustered deployment](Clustered-Environment.md) of a single application is not considered as a distributed system. So, if you only have a single application with multiple instances serving behind a load balancer, a real distributed messaging server may not be needed. + +## See Also + +* [Deploying to a Clustered Environment](Clustered-Environment.md) From 0f787a3198c24db9b19686d879c3a60674e2b8be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 6 Dec 2022 17:27:16 +0300 Subject: [PATCH 3/5] Application-Startup document progress --- docs/en/Application-Startup.md | 18 +++++++++++++++++- .../Getting-Started-AspNetCore-Application.md | 2 +- docs/en/Getting-Started.md | 2 -- .../en/images/app-startup-console-initial.png | Bin 0 -> 47711 bytes 4 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 docs/en/images/app-startup-console-initial.png diff --git a/docs/en/Application-Startup.md b/docs/en/Application-Startup.md index 6dd6df6a03..8ba51d5aa1 100644 --- a/docs/en/Application-Startup.md +++ b/docs/en/Application-Startup.md @@ -1,3 +1,19 @@ ## ABP Application Startup -TODO \ No newline at end of file +You typically use the [ABP CLI](CLI.md)'s `abp new` command to [get started](Getting-Started.md) with one of the pre-built [startup solution templates](Startup-Templates/Index.md). When you do that, you generally don't need to know the details of how the ABP Framework is integrated with your application, how it is configured and initialized. The startup template comes with many fundamental ABP packages and [application modules](Modules/Index) are pre-installed and configured for you. + +> It is always suggested to [get started with a startup template](Getting-Started.md) and modify it for your requirements. + +While the ABP Framework has a lot of features and integrations, it is built as a lightweight and modular framework. It consists of hundreds of NuGet and NMP packages, so you can use only the features you need to. If you follow the [Getting Started with an Empty ASP.NET Core MVC / Razor Pages Application](Getting-Started-AspNetCore-Application.md) document, you see how easy to install the ABP Framework into an empty ASP.NET Core project from scratch. You only install a single NuGet package and make a few small changes. + +This document is for who want to better understand how the ABP Framework is initialized and configured on startup. + +## Installing to a Console Application + +A .NET Console application is the minimalist .NET application. So, it is best to show installing the ABP Framework to a console application as a minimalist example. + +If you [create a new console application with Visual Studio](https://learn.microsoft.com/en-us/dotnet/core/tutorials/with-visual-studio) (for .NET 7.0 or later), you will see the following solution structure: + +![app-startup-console-initial](images/app-startup-console-initial.png) + +That solution template uses .NET's top level statements... \ No newline at end of file diff --git a/docs/en/Getting-Started-AspNetCore-Application.md b/docs/en/Getting-Started-AspNetCore-Application.md index c7f329878c..117b0b499e 100644 --- a/docs/en/Getting-Started-AspNetCore-Application.md +++ b/docs/en/Getting-Started-AspNetCore-Application.md @@ -1,4 +1,4 @@ -# Getting Started With an ABP and AspNet Core MVC Web Application +# Getting Started with an Empty ASP.NET Core MVC / Razor Pages Application This tutorial explains how to start ABP from scratch with minimal dependencies. You generally want to start with the **[startup template](Getting-Started-AspNetCore-MVC-Template.md)**. diff --git a/docs/en/Getting-Started.md b/docs/en/Getting-Started.md index 0304eb2320..6352f43bc7 100644 --- a/docs/en/Getting-Started.md +++ b/docs/en/Getting-Started.md @@ -11,8 +11,6 @@ > This document assumes that you prefer to use **{{ UI_Value }}** as the UI framework and **{{ DB_Value }}** as the database provider. For other options, please change the preference on top of this document. -## Contents - This tutorial explains how to **create and run** a new web application using the ABP Framework. Follow the steps below; 1. [Setup your development environment](Getting-Started-Setup-Environment.md) diff --git a/docs/en/images/app-startup-console-initial.png b/docs/en/images/app-startup-console-initial.png new file mode 100644 index 0000000000000000000000000000000000000000..2928037500cdc9c28f638d546b653860a2565c7d GIT binary patch literal 47711 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 Date: Tue, 6 Dec 2022 17:27:41 +0300 Subject: [PATCH 4/5] Update Application-Startup.md --- docs/en/Application-Startup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Application-Startup.md b/docs/en/Application-Startup.md index 8ba51d5aa1..23535e9203 100644 --- a/docs/en/Application-Startup.md +++ b/docs/en/Application-Startup.md @@ -16,4 +16,4 @@ If you [create a new console application with Visual Studio](https://learn.micro ![app-startup-console-initial](images/app-startup-console-initial.png) -That solution template uses .NET's top level statements... \ No newline at end of file +TODO: continue... \ No newline at end of file From 18ace7276688daf9d645574aa8737896d4cb4139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 6 Dec 2022 20:26:41 +0300 Subject: [PATCH 5/5] Enhance the Application-Startup document --- docs/en/Application-Startup.md | 186 ++++++++++++++++++++++++++- docs/en/Module-Development-Basics.md | 1 - 2 files changed, 183 insertions(+), 4 deletions(-) diff --git a/docs/en/Application-Startup.md b/docs/en/Application-Startup.md index 23535e9203..5ca971e733 100644 --- a/docs/en/Application-Startup.md +++ b/docs/en/Application-Startup.md @@ -2,7 +2,7 @@ You typically use the [ABP CLI](CLI.md)'s `abp new` command to [get started](Getting-Started.md) with one of the pre-built [startup solution templates](Startup-Templates/Index.md). When you do that, you generally don't need to know the details of how the ABP Framework is integrated with your application, how it is configured and initialized. The startup template comes with many fundamental ABP packages and [application modules](Modules/Index) are pre-installed and configured for you. -> It is always suggested to [get started with a startup template](Getting-Started.md) and modify it for your requirements. +> It is always suggested to [get started with a startup template](Getting-Started.md) and modify it for your requirements. Read that document only if you want to understand the details or you need to modify how the application starts. While the ABP Framework has a lot of features and integrations, it is built as a lightweight and modular framework. It consists of hundreds of NuGet and NMP packages, so you can use only the features you need to. If you follow the [Getting Started with an Empty ASP.NET Core MVC / Razor Pages Application](Getting-Started-AspNetCore-Application.md) document, you see how easy to install the ABP Framework into an empty ASP.NET Core project from scratch. You only install a single NuGet package and make a few small changes. @@ -12,8 +12,188 @@ This document is for who want to better understand how the ABP Framework is init A .NET Console application is the minimalist .NET application. So, it is best to show installing the ABP Framework to a console application as a minimalist example. -If you [create a new console application with Visual Studio](https://learn.microsoft.com/en-us/dotnet/core/tutorials/with-visual-studio) (for .NET 7.0 or later), you will see the following solution structure: +If you [create a new console application with Visual Studio](https://learn.microsoft.com/en-us/dotnet/core/tutorials/with-visual-studio) (for .NET 7.0 or later), you will see the following solution structure (I named the solution as `MyConsoleDemo`): ![app-startup-console-initial](images/app-startup-console-initial.png) -TODO: continue... \ No newline at end of file +This example uses the [top level statements](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/top-level-statements), so it consists of only a single line of code. The first step is to install the [Volo.Abp.Core](https://www.nuget.org/packages/Volo.Abp.Core) NuGet package, which is the most core NuGet package of the ABP framework. You can install it using [Package Manager Console](https://learn.microsoft.com/en-us/nuget/consume-packages/install-use-packages-powershell) in Visual Studio: + +````bash +Install-Package Volo.Abp.Core +```` + +Alternatively, you can use a command-line terminal in the root folder of the project (the folder containing the `MyConsoleDemo.csproj` file, for this example): + +````bash +dotnet add package Volo.Abp.Core +```` + +After adding the NuGet package, we should create a root [module class](Module-Development-Basics.md) for our application. We can create the following class in the project: + +````csharp +using Volo.Abp.Modularity; + +namespace MyConsoleDemo +{ + public class MyConsoleDemoModule : AbpModule + { + } +} +```` + +This is an empty class deriving from the `AbpModule` class. It is the main class that you will control your application's dependencies and implement your configuration, startup and shutdown logic. For more information, please check the [Modularity](Module-Development-Basics.md) document. + +As the second and the last step, change the `Program.cs` as shown in the following code block: + +````csharp +using MyConsoleDemo; +using Volo.Abp; + +// 1: Create the application container +using var application = await AbpApplicationFactory.CreateAsync(); + +// 2: Initialize/start the ABP Framework and all the modules +await application.InitializeAsync(); + +Console.WriteLine("ABP Framework has been started..."); + +// 3: Stop the ABP Framework and all the modules +await application.ShutdownAsync(); +```` + +That's all. Now, ABP Framework is installed, integrated, started and stopped in your application. From now, you can install [ABP packages](https://abp.io/packages) to your application whenever you need them. + +## Installing a Framework Package + +For example, if you want to send emails from your application, you can use .NET's standard [SmtpClient class](https://learn.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient). ABP also provides an `IEmailSender` service that simplifies [sending emails](Emailing.md) and configuring the email settings in a central place. If you want to use it, you should install the [Volo.Abp.Emailing](https://www.nuget.org/packages/Volo.Abp.Emailing) NuGet package to your project: + +````bash +dotnet add package Volo.Abp.Emailing +```` + +Once you add a new ABP package/module, you also need to specify the module dependency from your module class. So, change the `MyConsoleDemoModule` class as shown below: + +````csharp +using Volo.Abp.Emailing; +using Volo.Abp.Modularity; + +namespace MyConsoleDemo +{ + [DependsOn(typeof(AbpEmailingModule))] + public class MyConsoleDemoModule : AbpModule + { + } +} +```` + +I've just added a `DependsOn` attribute to declare that I want to use the ABP Emailing Module (`AbpEmailingModule`). Now, I can use the `IEmailSender` service in my `Program.cs`: + +````csharp +using Microsoft.Extensions.DependencyInjection; +using MyConsoleDemo; +using Volo.Abp; +using Volo.Abp.Emailing; + +using var application = await AbpApplicationFactory.CreateAsync(); +await application.InitializeAsync(); + +// Sending emails using the IEmailSender service +var emailsender = application.ServiceProvider.GetRequiredService(); +await emailsender.SendAsync( + to: "info@acme.com", + subject: "Hello World", + body: "My message body..." +); + +await application.ShutdownAsync(); +```` + +> If you run this application, you get a runtime error indicating that the email sending settings hasn't been done yet. You can check the [Email Sending](Emailing.md) document to learn how to configure it. + +That's all. Install an ABP NuGet package, add the module dependency (using the `DependsOn` attribute) and use any service inside the NuGet package. + +The [ABP CLI](CLI.md) already has a special command to perform adding an ABP NuGet and also adding the `DependsOn` attribute to your module class for you with a single command: + +````bash +abp add-package Volo.Abp.Emailing +```` + +We suggest you to use the `add-package` command instead of manually doing it. + +## AbpApplicationFactory + +`AbpApplicationFactory` is the main class that creates an ABP application container. It provides a single `CreateAsync` (and `Create` if you can't use asynchronous programming) method with multiple overloads. Let's investigate these overloads to understand where you can use them. + +The first overload gets a generic module class parameter as we've used before in this document: + +````csharp +AbpApplicationFactory.CreateAsync(); +```` + +The second overload gets the module class as a `Type` parameter, instead of a generic parameter. So, the previous code block can be re-written as shown below: + +````csharp +AbpApplicationFactory.CreateAsync(typeof(MyConsoleDemoModule)); +```` + +Both overloads works exactly same. So, you can use the second one if you don't know the module class type on development time and you (somehow) calculate it on runtime. + +If you create one of the methods above, ABP creates an internal service collection (`IServiceCollection`) and an internal service provider (`IServiceProvider`) to automate the [dependency injection](Dependency-Injection.md) setup from your application code. Notice that we've used the `application.ServiceProvider` property in the *Installing a Framework Package* section to resolve the `IEmailSender` service from the dependency injection system. + +The next overload gets an `IServiceCollection` parameter from you to allow you to set up the dependency injection system yourself, or integrate to another framework (like ASP.NET Core) that also setups the dependency injection system internally. + +We can change the `Program.cs` as shown below to externally manage the dependency injection setup: + +````csharp +using Microsoft.Extensions.DependencyInjection; +using MyConsoleDemo; +using Volo.Abp; + +// 1: Manually created the IServiceCollection +IServiceCollection services = new ServiceCollection(); + +// 2: Pass the IServiceCollection externally to the ABP Framework +using var application = await AbpApplicationFactory + .CreateAsync(services); + +// 3: Manually built the IServiceProvider object +IServiceProvider serviceProvider = services.BuildServiceProvider(); + +// 4: Pass the IServiceProvider externally to the ABP Framework +await application.InitializeAsync(serviceProvider); + +Console.WriteLine("ABP Framework has been started..."); + +await application.ShutdownAsync(); +```` + +In this example, we've used .NET's standard dependency injection container. The `services.BuildServiceProvider()` call creates the standard container. However, ABP provides an alternative extension method, `BuildServiceProviderFromFactory()`, that gracefully work even if you are using another DI container: + +````csharp +IServiceProvider serviceProvider = services.BuildServiceProviderFromFactory(); +```` + +You can check the [Autofac Integration](Autofac-Integration.md) document if you want to learn how you can integrate the [Autofac](https://autofac.org/) dependency injection container with the ABP Framework. + +Finally, the `CreateAsync` method has a last overload that takes the module class name as a `Type` parameter and a `IServiceCollection` object. So, we could re-write the last `CreateAsync` method usage as like in the following code block: + +````csharp +using var application = await AbpApplicationFactory + .CreateAsync(typeof(MyConsoleDemoModule), services); +```` + +> All of the `CreateAsync` method overloads have `Create` counterparts. If your application type can not utilize asynchronous programming (that means you can't use the `await` keyword), then you can use the `Create` method instead of the `CreateAsync` method. + +### AbpApplicationCreationOptions + +All of the `CreateAsync` overloads can get an optional `Action` parameter to configure the options that is used on the application creation. See the following example: + +````csharp +using var application = await AbpApplicationFactory + .CreateAsync(options => + { + options.ApplicationName = "MyApp"; + }); +```` + +We've passed a lambda method to configure the `ApplicationName` option. \ No newline at end of file diff --git a/docs/en/Module-Development-Basics.md b/docs/en/Module-Development-Basics.md index dd01f81ff4..dfce0bf4b2 100644 --- a/docs/en/Module-Development-Basics.md +++ b/docs/en/Module-Development-Basics.md @@ -20,7 +20,6 @@ public class BlogModule : AbpModule { } - ```` ### Configuring Dependency Injection & Other Modules