Main 작업을 수행합니다.
35 {
36 var builder = Host.CreateApplicationBuilder();
37 builder.Configuration.AddUserSecrets("codemaru-oauth-2ba4e1b2");
38
39 int serverPort = GetInt(builder.Configuration, "PortfolioServer:Port", 7080);
40 bool listenAnyIp = GetBool(builder.Configuration, "PortfolioServer:ListenAnyIp", true);
41 AuthOptions authOptions =
42 builder.Configuration.GetSection(AuthOptions.SectionName).Get<AuthOptions>() ?? new AuthOptions();
43 string usersDbPath = ResolvePath(
44 builder.Configuration[$"{AuthOptions.SectionName}:UsersDbPath"],
45 Path.Combine(AppContext.BaseDirectory, "App_Data", "codemaru.db"));
46
47 builder.Services.AddDreamineHybridWpf();
48 builder.Services.AddDreamineIdentityWpfHost();
49
50 var opts = PortfolioOptions.From(builder.Configuration);
51 builder.Services.AddSingleton(opts);
52 builder.Services.AddSingleton<IPortfolioTenantStore, JsonPortfolioTenantStore>();
53 builder.Services.AddSingleton<IProjectStore, JsonProjectStore>();
54 builder.Services.AddSingleton<IResumeStore, JsonResumeStore>();
55 builder.Services.AddSingleton<IContactStore, JsonContactStore>();
56 builder.Services.AddSingleton<IMediaService, LocalMediaService>();
57
58 builder.Services.AddSingleton<Views.MainWindow>();
59 builder.Services.AddHostedService<GhostAccountCleanupService>();
60
61 builder.Services.AddDreamineBlazorServer<AppShell>(options =>
62 {
63 options.Port = serverPort;
64 options.ListenAnyIp = listenAnyIp;
65 options.SharedServiceTypes.Add(typeof(PortfolioOptions));
66 options.SharedServiceTypes.Add(typeof(IPortfolioTenantStore));
67 options.SharedServiceTypes.Add(typeof(IProjectStore));
68 options.SharedServiceTypes.Add(typeof(IResumeStore));
69 options.SharedServiceTypes.Add(typeof(IContactStore));
70 options.SharedServiceTypes.Add(typeof(IMediaService));
71 options.AddPhysicalStaticFiles(opts.ResolvedDataPath, "/portfolio-data");
72
73 options.ConfigureServices = services =>
74 {
75 services.AddServerSideBlazor().AddHubOptions(o =>
76 {
77 o.MaximumReceiveMessageSize = null;
78 o.ClientTimeoutInterval = TimeSpan.FromMinutes(10);
79 o.HandshakeTimeout = TimeSpan.FromMinutes(2);
80 o.KeepAliveInterval = TimeSpan.FromSeconds(10);
81 });
82
83 services.AddAntiforgery(o =>
84 {
85 o.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Lax;
86 o.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.SameAsRequest;
87 });
88
89 services.Configure<CircuitOptions>(o =>
90 {
91 o.DisconnectedCircuitMaxRetained = 100;
92 o.DisconnectedCircuitRetentionPeriod = TimeSpan.FromMinutes(3);
93 o.JSInteropDefaultCallTimeout = TimeSpan.FromMinutes(1);
94 o.MaxBufferedUnacknowledgedRenderBatches = 10;
95 });
96
97 services.AddScoped<PortfolioUserContext>();
98 };
99
100 options.AddDreamineIdentity(authOptions, usersDbPath);
101 });
102
103 builder.Build().RunDreamineWpfApp<App>();
104 }