4.abpのasp.Netcoreモジュールプロファイリング
10749 ワード
関連モジュール AbpAspNetCoreModule AbpAspNetCoreMvcModule AbpAspNetCoreMvcContractsModule
abpはこの3つのモジュールを介してaspをロード構成する.net core.,最も主要なのはAppAspNetCoreMvcModuleモジュールクラスであり、abpがaspnet coreに基づいて独自のコントローラとAppServicesを構築する方法は、このクラスにあります.AppAspNetCoreMvcModule AppAspNetCoreMvcConventionalRegisterクラスをConventionalRegistrarListリストに追加します.このクラスは主に依存を注入し、サービスライフサイクルを取得するために使用されます. A s p N t e C o r e D e scriptionModelProvider abpはどのようにしてaspnet coreが独自のAPIを作成したのでしょうか?AspNetCoreDescriptionModelProviderというクラスがあります.このクラスはaspnet coreを提供する記述モデルで、ソースコードは以下の通りです. AbpHttpModule Abp jqueryエージェントスクリプトジェネレータを作成し、主にapiを生産してフロントエンドへのアクセスを提供する
abpはこの3つのモジュールを介してaspをロード構成する.net core.,最も主要なのはAppAspNetCoreMvcModuleモジュールクラスであり、abpがaspnet coreに基づいて独自のコントローラとAppServicesを構築する方法は、このクラスにあります.
public override void PreConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddConventionalRegistrar(new AbpAspNetCoreMvcConventionalRegistrar());
}
次にポイントですが、コンフィギュレーション・サービス・メソッドではビューとコントローラを構成します.もちろんaspベースです.net core mvc.まずRazorを構成する: context.Services.Insert(0,
ServiceDescriptor.Singleton>(
new ConfigureOptions(options =>
{
options.FileProviders.Add(
new RazorViewEngineVirtualFileProvider(
context.Services.GetSingletonInstance>()
)
);
}
)
)
);
Api記述子を構成する: Configure(options =>
{
options.IgnoredInterfaces.AddIfNotContains(typeof(IAsyncActionFilter));
options.IgnoredInterfaces.AddIfNotContains(typeof(IFilterMetadata));
options.IgnoredInterfaces.AddIfNotContains(typeof(IActionFilter));
});
aspnetcore mvcのフィルタインタフェースが見え、Api記述モデルオプションクラスに追加しました.以下、注入MVC: var mvcCoreBuilder = context.Services.AddMvcCore();
var mvcBuilder = context.Services.AddMvc()
.AddDataAnnotationsLocalization(options =>
{
options.DataAnnotationLocalizerProvider = (type, factory) =>
{
var resourceType = abpMvcDataAnnotationsLocalizationOptions.AssemblyResources.GetOrDefault(type.Assembly);
return factory.Create(resourceType ?? type);
};
})
.AddViewLocalization();
DIを使用してコントローラを作成し、aspnet coreのデフォルトのコントローラアクティベータServiceBasedControllerActivatvatorクラスを使用する: //Use DI to create controllers
context.Services.Replace(ServiceDescriptor.Transient());
abpは、aspnetcore mvcのControllerFeatureProviderに基づいて独自のコントローラを構築し、判断コントローラを検索する、という約束されたコントローラプロパティプロバイダクラスを提供する. //Add feature providers
var partManager = context.Services.GetSingletonInstance();
var application = context.Services.GetSingletonInstance();
partManager.FeatureProviders.Add(new AbpConventionalControllerFeatureProvider(application));
このクラスのソースコード: public class AbpConventionalControllerFeatureProvider : ControllerFeatureProvider
{
private readonly IAbpApplication _application;
public AbpConventionalControllerFeatureProvider(IAbpApplication application)
{
_application = application;
}
protected override bool IsController(TypeInfo typeInfo)
{
//TODO: Move this to a lazy loaded field for efficiency.
if (_application.ServiceProvider == null)
{
return false;
}
var configuration = _application.ServiceProvider
.GetRequiredService>().Value
.ConventionalControllers
.ConventionalControllerSettings
.GetSettingOrNull(typeInfo.AsType());
return configuration != null;
}
}
以上より、abpはaspnetcore mvcに基づいてabpのmvcモジュール、特にControllerの作成を構成する.AppAspNetCoreMvcOptionsのサービスを取得して規約のコントローラを検索することがコードからわかります.コントローラかどうかを返します.AbpAspNetCoreMvcOptionsクラスはAbp対aspnet core mvcのパッケージであり、ソースコードは以下の通りである: public class AbpAspNetCoreMvcOptions
{
public ConventionalControllerOptions ConventionalControllers { get; }
public AbpAspNetCoreMvcOptions()
{
ConventionalControllers = new ConventionalControllerOptions();
}
}
//
public class ConventionalControllerOptions
{
public ConventionalControllerSettingList ConventionalControllerSettings { get; }
public List FormBodyBindingIgnoredTypes { get; }
public ConventionalControllerOptions()
{
ConventionalControllerSettings = new ConventionalControllerSettingList();
FormBodyBindingIgnoredTypes = new List
{
typeof(IFormFile)
};
}
public ConventionalControllerOptions Create(Assembly assembly, [CanBeNull] Action optionsAction = null)
{
var setting = new ConventionalControllerSetting(assembly, ModuleApiDescriptionModel.DefaultRootPath); // DefaultRootPath = app,abp app 。
optionsAction?.Invoke(setting);
setting.Initialize();
ConventionalControllerSettings.Add(setting);
return this;
}
}
AbpAspNetCoreMvcOptionsは実際にはConventionalControllerOptionsによって契約の構成を完了し、カスタムルーティングおよび動的APIを実現する. public class AspNetCoreApiDescriptionModelProvider : IApiDescriptionModelProvider, ITransientDependency
{
public ILogger Logger { get; set; }
private readonly IApiDescriptionGroupCollectionProvider _descriptionProvider;
private readonly AbpAspNetCoreMvcOptions _options;
private readonly ApiDescriptionModelOptions _modelOptions;
public AspNetCoreApiDescriptionModelProvider(
IApiDescriptionGroupCollectionProvider descriptionProvider,
IOptions options,
IOptions modelOptions)
{
_descriptionProvider = descriptionProvider;
_options = options.Value;
_modelOptions = modelOptions.Value;
Logger = NullLogger.Instance;
}
public ApplicationApiDescriptionModel CreateApiModel()
{
//TODO: Can cache the model?
var model = ApplicationApiDescriptionModel.Create();
foreach (var descriptionGroupItem in _descriptionProvider.ApiDescriptionGroups.Items)
{
foreach (var apiDescription in descriptionGroupItem.Items)
{
if (!apiDescription.ActionDescriptor.IsControllerAction())
{
continue;
}
AddApiDescriptionToModel(apiDescription, model);
}
}
return model;
}
private void AddApiDescriptionToModel(ApiDescription apiDescription, ApplicationApiDescriptionModel model)
{
var controllerType = apiDescription.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.AsType();
var setting = FindSetting(controllerType);
var moduleModel = model.GetOrAddModule(GetRootPath(controllerType, setting));
var controllerModel = moduleModel.GetOrAddController(controllerType.FullName, CalculateControllerName(controllerType, setting), controllerType, _modelOptions.IgnoredInterfaces);
var method = apiDescription.ActionDescriptor.GetMethodInfo();
var uniqueMethodName = GetUniqueActionName(method);
if (controllerModel.Actions.ContainsKey(uniqueMethodName))
{
Logger.LogWarning($"Controller '{controllerModel.ControllerName}' contains more than one action with name '{uniqueMethodName}' for module '{moduleModel.RootPath}'. Ignored: " + method);
return;
}
Logger.LogDebug($"ActionApiDescriptionModel.Create: {controllerModel.ControllerName}.{uniqueMethodName}");
var actionModel = controllerModel.AddAction(uniqueMethodName, ActionApiDescriptionModel.Create(
uniqueMethodName,
method,
apiDescription.RelativePath,
apiDescription.HttpMethod,
GetSupportedVersions(controllerType, method, setting)
));
AddParameterDescriptionsToModel(actionModel, method, apiDescription);
}
private static string CalculateControllerName(Type controllerType, ConventionalControllerSetting setting)
{
var controllerName = controllerType.Name.RemovePostFix("Controller").RemovePostFix(ApplicationService.CommonPostfixes);
if (setting?.UrlControllerNameNormalizer != null)
{
controllerName = setting.UrlControllerNameNormalizer(new UrlControllerNameNormalizerContext(setting.RootPath, controllerName));
}
return controllerName;
}
}
このクラスはActionからControllerまでの記述を提供し、abp独自のapiを構築しました.呼び出しには2つの場所があります.1つはAppApiDefinitionControllerで、1つはProxyScriptManagerで、前者はAppを定義するapiコントローラ定義の場所で、後者はエージェントスクリプトを生成する場所で、abpのサンプルプロジェクトBookStoreではインタフェースApp/ServiceProxyScriptを呼び出してjsファイルを生成します.このjsファイルの中にはapiのurlアドレスがあり、フロントエンドはこのapiアドレスにアクセスしてappserviceなどのバックエンドメソッドにアクセスします.ソースコードは以下の通り: [Area("Abp")]
[Route("Abp/ServiceProxyScript")]
[DisableAuditing]
public class AbpServiceProxyScriptController : AbpController
{
private readonly IProxyScriptManager _proxyScriptManager;
public AbpServiceProxyScriptController(IProxyScriptManager proxyScriptManager)
{
_proxyScriptManager = proxyScriptManager;
}
[HttpGet]
[Produces("text/javascript", "text/plain")]
public string GetAll(ServiceProxyGenerationModel model)
{
model.Normalize();
return _proxyScriptManager.GetScript(model.CreateOptions());
}
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure(options =>
{
options.Generators[JQueryProxyScriptGenerator.Name] = typeof(JQueryProxyScriptGenerator);
});
}