The OnTopic.Editor.AspNetCore project provides a web-based interface for the OnTopic Library. The editor is distributed as a Razor Class Library via NuGet so it can easily be added to a website that implements the OnTopic.AspNetCore.Mvc library.
Installation can be performed by providing a <PackageReference /> to the OnTopic.Editor.AspNetCore.All NuGet metapackage.
<Project Sdk="Microsoft.NET.Sdk.Web">
…
<ItemGroup>
<PackageReference Include="OnTopic.Editor.AspNetCore.All" Version="5.0.0" />
</ItemGroup>
</Project>There are a lot of moving parts to the editor, and it requires the configuration of services, routes, and service dependencies. This process is aided by a set of extension methods, which are recommended.
The editor necessitates a custom model binder—AttributeBindingModelBinderProvider—in order to work properly. This can be manually configured via AddMvcOptions(), or can be added using the AddTopicEditor() extension method:
public class Startup {
…
public void ConfigureServices(IServiceCollection services) {
services.AddControllersWithViews()
.AddTopicSupport()
.AddTopicEditor();
}
}The editor lives in an area called Editor and a controller called EditorController. A custom route can be conigured using the MapTopicEditorRoute() extension method to setup the /OnTopic route (e.g., /OnTopic/Edit/Root/Web):
public class Startup {
…
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
app.UseEndpoints(endpoints => {
endpoints.MapTopicEditorRoute();
});
}
}The editor is implemented through a set of ASP.NET Core View Components, some of which have external dependencies on a ITopicRepository. These should be configured via dependency injection. If you're using a dependency injection container, those dependencies should be the same as those required for the OnTopic Library. If you are manually configuring your dependencies, however, then the following provides a bare-bones example:
public class ControllerActivator : IControllerActivator {
…
public object Create(ControllerContext context) {
var type = context.ActionDescriptor.ControllerTypeInfo.AsType();
if (type == typeof(EditorController)) {
return new EditorController(_topicRepository, _topicMappingService);
}
}
}Note: This assumes a
_topicRepositoryand_topicMappingServicehave already been configured; see theOnTopic.AspNetCore.Mvcdocumentation for details.
The StandardEditorComposer class acts as a clearing house for accepting common dependencies and then composing the appropriate dependency graph for the view components:
public class ViewComponentActivator : IViewComponentActivator {
…
public object Create(ViewComponentContext context) {
var standardEditorComposer = new StandardEditorComposer(_topicRepository, _webHostEnvironment);
var type = context.ViewComponentDescriptor.TypeInfo.AsType();
if (standardEditorComposer.IsEditorComponent(type)) {
return standardEditorComposer.ActivateEditorComponent(type, _topicRepository);
}
}
} Note: For a full example, see the
SampleActivatorin theOnTopic.Editor.AspNetCore.Hostproject.