Skip to content

Commit 955376c

Browse files
committed
Merge branch 'dev' into gterdem/organization_unit_enhancement
2 parents d82f472 + 6a892bf commit 955376c

File tree

173 files changed

+2362
-719
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

173 files changed

+2362
-719
lines changed

docs/en/AspNet-Boilerplate-Migration-Guide.md

+8-12
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,9 @@ However, it provides the following methods those can be used to query a single e
216216
* `FindAsync(id)` returns the entity or null if not found.
217217
* `GetAsync(id)` method returns the entity or throws an `EntityNotFoundException` (which causes HTTP 404 status code) if not found.
218218

219-
#### Sync vs Async
219+
#### Sync vs Async
220220

221-
ABP Framework repository has no sync methods (like `Insert`). All the methods are async (like `InsertAsync`). So, if your application has sync repository method usages, convert them to async versions.
221+
ABP Framework repository has no sync methods (like `Insert`). All the methods are async (like `InsertAsync`). So, if your application has sync repository method usages, convert them to async versions.
222222

223223
In general, ABP Framework forces you to completely use async everywhere, because mixing async & sync methods is not a recommended approach.
224224

@@ -444,7 +444,7 @@ ASP.NET Boilerplate uses Castle Windsor's [logging facility](http://docs.castlep
444444
using Castle.Core.Logging; //1: Import Logging namespace
445445
446446
public class TaskAppService : ITaskAppService
447-
{
447+
{
448448
//2: Getting a logger using property injection
449449
public ILogger Logger { get; set; }
450450

@@ -693,26 +693,22 @@ public class AbpTenantManagementWebMainMenuContributor : IMenuContributor
693693
var administrationMenu = context.Menu.GetAdministration();
694694

695695
//Resolve some needed services from the DI container
696-
var authorizationService = context.ServiceProvider
697-
.GetRequiredService<IAuthorizationService>();
698-
var l = context.ServiceProvider
699-
.GetRequiredService<IStringLocalizer<AbpTenantManagementResource>>();
696+
var l = context.GetLocalizer<AbpTenantManagementResource>();
700697

701698
var tenantManagementMenuItem = new ApplicationMenuItem(
702699
TenantManagementMenuNames.GroupName,
703700
l["Menu:TenantManagement"],
704701
icon: "fa fa-users");
705-
702+
706703
administrationMenu.AddItem(tenantManagementMenuItem);
707704

708705
//Conditionally add the "Tenants" menu item based on the permission
709-
if (await authorizationService
710-
.IsGrantedAsync(TenantManagementPermissions.Tenants.Default))
706+
if (await context.IsGrantedAsync(TenantManagementPermissions.Tenants.Default))
711707
{
712708
tenantManagementMenuItem.AddItem(
713709
new ApplicationMenuItem(
714710
TenantManagementMenuNames.Tenants,
715-
l["Tenants"],
711+
l["Tenants"],
716712
url: "/TenantManagement/Tenants"));
717713
}
718714
}
@@ -731,4 +727,4 @@ The following features are not present for the ABP Framework. Here, a list of so
731727
* [Real time notification system](https://aspnetboilerplate.com/Pages/Documents/Notification-System) ([#633](https://github.com/abpframework/abp/issues/633))
732728
* [NHibernate Integration](https://aspnetboilerplate.com/Pages/Documents/NHibernate-Integration) ([#339](https://github.com/abpframework/abp/issues/339)) - We don't intent to work on this, but any community contribution welcome.
733729

734-
Some of these features will eventually be implemented. However, you can implement them yourself if they are important for you. If you want, you can [contribute](Contribution/Index.md) to the framework, it is appreciated.
730+
Some of these features will eventually be implemented. However, you can implement them yourself if they are important for you. If you want, you can [contribute](Contribution/Index.md) to the framework, it is appreciated.

docs/en/Customizing-Application-Modules-Overriding-Services.md

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ In most cases, you will want to change one or a few methods of the current imple
5959
### Example: Overriding an Application Service
6060

6161
````csharp
62+
//[RemoteService(IsEnabled = false)] // If you use dynamic controller feature you can disable remote service. Prevent creating duplicate controller for the application service.
6263
[Dependency(ReplaceServices = true)]
6364
[ExposeServices(typeof(IIdentityUserAppService), typeof(IdentityUserAppService))]
6465
public class MyIdentityUserAppService : IdentityUserAppService

docs/en/Multi-Tenancy.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -303,10 +303,10 @@ TODO:...
303303
Volo.Abp.AspNetCore.MultiTenancy package adds following tenant resolvers to determine current tenant from current web request (ordered by priority). These resolvers are added and work out of the box:
304304

305305
* **CurrentUserTenantResolveContributor**: Gets the tenant id from claims of the current user, if the current user has logged in. **This should always be the first contributor for security**.
306-
* **QueryStringTenantResolver**: Tries to find current tenant id from query string parameter. Parameter name is "__tenant" by default.
307-
* **RouteTenantResolver**: Tries to find current tenant id from route (URL path). Variable name is "__tenant" by default. So, if you defined a route with this variable, then it can determine the current tenant from the route.
308-
* **HeaderTenantResolver**: Tries to find current tenant id from HTTP header. Header name is "__tenant" by default.
309-
* **CookieTenantResolver**: Tries to find current tenant id from cookie values. Cookie name is "__tenant" by default.
306+
* **QueryStringTenantResolveContributor**: Tries to find current tenant id from query string parameter. Parameter name is "__tenant" by default.
307+
* **RouteTenantResolveContributor**: Tries to find current tenant id from route (URL path). Variable name is "__tenant" by default. So, if you defined a route with this variable, then it can determine the current tenant from the route.
308+
* **HeaderTenantResolveContributor**: Tries to find current tenant id from HTTP header. Header name is "__tenant" by default.
309+
* **CookieTenantResolveContributor**: Tries to find current tenant id from cookie values. Cookie name is "__tenant" by default.
310310

311311
> If you use nginx as a reverse proxy server, please note that if `TenantKey` contains an underscore or other special characters, there may be a problem, please refer to:
312312
http://nginx.org/en/docs/http/ngx_http_core_module.html#ignore_invalid_headers
@@ -346,7 +346,7 @@ namespace MyCompany.MyProject
346346
//Subdomain format: {0}.mydomain.com
347347
//Adding as the second highest priority resolver after 'CurrentUserTenantResolveContributor' to
348348
//ensure the user cannot impersonate a different tenant.
349-
options.TenantResolvers.Insert(1, new DomainTenantResolver("{0}.mydomain.com"));
349+
options.TenantResolvers.Insert(1, new DomainTenantResolveContributor("{0}.mydomain.com"));
350350
});
351351

352352
//...
@@ -357,7 +357,7 @@ namespace MyCompany.MyProject
357357

358358
{0} is the the placeholder to determine current tenant's unique name.
359359

360-
Instead of ``options.TenantResolvers.Insert(1, new DomainTenantResolver("{0}.mydomain.com"));`` you can use this shortcut:
360+
Instead of ``options.TenantResolvers.Insert(1, new DomainTenantResolveContributor("{0}.mydomain.com"));`` you can use this shortcut:
361361

362362
````C#
363363
options.AddDomainTenantResolver("{0}.mydomain.com");

docs/en/Object-To-Object-Mapping.md

+55
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,61 @@ public class MyProfile : Profile
162162

163163
It is suggested to use the `MapExtraProperties()` method if both classes are extensible objects (implement the `IHasExtraProperties` interface). See the [object extension document](Object-Extensions.md) for more.
164164

165+
### Other Useful Extension Methods
166+
167+
There are some more extension methods those can simplify your mapping code.
168+
169+
#### Ignoring Audit Properties
170+
171+
It is common to ignore audit properties when you map an object to another.
172+
173+
Assume that you need to map a `ProductDto` ([DTO](Data-Transfer-Objects.md)) to a `Product` [entity](Entities.md) and the entity is inheriting from the `AuditedEntity` class (which provides properties like `CreationTime`, `CreatorId`, `IHasModificationTime`... etc).
174+
175+
You probably want to ignore these base properties while mapping from the DTO. You can use `IgnoreAuditedObjectProperties()` method to ignore all audit properties (instead of manually ignoring them one by one):
176+
177+
````csharp
178+
public class MyProfile : Profile
179+
{
180+
public MyProfile()
181+
{
182+
CreateMap<ProductDto, Product>()
183+
.IgnoreAuditedObjectProperties();
184+
}
185+
}
186+
````
187+
188+
There are more extension methods like `IgnoreFullAuditedObjectProperties()` and `IgnoreCreationAuditedObjectProperties()` those can be used based on your entity type.
189+
190+
> See the "*Base Classes & Interfaces for Audit Properties*" section in the [entities document](Entities.md) to know more about auditing properties.
191+
192+
#### Ignoring Other Properties
193+
194+
In AutoMapper, you typically write such a mapping code to ignore a property:
195+
196+
````csharp
197+
public class MyProfile : Profile
198+
{
199+
public MyProfile()
200+
{
201+
CreateMap<SimpleClass1, SimpleClass2>()
202+
.ForMember(x => x.CreationTime, map => map.Ignore());
203+
}
204+
}
205+
````
206+
207+
We found it unnecessarily long and created the `Ignore()` extension method:
208+
209+
````csharp
210+
public class MyProfile : Profile
211+
{
212+
public MyProfile()
213+
{
214+
CreateMap<SimpleClass1, SimpleClass2>()
215+
.Ignore(x => x.CreationTime);
216+
}
217+
}
218+
````
219+
165220
## Advanced Topics
166221

167222
### IObjectMapper<TContext> Interface

docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ context.Services.Replace(
5959
### 示例: 重写服务方法
6060

6161
````csharp
62+
//[RemoteService(IsEnabled = false)] // 如果你在使用动态控制器,为了避免为应用服务创建重复的控制器, 你可以禁用远程访问.
6263
[Dependency(ReplaceServices = true)]
6364
[ExposeServices(typeof(IIdentityUserAppService), typeof(IdentityUserAppService))]
6465
public class MyIdentityUserAppService : IdentityUserAppService

docs/zh-Hans/Multi-Tenancy.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,10 @@ TODO:...
304304
Volo.Abp.AspNetCore.MultiTenancy 添加了下面这些租户解析器,从当前Web请求(按优先级排序)中确定当前租户.
305305

306306
* **CurrentUserTenantResolveContributor**: 如果当前用户已登录,从当前用户的声明中获取租户Id. **出于安全考虑,应该始终将其做为第一个Contributor**.
307-
* **QueryStringTenantResolver**: 尝试从query string参数中获取当前租户,默认参数名为"__tenant".
308-
* **RouteTenantResolver**:尝试从当前路由中获取(URL路径),默认是变量名是"__tenant".所以,如果你的路由中定义了这个变量,就可以从路由中确定当前租户.
309-
* **HeaderTenantResolver**: 尝试从HTTP header中获取当前租户,默认的header名称是"__tenant".
310-
* **CookieTenantResolver**: 尝试从当前cookie中获取当前租户.默认的Cookie名称是"__tenant".
307+
* **QueryStringTenantResolveContributor**: 尝试从query string参数中获取当前租户,默认参数名为"__tenant".
308+
* **RouteTenantResolveContributor**:尝试从当前路由中获取(URL路径),默认是变量名是"__tenant".所以,如果你的路由中定义了这个变量,就可以从路由中确定当前租户.
309+
* **HeaderTenantResolveContributor**: 尝试从HTTP header中获取当前租户,默认的header名称是"__tenant".
310+
* **CookieTenantResolveContributor**: 尝试从当前cookie中获取当前租户.默认的Cookie名称是"__tenant".
311311

312312
> 如果你使用nginx作为反向代理服务器,请注意如果`TenantKey`包含下划线或其他特殊字符可能存在问题, 请参考:
313313
http://nginx.org/en/docs/http/ngx_http_core_module.html#ignore_invalid_headers
@@ -344,7 +344,7 @@ namespace MyCompany.MyProject
344344
Configure<AbpTenantResolveOptions>(options =>
345345
{
346346
//子域名格式: {0}.mydomain.com (作为第二优先级解析器添加, 位于CurrentUserTenantResolveContributor之后)
347-
options.TenantResolvers.Insert(1, new DomainTenantResolver("{0}.mydomain.com"));
347+
options.TenantResolvers.Insert(1, new DomainTenantResolveContributor("{0}.mydomain.com"));
348348
});
349349

350350
//...
@@ -355,7 +355,7 @@ namespace MyCompany.MyProject
355355

356356
{0}是用来确定当前租户唯一名称的占位符.
357357

358-
你可以使用下面的方法,代替``options.TenantResolvers.Insert(1, new DomainTenantResolver("{0}.mydomain.com"));``:
358+
你可以使用下面的方法,代替``options.TenantResolvers.Insert(1, new DomainTenantResolveContributor("{0}.mydomain.com"));``:
359359

360360
````C#
361361
options.AddDomainTenantResolver("{0}.mydomain.com");

docs/zh-Hans/SignalR-Integration.md

+11-1
Original file line numberDiff line numberDiff line change
@@ -224,4 +224,14 @@ ABP实现 `SignalR` 的 `IUserIdProvider` 接口,从ABP框架的 `ICurrentUser`
224224

225225
参阅 [SignalR集成Demo](https://github.com/abpframework/abp-samples/tree/master/SignalRDemo),它有一个简单的聊天页面,可以在(经过身份验证的)用户之间发送消息.
226226

227-
![signalr-demo-chat](images/signalr-demo-chat.png)
227+
![signalr-demo-chat](images/signalr-demo-chat.png)
228+
229+
## 备注
230+
231+
ABP框架不会更改SignalR. 就像在其他ASP.NET Core应用程序中一样,它也可以在基于ABP框架的应用程序中工作.
232+
233+
参考[微软文档](https://docs.microsoft.com/zh-cn/aspnet/core/signalr/scale)托管和扩展您的应用程序,集成[Azure](https://docs.microsoft.com/zh-cn/aspnet/core/signalr/publish-to-azure-web-app)[Redis底版](https://docs.microsoft.com/zh-cn/aspnet/core/signalr/redis-backplane)...等.
234+
235+
## 另请参阅
236+
237+
* [微软SignalR文档](https://docs.microsoft.com/zh-cn/aspnet/core/signalr/introduction)

0 commit comments

Comments
 (0)