mirror of https://github.com/abpframework/abp.git
95 changed files with 1089 additions and 194 deletions
@ -0,0 +1,3 @@ |
|||||
|
# Distributed Event Bus RabbitMQ Integration |
||||
|
|
||||
|
TODO |
||||
@ -0,0 +1,56 @@ |
|||||
|
# Sample Applications |
||||
|
|
||||
|
Here, a list of official samples built with the ABP Framework. Most of these samples are located under the [abpframework/abp-samples](https://github.com/abpframework/abp-samples) GitHub repository. |
||||
|
|
||||
|
### Microservice Demo |
||||
|
|
||||
|
A complete solution to demonstrate how to build systems based on the microservice architecture. |
||||
|
|
||||
|
* [The complete documentation for this sample](Microservice-Demo.md) |
||||
|
* [Source code](https://github.com/abpframework/abp/tree/dev/samples/MicroserviceDemo) |
||||
|
* [Microservice architecture document](../Microservice-Architecture.md) |
||||
|
|
||||
|
### Book Store |
||||
|
|
||||
|
A simple CRUD application to show basic principles of developing an application with the ABP Framework. The same sample was implemented with different technologies: |
||||
|
|
||||
|
* **Book Store: Razor Pages UI & Entity Framework Core** |
||||
|
|
||||
|
* [Tutorial](https://docs.abp.io/en/abp/latest/Tutorials/Part-1?UI=MVC) |
||||
|
* [Source code](https://github.com/abpframework/abp-samples/tree/master/BookStore) |
||||
|
|
||||
|
* **Book Store: Angular UI & MongoDB** |
||||
|
|
||||
|
* [Tutorial](https://docs.abp.io/en/abp/latest/Tutorials/Part-1?UI=NG) |
||||
|
* [Source code](https://github.com/abpframework/abp-samples/tree/master/BookStore-Angular-MongoDb) |
||||
|
|
||||
|
* **Book Store: Modular application (Razor Pages UI & EF Core)** |
||||
|
|
||||
|
* [Source code](https://github.com/abpframework/abp-samples/tree/master/BookStore-Modular) |
||||
|
|
||||
|
While there is no Razor Pages & MongoDB combination, you can check both documents to understand it since DB & UI selection don't effect each other. |
||||
|
|
||||
|
### Other Samples |
||||
|
|
||||
|
* **Entity Framework Migrations**: A solution to demonstrate how to split your application into multiple databases each database contains different modules. |
||||
|
* [Source code](https://github.com/abpframework/abp-samples/tree/master/DashboardDemo) |
||||
|
* [EF Core database migrations document](../Entity-Framework-Core-Migrations.md) |
||||
|
* **Dashboard Demo**: A simple application to show how to use the widget system for the ASP.NET Core MVC UI. |
||||
|
* [Source code](https://github.com/abpframework/abp-samples/tree/master/DashboardDemo) |
||||
|
* [Widget documentation](../UI/AspNetCore/Widgets.md) |
||||
|
* **RabbitMQ Event Bus Demo**: A solution consists of two applications communicating to each other via distributed events with RabbitMQ integration. |
||||
|
* [Source code](https://github.com/abpframework/abp-samples/tree/master/RabbitMqEventBus) |
||||
|
* [Distributed event bus document](../Distributed-Event-Bus.md) |
||||
|
* [RabbitMQ distributed event bus integration document](../Distributed-Event-Bus-RabbitMQ-Integration.md) |
||||
|
* **Authentication Customization**: A solution to show how to customize the authentication for ASP.NET Core MVC / Razor Pages applications. |
||||
|
* [Source code](https://github.com/abpframework/abp-samples/tree/master/aspnet-core/Authentication-Customization) |
||||
|
* Related "[How To](../How-To/Index.md)" documents: |
||||
|
* [Azure Active Directory Authentication](../How-To/Azure-Active-Directory-Authentication-MVC.md) |
||||
|
* [Customize the Login Page](../How-To/Customize-Login-Page-MVC.md) |
||||
|
* [Customize the SignIn Manager](../How-To/Customize-SignIn-Manager.md) |
||||
|
* **Empty ASP.NET Core Application**: The most basic ASP.NET Core application with the ABP Framework installed. |
||||
|
* [Source code](https://github.com/abpframework/abp-samples/tree/master/BasicAspNetCoreApplication) |
||||
|
* [Documentation](../Getting-Started-AspNetCore-Application.md) |
||||
|
* **Empty Console Application**: The most basic console application with the ABP Framework installed. |
||||
|
* [Source code](https://github.com/abpframework/abp-samples/tree/master/BasicConsoleApplication) |
||||
|
* [Documentation](../Getting-Started-Console-Application.md) |
||||
@ -0,0 +1,16 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Core; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.SignalR |
||||
|
{ |
||||
|
[DependsOn(typeof(CoreScriptContributor))] |
||||
|
public class SignalRBrowserScriptContributor : BundleContributor |
||||
|
{ |
||||
|
public override void ConfigureBundle(BundleConfigurationContext context) |
||||
|
{ |
||||
|
context.Files.AddIfNotContains("/libs/signalr/browser/signalr.js"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,27 @@ |
|||||
|
{ |
||||
|
"iisSettings": { |
||||
|
"windowsAuthentication": false, |
||||
|
"anonymousAuthentication": true, |
||||
|
"iisExpress": { |
||||
|
"applicationUrl": "http://localhost:53900/", |
||||
|
"sslPort": 44362 |
||||
|
} |
||||
|
}, |
||||
|
"profiles": { |
||||
|
"IIS Express": { |
||||
|
"commandName": "IISExpress", |
||||
|
"launchBrowser": true, |
||||
|
"environmentVariables": { |
||||
|
"ASPNETCORE_ENVIRONMENT": "Development" |
||||
|
} |
||||
|
}, |
||||
|
"Volo.Abp.SignalR": { |
||||
|
"commandName": "Project", |
||||
|
"launchBrowser": true, |
||||
|
"environmentVariables": { |
||||
|
"ASPNETCORE_ENVIRONMENT": "Development" |
||||
|
}, |
||||
|
"applicationUrl": "https://localhost:5001;http://localhost:5000" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk.Web"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netcoreapp3.1</TargetFramework> |
||||
|
<AssemblyName>Volo.Abp.AspNetCore.SignalR</AssemblyName> |
||||
|
<PackageId>Volo.Abp.AspNetCore.SignalR</PackageId> |
||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<IsPackable>true</IsPackable> |
||||
|
<OutputType>Library</OutputType> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.AspNetCore\Volo.Abp.AspNetCore.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,115 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Reflection; |
||||
|
using Microsoft.AspNetCore.Builder; |
||||
|
using Microsoft.AspNetCore.Http.Connections; |
||||
|
using Microsoft.AspNetCore.Routing; |
||||
|
using Microsoft.AspNetCore.SignalR; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.SignalR |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpAspNetCoreModule) |
||||
|
)] |
||||
|
public class AbpAspNetCoreSignalRModule : AbpModule |
||||
|
{ |
||||
|
private static readonly MethodInfo MapHubGenericMethodInfo = |
||||
|
typeof(AbpAspNetCoreSignalRModule) |
||||
|
.GetMethod("MapHub", BindingFlags.Static | BindingFlags.NonPublic); |
||||
|
|
||||
|
public override void PreConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
context.Services.AddConventionalRegistrar(new AbpSignalRConventionalRegistrar()); |
||||
|
|
||||
|
AutoAddHubTypes(context.Services); |
||||
|
} |
||||
|
|
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
context.Services.AddSignalR(); |
||||
|
|
||||
|
Configure<AbpEndpointRouterOptions>(options => |
||||
|
{ |
||||
|
options.EndpointConfigureActions.Add(endpointContext => |
||||
|
{ |
||||
|
var signalROptions = endpointContext |
||||
|
.ScopeServiceProvider |
||||
|
.GetRequiredService<IOptions<AbpSignalROptions>>() |
||||
|
.Value; |
||||
|
|
||||
|
foreach (var hubConfig in signalROptions.Hubs) |
||||
|
{ |
||||
|
MapHubType( |
||||
|
hubConfig.HubType, |
||||
|
endpointContext.Endpoints, |
||||
|
hubConfig.RoutePattern, |
||||
|
opts => |
||||
|
{ |
||||
|
foreach (var configureAction in hubConfig.ConfigureActions) |
||||
|
{ |
||||
|
configureAction(opts); |
||||
|
} |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void AutoAddHubTypes(IServiceCollection services) |
||||
|
{ |
||||
|
var hubTypes = new List<Type>(); |
||||
|
|
||||
|
services.OnRegistred(context => |
||||
|
{ |
||||
|
if (typeof(Hub).IsAssignableFrom(context.ImplementationType)) |
||||
|
{ |
||||
|
hubTypes.Add(context.ImplementationType); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
services.Configure<AbpSignalROptions>(options => |
||||
|
{ |
||||
|
foreach (var hubType in hubTypes) |
||||
|
{ |
||||
|
options.Hubs.Add(HubConfig.Create(hubType)); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void MapHubType( |
||||
|
Type hubType, |
||||
|
IEndpointRouteBuilder endpoints, |
||||
|
string pattern, |
||||
|
Action<HttpConnectionDispatcherOptions> configureOptions) |
||||
|
{ |
||||
|
MapHubGenericMethodInfo |
||||
|
.MakeGenericMethod(hubType) |
||||
|
.Invoke( |
||||
|
this, |
||||
|
new object[] |
||||
|
{ |
||||
|
endpoints, |
||||
|
pattern, |
||||
|
configureOptions |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
// ReSharper disable once UnusedMember.Local (used via reflection)
|
||||
|
private static void MapHub<THub>( |
||||
|
IEndpointRouteBuilder endpoints, |
||||
|
string pattern, |
||||
|
Action<HttpConnectionDispatcherOptions> configureOptions) |
||||
|
where THub : Hub |
||||
|
{ |
||||
|
endpoints.MapHub<THub>( |
||||
|
pattern, |
||||
|
configureOptions |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,135 @@ |
|||||
|
using System; |
||||
|
using Microsoft.AspNetCore.Authorization; |
||||
|
using Microsoft.AspNetCore.SignalR; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Localization; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.Extensions.Logging.Abstractions; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
using Volo.Abp.Timing; |
||||
|
using Volo.Abp.Users; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.SignalR |
||||
|
{ |
||||
|
public abstract class AbpHub : Hub |
||||
|
{ |
||||
|
public IServiceProvider ServiceProvider { get; set; } |
||||
|
protected readonly object ServiceProviderLock = new object(); |
||||
|
|
||||
|
protected TService LazyGetRequiredService<TService>(ref TService reference) |
||||
|
=> LazyGetRequiredService(typeof(TService), ref reference); |
||||
|
|
||||
|
protected TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference) |
||||
|
{ |
||||
|
if (reference == null) |
||||
|
{ |
||||
|
lock (ServiceProviderLock) |
||||
|
{ |
||||
|
if (reference == null) |
||||
|
{ |
||||
|
reference = (TRef)ServiceProvider.GetRequiredService(serviceType); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return reference; |
||||
|
} |
||||
|
|
||||
|
public ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); |
||||
|
private ILoggerFactory _loggerFactory; |
||||
|
|
||||
|
protected ILogger Logger => _lazyLogger.Value; |
||||
|
private Lazy<ILogger> _lazyLogger => new Lazy<ILogger>(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true); |
||||
|
|
||||
|
public ICurrentUser CurrentUser => LazyGetRequiredService(ref _currentUser); |
||||
|
private ICurrentUser _currentUser; |
||||
|
|
||||
|
public ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant); |
||||
|
private ICurrentTenant _currentTenant; |
||||
|
|
||||
|
public IAuthorizationService AuthorizationService => LazyGetRequiredService(ref _authorizationService); |
||||
|
private IAuthorizationService _authorizationService; |
||||
|
|
||||
|
public IClock Clock => LazyGetRequiredService(ref _clock); |
||||
|
private IClock _clock; |
||||
|
|
||||
|
public IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(ref _stringLocalizerFactory); |
||||
|
private IStringLocalizerFactory _stringLocalizerFactory; |
||||
|
|
||||
|
public IStringLocalizer L => _localizer ?? (_localizer = StringLocalizerFactory.Create(LocalizationResource)); |
||||
|
private IStringLocalizer _localizer; |
||||
|
|
||||
|
protected Type LocalizationResource |
||||
|
{ |
||||
|
get => _localizationResource; |
||||
|
set |
||||
|
{ |
||||
|
_localizationResource = value; |
||||
|
_localizer = null; |
||||
|
} |
||||
|
} |
||||
|
private Type _localizationResource = typeof(DefaultResource); |
||||
|
} |
||||
|
|
||||
|
public abstract class AbpHub<T> : Hub<T> |
||||
|
where T : class |
||||
|
{ |
||||
|
public IServiceProvider ServiceProvider { get; set; } |
||||
|
protected readonly object ServiceProviderLock = new object(); |
||||
|
|
||||
|
protected TService LazyGetRequiredService<TService>(ref TService reference) |
||||
|
=> LazyGetRequiredService(typeof(TService), ref reference); |
||||
|
|
||||
|
protected TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference) |
||||
|
{ |
||||
|
if (reference == null) |
||||
|
{ |
||||
|
lock (ServiceProviderLock) |
||||
|
{ |
||||
|
if (reference == null) |
||||
|
{ |
||||
|
reference = (TRef)ServiceProvider.GetRequiredService(serviceType); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return reference; |
||||
|
} |
||||
|
|
||||
|
public ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); |
||||
|
private ILoggerFactory _loggerFactory; |
||||
|
|
||||
|
protected ILogger Logger => _lazyLogger.Value; |
||||
|
private Lazy<ILogger> _lazyLogger => new Lazy<ILogger>(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true); |
||||
|
|
||||
|
public ICurrentUser CurrentUser => LazyGetRequiredService(ref _currentUser); |
||||
|
private ICurrentUser _currentUser; |
||||
|
|
||||
|
public ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant); |
||||
|
private ICurrentTenant _currentTenant; |
||||
|
|
||||
|
public IAuthorizationService AuthorizationService => LazyGetRequiredService(ref _authorizationService); |
||||
|
private IAuthorizationService _authorizationService; |
||||
|
|
||||
|
public IClock Clock => LazyGetRequiredService(ref _clock); |
||||
|
private IClock _clock; |
||||
|
|
||||
|
public IStringLocalizerFactory StringLocalizerFactory => LazyGetRequiredService(ref _stringLocalizerFactory); |
||||
|
private IStringLocalizerFactory _stringLocalizerFactory; |
||||
|
|
||||
|
public IStringLocalizer L => _localizer ?? (_localizer = StringLocalizerFactory.Create(LocalizationResource)); |
||||
|
private IStringLocalizer _localizer; |
||||
|
|
||||
|
protected Type LocalizationResource |
||||
|
{ |
||||
|
get => _localizationResource; |
||||
|
set |
||||
|
{ |
||||
|
_localizationResource = value; |
||||
|
_localizer = null; |
||||
|
} |
||||
|
} |
||||
|
private Type _localizationResource = typeof(DefaultResource); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
using System; |
||||
|
using Microsoft.AspNetCore.SignalR; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.SignalR |
||||
|
{ |
||||
|
public class AbpSignalRConventionalRegistrar : ConventionalRegistrarBase |
||||
|
{ |
||||
|
public override void AddType(IServiceCollection services, Type type) |
||||
|
{ |
||||
|
if (IsConventionalRegistrationDisabled(type)) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (!IsHub(type)) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var serviceTypes = ExposedServiceExplorer.GetExposedServices(type); |
||||
|
|
||||
|
TriggerServiceExposing(services, type, serviceTypes); |
||||
|
|
||||
|
foreach (var serviceType in serviceTypes) |
||||
|
{ |
||||
|
services.Add( |
||||
|
ServiceDescriptor.Describe( |
||||
|
serviceType, |
||||
|
type, |
||||
|
ServiceLifetime.Transient |
||||
|
) |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static bool IsHub(Type type) |
||||
|
{ |
||||
|
return typeof(Hub).IsAssignableFrom(type); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.SignalR |
||||
|
{ |
||||
|
public class AbpSignalROptions |
||||
|
{ |
||||
|
public List<HubConfig> Hubs { get; } |
||||
|
|
||||
|
public AbpSignalROptions() |
||||
|
{ |
||||
|
Hubs = new List<HubConfig>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
using Microsoft.AspNetCore.SignalR; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Users; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.SignalR |
||||
|
{ |
||||
|
public class AbpSignalRUserIdProvider : IUserIdProvider, ITransientDependency |
||||
|
{ |
||||
|
public ICurrentUser CurrentUser { get; } |
||||
|
|
||||
|
public AbpSignalRUserIdProvider(ICurrentUser currentUser) |
||||
|
{ |
||||
|
CurrentUser = currentUser; |
||||
|
} |
||||
|
|
||||
|
public virtual string GetUserId(HubConnectionContext connection) |
||||
|
{ |
||||
|
return CurrentUser.Id?.ToString(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using JetBrains.Annotations; |
||||
|
using Microsoft.AspNetCore.Http.Connections; |
||||
|
using Microsoft.AspNetCore.SignalR; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.SignalR |
||||
|
{ |
||||
|
public class HubConfig |
||||
|
{ |
||||
|
[NotNull] |
||||
|
public Type HubType { get; } |
||||
|
|
||||
|
[NotNull] |
||||
|
public string RoutePattern { get; set; } |
||||
|
|
||||
|
[NotNull] |
||||
|
public List<Action<HttpConnectionDispatcherOptions>> ConfigureActions { get; set; } |
||||
|
|
||||
|
public HubConfig( |
||||
|
[NotNull] Type hubType, |
||||
|
[NotNull] string routePattern) |
||||
|
{ |
||||
|
HubType = Check.NotNull(hubType, nameof(hubType)); |
||||
|
RoutePattern = Check.NotNullOrWhiteSpace(routePattern, nameof(routePattern)); |
||||
|
ConfigureActions = new List<Action<HttpConnectionDispatcherOptions>>(); |
||||
|
} |
||||
|
|
||||
|
public static HubConfig Create<THub>() |
||||
|
where THub : Hub |
||||
|
{ |
||||
|
return Create(typeof(THub)); |
||||
|
} |
||||
|
|
||||
|
public static HubConfig Create(Type hubType) |
||||
|
{ |
||||
|
return new HubConfig( |
||||
|
hubType, |
||||
|
HubRouteAttribute.GetRoutePattern(hubType) |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
using System; |
||||
|
using System.Reflection; |
||||
|
using Microsoft.AspNetCore.SignalR; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.SignalR |
||||
|
{ |
||||
|
public class HubRouteAttribute : Attribute |
||||
|
{ |
||||
|
public string RoutePattern { get; set; } |
||||
|
|
||||
|
public HubRouteAttribute(string routePattern) |
||||
|
{ |
||||
|
RoutePattern = routePattern; |
||||
|
} |
||||
|
|
||||
|
public static string GetRoutePattern<THub>() |
||||
|
where THub : Hub |
||||
|
{ |
||||
|
return GetRoutePattern(typeof(THub)); |
||||
|
} |
||||
|
|
||||
|
public static string GetRoutePattern(Type hubType) |
||||
|
{ |
||||
|
var routeAttribute = hubType.GetSingleAttributeOrNull<HubRouteAttribute>(); |
||||
|
if (routeAttribute != null) |
||||
|
{ |
||||
|
return routeAttribute.RoutePattern; |
||||
|
} |
||||
|
|
||||
|
return "/signalr-hubs/" + hubType.Name.RemovePostFix("Hub").ToKebabCase(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,47 @@ |
|||||
|
using System; |
||||
|
using System.Linq; |
||||
|
using Microsoft.AspNetCore.Routing; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
|
||||
|
namespace Microsoft.AspNetCore.Builder |
||||
|
{ |
||||
|
public static class AbpAspNetCoreApplicationBuilderExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Maps endpoints configured with the <see cref="AbpEndpointRouterOptions"/>.
|
||||
|
/// It internally uses the standard app.UseEndpoints(...) method.
|
||||
|
/// </summary>
|
||||
|
/// <param name="app">The application builder</param>
|
||||
|
/// <param name="additionalConfigurationAction">Additional (and optional) endpoint configuration</param>
|
||||
|
/// <returns></returns>
|
||||
|
public static IApplicationBuilder UseConfiguredEndpoints( |
||||
|
this IApplicationBuilder app, |
||||
|
Action<IEndpointRouteBuilder> additionalConfigurationAction = null) |
||||
|
{ |
||||
|
var options = app.ApplicationServices |
||||
|
.GetRequiredService<IOptions<AbpEndpointRouterOptions>>() |
||||
|
.Value; |
||||
|
|
||||
|
if (!options.EndpointConfigureActions.Any()) |
||||
|
{ |
||||
|
return app; |
||||
|
} |
||||
|
|
||||
|
return app.UseEndpoints(endpoints => |
||||
|
{ |
||||
|
using (var scope = app.ApplicationServices.CreateScope()) |
||||
|
{ |
||||
|
var context = new EndpointRouteBuilderContext(endpoints, scope.ServiceProvider); |
||||
|
|
||||
|
foreach (var configureAction in options.EndpointConfigureActions) |
||||
|
{ |
||||
|
configureAction(context); |
||||
|
} |
||||
|
|
||||
|
additionalConfigurationAction?.Invoke(endpoints); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Microsoft.AspNetCore.Routing |
||||
|
{ |
||||
|
public class AbpEndpointRouterOptions |
||||
|
{ |
||||
|
public List<Action<EndpointRouteBuilderContext>> EndpointConfigureActions { get; } |
||||
|
|
||||
|
public AbpEndpointRouterOptions() |
||||
|
{ |
||||
|
EndpointConfigureActions = new List<Action<EndpointRouteBuilderContext>>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Microsoft.AspNetCore.Routing |
||||
|
{ |
||||
|
public class EndpointRouteBuilderContext |
||||
|
{ |
||||
|
public IEndpointRouteBuilder Endpoints { get; } |
||||
|
public IServiceProvider ScopeServiceProvider { get; } |
||||
|
|
||||
|
public EndpointRouteBuilderContext( |
||||
|
IEndpointRouteBuilder endpoints, |
||||
|
IServiceProvider scopeServiceProvider) |
||||
|
{ |
||||
|
Endpoints = endpoints; |
||||
|
ScopeServiceProvider = scopeServiceProvider; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
{ |
||||
|
"culture": "es", |
||||
|
"texts": { |
||||
|
"DisplayName:Abp.Mailing.DefaultFromAddress": "Dirección de envío", |
||||
|
"DisplayName:Abp.Mailing.DefaultFromDisplayName": "Nombre de envío", |
||||
|
"DisplayName:Abp.Mailing.Smtp.Host": "Host", |
||||
|
"DisplayName:Abp.Mailing.Smtp.Port": "Puerto", |
||||
|
"DisplayName:Abp.Mailing.Smtp.UserName": "Nombre de usuario", |
||||
|
"DisplayName:Abp.Mailing.Smtp.Password": "Contraseña", |
||||
|
"DisplayName:Abp.Mailing.Smtp.Domain": "Dominio", |
||||
|
"DisplayName:Abp.Mailing.Smtp.EnableSsl": "Habilitar SSL", |
||||
|
"DisplayName:Abp.Mailing.Smtp.UseDefaultCredentials": "Usar las credenciales por defecto", |
||||
|
"Description:Abp.Mailing.DefaultFromAddress": "La dirección de envío por defecto", |
||||
|
"Description:Abp.Mailing.DefaultFromDisplayName": "El nombre de envío por defecto", |
||||
|
"Description:Abp.Mailing.Smtp.Host": "El nombre o dirección del host para transacciones SMTP.", |
||||
|
"Description:Abp.Mailing.Smtp.Port": "El puerto usado para transacciones SMTP.", |
||||
|
"Description:Abp.Mailing.Smtp.UserName": "Nombre de usuario asociado a las credenciales.", |
||||
|
"Description:Abp.Mailing.Smtp.Password": "La contraseña del ususario asociado a las credenciales.", |
||||
|
"Description:Abp.Mailing.Smtp.Domain": "El dominio o equipo que valida las credenciales.", |
||||
|
"Description:Abp.Mailing.Smtp.EnableSsl": "Si SmtpClient usa Secure Sockets Layer (SSL) para encriptar la conección.", |
||||
|
"Description:Abp.Mailing.Smtp.UseDefaultCredentials": "Si las credenciales por defecto se envían con los request." |
||||
|
} |
||||
|
} |
||||
@ -1,6 +1,6 @@ |
|||||
{ |
{ |
||||
"culture": "es", |
"culture": "es", |
||||
"texts": { |
"texts": { |
||||
"Menu:Administration": "Administración" |
"Menu:Administration": "Administración" |
||||
} |
} |
||||
} |
} |
||||
@ -0,0 +1,45 @@ |
|||||
|
{ |
||||
|
"culture": "es", |
||||
|
"texts": { |
||||
|
"UserName": "Nombre de usuario", |
||||
|
"EmailAddress": "Dirección de correo electrónico", |
||||
|
"UserNameOrEmailAddress": "Nombre de usuario o dirección de correo electrónico", |
||||
|
"Password": "Contraseña", |
||||
|
"RememberMe": "Recuérdame", |
||||
|
"UseAnotherServiceToLogin": "Usar otro servicio para iniciar sesión", |
||||
|
"UserLockedOutMessage": "La cuenta de usuario ha sido bloqueada debido a los intentos de inicio de sesión no válidos. Por favor, espere unos minutos y vuelve a intentarlo.", |
||||
|
"InvalidUserNameOrPassword": "El nombre de usuario o la contraseña no son válidos", |
||||
|
"LoginIsNotAllowed": "No está permitido el inicio de sesión! Usted tendrá que confirmar su correo electrónico o número de teléfono.", |
||||
|
"SelfRegistrationDisabledMessage": "El autoregistro de usuario está deshabilitado para esta aplicación. Póngase en contacto con el administrador de la aplicación para registrar un nuevo usuario.", |
||||
|
"LocalLoginDisabledMessage": "No está habilitado el login local para esta aplicación.", |
||||
|
"Login": "Iniciar sesión", |
||||
|
"Cancel": "Cancelar", |
||||
|
"Register": "Registrarse", |
||||
|
"AreYouANewUser": "¿Usted es un usuario nuevo?", |
||||
|
"AlreadyRegistered": "¿Está registrado en esta aplicación?", |
||||
|
"InvalidLoginRequest": "Solicitud de inicio de sesión no válido", |
||||
|
"ThereAreNoLoginSchemesConfiguredForThisClient": "No hay ningún esquema de inicio de sesión configurado para este cliente.", |
||||
|
"LogInUsingYourProviderAccount": "Inicia sesión con tu cuenta de {0} ", |
||||
|
"DisplayName:CurrentPassword": "Contraseña actual", |
||||
|
"DisplayName:NewPassword": "Nueva contraseña", |
||||
|
"DisplayName:NewPasswordConfirm": "Confirmar nueva contraseña", |
||||
|
"PasswordChangedMessage": "Su contraseña ha sido cambiada con éxito.", |
||||
|
"DisplayName:UserName": "Nombre de usuario", |
||||
|
"DisplayName:Email": "Correo electrónico", |
||||
|
"DisplayName:Name": "Nombre", |
||||
|
"DisplayName:Surname": "Apellido", |
||||
|
"DisplayName:Password": "Contraseña", |
||||
|
"DisplayName:EmailAddress": "Dirección de correo electrónico", |
||||
|
"DisplayName:PhoneNumber": "Número de teléfono", |
||||
|
"PersonalSettings": "Configuración Personal", |
||||
|
"PersonalSettingsSaved": "Ajustes personales guardados", |
||||
|
"PasswordChanged": "Cambiar la contraseña", |
||||
|
"NewPasswordConfirmFailed": "Por favor, confirme la nueva contraseña.", |
||||
|
"Manage": "Administrar", |
||||
|
"ManageYourProfile": "Gestionar su perfil", |
||||
|
"DisplayName:Abp.Account.IsSelfRegistrationEnabled": "Habilitar el registro de usuario", |
||||
|
"Description:Abp.Account.IsSelfRegistrationEnabled": "Si está habilitado los usuarios pueden crear una cuenta mediante el registro automático.", |
||||
|
"DisplayName:Abp.Account.EnableLocalLogin": "Habilitar cuenta local", |
||||
|
"Description:Abp.Account.EnableLocalLogin": "Indica que el servidor permite iniciar sessión con una cuenta local." |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,5 @@ |
|||||
|
module.exports = { |
||||
|
mappings: { |
||||
|
"@node_modules/@microsoft/signalr/dist/browser/*.*": "@libs/signalr/browser/" |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
{ |
||||
|
"version": "2.7.0", |
||||
|
"name": "@abp/signalr", |
||||
|
"publishConfig": { |
||||
|
"access": "public" |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"@abp/core": "^2.7.0", |
||||
|
"@microsoft/signalr": "^3.1.3" |
||||
|
}, |
||||
|
"gitHead": "0ea3895f3b0b489e3ea81fc88f8f0896b22b61bd" |
||||
|
} |
||||
Loading…
Reference in new issue