forked from Lombiq/Orchard-Training-Demo-Module
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStartup.cs
More file actions
184 lines (158 loc) · 8.28 KB
/
Startup.cs
File metadata and controls
184 lines (158 loc) · 8.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
* A Startup class (there can be multiple ones in a module under different namespaces) will be called by the framework.
* It's the same as the ASP.NET Startup class (https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup). In
* there you can e.g. register injected services and change the request pipeline.
*/
using Fluid;
using Lombiq.TrainingDemo.Activities;
using Lombiq.TrainingDemo.Drivers;
using Lombiq.TrainingDemo.Events;
using Lombiq.TrainingDemo.Fields;
using Lombiq.TrainingDemo.Filters;
using Lombiq.TrainingDemo.Handlers;
using Lombiq.TrainingDemo.Indexes;
using Lombiq.TrainingDemo.Indexing;
using Lombiq.TrainingDemo.Liquid;
using Lombiq.TrainingDemo.Middlewares;
using Lombiq.TrainingDemo.Migrations;
using Lombiq.TrainingDemo.Models;
using Lombiq.TrainingDemo.Navigation;
using Lombiq.TrainingDemo.Permissions;
using Lombiq.TrainingDemo.Services;
using Lombiq.TrainingDemo.Settings;
using Lombiq.TrainingDemo.ViewModels;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OrchardCore.BackgroundTasks;
using OrchardCore.ContentManagement;
using OrchardCore.ContentManagement.Display.ContentDisplay;
using OrchardCore.ContentTypes.Editors;
using OrchardCore.Data.Migration;
using OrchardCore.DisplayManagement;
using OrchardCore.DisplayManagement.Descriptors;
using OrchardCore.DisplayManagement.Handlers;
using OrchardCore.Environment.Shell;
using OrchardCore.Environment.Shell.Configuration;
using OrchardCore.Indexing;
using OrchardCore.Liquid;
using OrchardCore.Modules;
using OrchardCore.Navigation;
using OrchardCore.ResourceManagement;
using OrchardCore.Security.Permissions;
using OrchardCore.Settings;
using OrchardCore.Users.Events;
using OrchardCore.Workflows.Helpers;
using System;
using System.IO;
using YesSql.Indexes;
namespace Lombiq.TrainingDemo;
// While the startup class doesn't need to derive from StartupBase and can just use conventionally named methods it's a
// bit less of a magic this way, and code analysis won't tell us to make it static.
public class Startup : StartupBase
{
private readonly IShellConfiguration _shellConfiguration;
public Startup(IShellConfiguration shellConfiguration) => _shellConfiguration = shellConfiguration;
public override void ConfigureServices(IServiceCollection services)
{
// NEXT STATION: Views/PersonPart.Edit.cshtml
// Book
services.AddScoped<IDisplayDriver<Book>, BookDisplayDriver>();
services.AddScoped<IDisplayManager<Book>, DisplayManager<Book>>();
services.AddDataMigration<BookMigrations>();
services.AddSingleton<IIndexProvider, BookIndexProvider>();
// Person Part
services.AddContentPart<PersonPart>()
.UseDisplayDriver<PersonPartDisplayDriver>()
.AddHandler<PersonPartHandler>();
services.AddDataMigration<PersonMigrations>();
services.AddSingleton<IIndexProvider, PersonPartIndexProvider>();
// Color Field
services.AddContentField<ColorField>()
.UseDisplayDriver<ColorFieldDisplayDriver>();
services.AddScoped<IContentPartFieldDefinitionDisplayDriver, ColorFieldSettingsDriver>();
services.AddScoped<IContentFieldIndexHandler, ColorFieldIndexHandler>();
// Resources
services.AddTransient<IConfigureOptions<ResourceManagementOptions>, ResourceManagementOptionsConfiguration>();
// Permissions
services.AddScoped<IPermissionProvider, PersonPermissions>();
// Admin Menu
services.AddScoped<INavigationProvider, PersonsAdminMenu>();
// Main Menu
services.AddScoped<INavigationProvider, TrainingDemoNavigationProvider>();
// Demo Settings
services.Configure<DemoSettings>(_shellConfiguration.GetSection("Lombiq_TrainingDemo"));
services.AddTransient<IConfigureOptions<DemoSettings>, DemoSettingsConfiguration>();
services.AddScoped<IDisplayDriver<ISite>, DemoSettingsDisplayDriver>();
services.AddScoped<IPermissionProvider, DemoSettingsPermissions>();
services.AddScoped<INavigationProvider, DemoSettingsAdminMenu>();
// Filters
services.Configure<MvcOptions>((options) =>
{
options.Filters.Add(typeof(ShapeInjectionFilter));
options.Filters.Add(typeof(ResourceInjectionFilter));
options.Filters.Add(typeof(ResourceFromShapeInjectingFilter));
});
// Shape table provider
services.AddScoped<IShapeTableProvider, ShapeHidingShapeTableProvider>();
// File System
services.AddSingleton<ICustomFileStore>(serviceProvider =>
{
// So our goal here is to have a custom folder in the tenant's own folder. The Media folder is also there
// but we won't use that. To get tenant-specific data we need to use the ShellOptions and ShellSettings
// objects.
var shellOptions = serviceProvider.GetRequiredService<IOptions<ShellOptions>>().Value;
var shellSettings = serviceProvider.GetRequiredService<ShellSettings>();
// Necessary for the comment.
#pragma warning disable SA1114 // Parameter list should follow declaration
var tenantFolderPath = PathExtensions.Combine(
// This is the absolute path of the "App_Data" folder.
shellOptions.ShellsApplicationDataPath,
// This is the folder which contains the tenants which is Sites by default.
shellOptions.ShellsContainerName,
// This is the tenant name. We want our custom folder inside this folder.
shellSettings.Name);
#pragma warning restore SA1114 // Parameter list should follow declaration
// And finally our full base path.
var customFolderPath = PathExtensions.Combine(tenantFolderPath, "CustomFiles");
// Now register our CustomFileStore instance with the path given.
return new CustomFileStore(customFolderPath);
// NEXT STATION: Controllers/FileManagementController and find the CreateFileInCustomFolder method.
});
// Caching
services.AddScoped<IDateTimeCachingService, DateTimeCachingService>();
// Background tasks. Note that these have to be singletons.
services.AddSingleton<IBackgroundTask, DemoBackgroundTask>();
// Event handlers
services.AddScoped<ILoginFormEvent, LoginGreeting>();
// Workflows
services.AddActivity<ManagePersonsPermissionCheckerTask, ManagePersonsPermissionCheckerTaskDisplayDriver>();
// Liquid
// To be able to access the properties inside these view models in display shapes rendered by the Liquid markup
// engine you need to register them. To learn more about Liquid in Orchard Core see this documentation:
// https://docs.orchardcore.net/en/latest/docs/reference/modules/Liquid/
services.Configure<TemplateOptions>(options =>
{
options.MemberAccessStrategy.Register<PersonPartViewModel>();
options.MemberAccessStrategy.Register<ColorField>();
options.MemberAccessStrategy.Register<DisplayColorFieldViewModel>();
})
// You can create custom liquid filters with the following. You can check out Liquid/ShortDateFilter.cs and
// come back here.
.AddLiquidFilter<ShortDateFilter>("short_date");
}
}
// A second Startup class, corresponding to our second feature (see Manifest.cs). Note how the Feature attribute tells
// Orchard to only activate the class if the feature is enabled. This way, you can register services corresponding to a
// feature only when necessary. Note that controllers aren't registered but activated automatically so you have to
// decorate them with the attribute too.
[Feature("Lombiq.TrainingDemo.Middlewares")]
public class MiddlewaresStartup : StartupBase
{
public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) =>
// You can put service configuration here as you would do it in other ASP.NET Core applications. If you don't
// need it you can skip overriding it. However, here we need it for our middleware.
app.UseMiddleware<RequestLoggingMiddleware>();
}