WeddingPlatform.Web 1.0.0.0
지도, 갤러리, 방명록, 계좌 안내와 배경음악을 링크 하나에 담는 무료 모바일 청첩장 서비스입니다.
로딩중...
검색중...
일치하는것 없음
WeddingPlatform.Program 클래스 참조

더 자세히 ...

정적 Public 멤버 함수

static void Main ()

정적 Private 멤버 함수

static void Run ()
static bool IsTcpPortAvailable (int port, bool listenAnyIp)
static int GetFreeLoopbackPort ()
static void WriteStartupFailureLog (Exception ex)
static int GetInt (IConfiguration cfg, string key, int fallback)
static bool GetBool (IConfiguration cfg, string key, bool fallback)
static string ResolvePath (string? configuredPath, string fallback)

상세한 설명

Program 기능과 관련 상태를 캡슐화합니다.

Program.cs 파일의 26 번째 라인에서 정의되었습니다.

멤버 함수 문서화

◆ GetBool()

bool WeddingPlatform.Program.GetBool ( IConfiguration cfg,
string key,
bool fallback )
inlinestaticprivate

Bool 값을 가져옵니다.

매개변수
cfgcfg에 사용할 IConfiguration 값입니다.
keykey에 사용할 string 값입니다.
fallbackfallback에 사용할 bool 값입니다.
반환값
Get Bool 조건이 충족되면 true이고, 그렇지 않으면 false입니다.

Program.cs 파일의 368 번째 라인에서 정의되었습니다.

368 =>
369 bool.TryParse(cfg[key], out bool v) ? v : fallback;

다음에 의해서 참조됨 : Run().

이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ GetFreeLoopbackPort()

int WeddingPlatform.Program.GetFreeLoopbackPort ( )
inlinestaticprivate

Free Loopback Port 값을 가져옵니다.

반환값
Get Free Loopback Port 작업에서 생성한 int 결과입니다.

Program.cs 파일의 236 번째 라인에서 정의되었습니다.

237 {
238 var listener = new TcpListener(IPAddress.Loopback, 0);
239 listener.Start();
240 try
241 {
242 return ((IPEndPoint)listener.LocalEndpoint).Port;
243 }
244 finally
245 {
246 listener.Stop();
247 }
248 }

다음에 의해서 참조됨 : Run().

이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ GetInt()

int WeddingPlatform.Program.GetInt ( IConfiguration cfg,
string key,
int fallback )
inlinestaticprivate

Int 값을 가져옵니다.

매개변수
cfgcfg에 사용할 IConfiguration 값입니다.
keykey에 사용할 string 값입니다.
fallbackfallback에 사용할 int 값입니다.
반환값
Get Int 작업에서 생성한 int 결과입니다.

Program.cs 파일의 325 번째 라인에서 정의되었습니다.

325 =>
326 int.TryParse(cfg[key], out int v) ? v : fallback;

다음에 의해서 참조됨 : Run().

이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ IsTcpPortAvailable()

bool WeddingPlatform.Program.IsTcpPortAvailable ( int port,
bool listenAnyIp )
inlinestaticprivate

Is Tcp Port Available 조건을 확인합니다.

매개변수
portport에 사용할 int 값입니다.
listenAnyIplisten Any Ip에 사용할 bool 값입니다.
반환값
Is Tcp Port Available 조건이 충족되면 true이고, 그렇지 않으면 false입니다.

Program.cs 파일의 199 번째 라인에서 정의되었습니다.

200 {
201 if (port <= 0) return false;
202
203 TcpListener? listener = null;
204 try
205 {
206 listener = new TcpListener(listenAnyIp ? IPAddress.Any : IPAddress.Loopback, port);
207 listener.Start();
208 return true;
209 }
210 catch (SocketException)
211 {
212 return false;
213 }
214 finally
215 {
216 listener?.Stop();
217 }
218 }

다음에 의해서 참조됨 : Run().

이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ Main()

void WeddingPlatform.Program.Main ( )
inlinestatic

Main 작업을 수행합니다.

Program.cs 파일의 37 번째 라인에서 정의되었습니다.

38 {
39 try
40 {
41 Run();
42 }
43 catch (Exception ex)
44 {
45 WriteStartupFailureLog(ex);
46 System.Windows.MessageBox.Show(
47 $"Wedding Platform 실행 중 오류가 발생했습니다.\n\n{ex.Message}\n\n자세한 내용은 로그를 확인하세요.",
48 "Wedding Platform",
49 System.Windows.MessageBoxButton.OK,
50 System.Windows.MessageBoxImage.Error);
51 }
52 }

다음을 참조함 : Run(), WriteStartupFailureLog().

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ ResolvePath()

string WeddingPlatform.Program.ResolvePath ( string? configuredPath,
string fallback )
inlinestaticprivate

Resolve Path 작업을 수행합니다.

매개변수
configuredPathconfigured Path에 사용할 string? 값입니다.
fallbackfallback에 사용할 string 값입니다.
반환값
Resolve Path 작업에서 생성한 string 결과입니다.

Program.cs 파일의 403 번째 라인에서 정의되었습니다.

404 {
405 if (string.IsNullOrWhiteSpace(configuredPath))
406 {
407 return fallback;
408 }
409
410 return Path.IsPathRooted(configuredPath)
411 ? configuredPath
412 : Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, configuredPath));
413 }

다음에 의해서 참조됨 : Run().

이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ Run()

void WeddingPlatform.Program.Run ( )
inlinestaticprivate

Run 작업을 수행합니다.

Program.cs 파일의 62 번째 라인에서 정의되었습니다.

63 {
64 HostApplicationBuilder builder = Host.CreateApplicationBuilder();
65 builder.Configuration.AddUserSecrets("codemaru-oauth-2ba4e1b2");
66
67 int serverPort = GetInt(builder.Configuration, "WeddingServer:Port", 5050);
68 bool listenAnyIp = GetBool(builder.Configuration, "WeddingServer:ListenAnyIp", true);
69 bool useEmbeddedWebView = GetBool(builder.Configuration, "WeddingShell:UseEmbeddedWebView", true);
70 if (!IsTcpPortAvailable(serverPort, listenAnyIp))
71 {
72 serverPort = GetFreeLoopbackPort();
73 listenAnyIp = false;
74 }
75
76 AuthOptions authOptions =
77 builder.Configuration.GetSection(AuthOptions.SectionName).Get<AuthOptions>() ?? new AuthOptions();
78 string usersDbPath = ResolvePath(
79 builder.Configuration[$"{AuthOptions.SectionName}:UsersDbPath"],
80 Path.Combine(AppContext.BaseDirectory, "App_Data", "codemaru.db"));
81
82 builder.Services.AddDreamineHybridWpf();
83 builder.Services.AddDreamineIdentityWpfHost();
84
85 // ── Wedding 서비스 ─────────────────────────────────────────
86 var weddingOpts = WeddingOptions.From(builder.Configuration);
87 builder.Services.AddSingleton(weddingOpts);
88 builder.Services.AddSingleton<ITenantStore, JsonTenantStore>();
89 builder.Services.AddSingleton<IGuestbookStorage, CsvGuestbookStorage>();
90 builder.Services.AddSingleton<IGlobalSettingsStore, JsonGlobalSettingsStore>();
91 builder.Services.AddSingleton<IMediaQuotaPolicyResolver, MediaQuotaPolicyResolver>();
92 builder.Services.AddSingleton<IImageOptimizationService, SystemDrawingImageOptimizationService>();
93 builder.Services.AddSingleton<IMediaMigrationService, JsonMediaMigrationService>();
94 builder.Services.AddSingleton<IMediaUsageQueryService, FileSystemMediaUsageQueryService>();
95 builder.Services.AddSingleton<ISuperAdminSessionTokenService, SuperAdminSessionTokenService>();
96 builder.Services.AddSingleton<IPhotoService, LocalPhotoService>();
97
98 builder.Services.AddSingleton<Views.MainWindow>();
99 builder.Services.AddHostedService<GhostAccountCleanupService>();
100
101 builder.Services.AddDreamineBlazorServer<AppShell>(options =>
102 {
103 options.Port = serverPort;
104 options.ListenAnyIp = listenAnyIp;
105 options.UseEmbeddedWebView = useEmbeddedWebView;
106 // Wedding 서비스 Blazor 호스트에 공유 (ViewModel은 AutoRegisterViewModels로 자동 등록)
107 options.SharedServiceTypes.Add(typeof(WeddingOptions));
108 options.SharedServiceTypes.Add(typeof(ITenantStore));
109 options.SharedServiceTypes.Add(typeof(IGuestbookStorage));
110 options.SharedServiceTypes.Add(typeof(IGlobalSettingsStore));
111 options.SharedServiceTypes.Add(typeof(IMediaQuotaPolicyResolver));
112 options.SharedServiceTypes.Add(typeof(IImageOptimizationService));
113 options.SharedServiceTypes.Add(typeof(IMediaMigrationService));
114 options.SharedServiceTypes.Add(typeof(IMediaUsageQueryService));
115 options.SharedServiceTypes.Add(typeof(ISuperAdminSessionTokenService));
116 options.SharedServiceTypes.Add(typeof(IPhotoService));
117 // 업로드된 사진을 /wedding-data/ URL로 제공
118 options.AddPhysicalStaticFiles(weddingOpts.ResolvedDataPath, "/wedding-data");
119
120 // InputFile(동영상 등 대용량 업로드)은 SignalR 회선을 통해 청크 단위로 전송되는데,
121 // 기본 SignalR 메시지 크기 제한(32KB)과 짧은 타임아웃 때문에 큰 파일은 매우 느리거나
122 // 응답 없이 멈춘 것처럼 보입니다. 업로드 용량 검증은 LocalPhotoService에서 별도로
123 // 하고 있으므로 전송 한도 자체는 풀어줍니다.
124 options.ConfigureServices = services =>
125 {
126 services.AddServerSideBlazor()
127 .AddHubOptions(o =>
128 {
129 o.MaximumReceiveMessageSize = null; // 무제한 (용량 검증은 LocalPhotoService에서 수행)
130 o.ClientTimeoutInterval = TimeSpan.FromMinutes(10);
131 o.HandshakeTimeout = TimeSpan.FromMinutes(2);
132 o.KeepAliveInterval = TimeSpan.FromSeconds(10);
133 o.EnableDetailedErrors = false;
134 });
135
136 // 삼성 인터넷 등 일부 브라우저가 SameSite 쿠키 정책에 엄격한 경우
137 // Blazor 회로 토큰(antiforgery 쿠키)이 차단될 수 있습니다.
138 // Lax + SameAsRequest 설정으로 호환성을 높입니다.
139 services.AddAntiforgery(o =>
140 {
141 o.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Lax;
142 o.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.SameAsRequest;
143 });
144
145 // CircuitOptions: 회선 연결 실패 후 유지 시간 증가 (재접속 시 기존 상태 복원)
146 services.Configure<CircuitOptions>(o =>
147 {
148 o.DisconnectedCircuitMaxRetained = 100;
149 o.DisconnectedCircuitRetentionPeriod = TimeSpan.FromMinutes(3);
150 o.JSInteropDefaultCallTimeout = TimeSpan.FromMinutes(1);
151 o.MaxBufferedUnacknowledgedRenderBatches = 10;
152 });
153
154 services.AddScoped<WeddingUserContext>();
155 };
156
157 options.AddDreamineIdentity(authOptions, usersDbPath);
158 });
159
160 // OG 플랫폼 이미지 자동 생성 (없을 때만)
161 var wwwroot = Path.Combine(AppContext.BaseDirectory, "wwwroot");
162 try { OgImageGenerator.EnsureGenerated(wwwroot); } catch { /* 이미지 생성 실패해도 앱 계속 실행 */ }
163
164 builder.Build().RunDreamineWpfApp<App>();
165 }

다음을 참조함 : WeddingPlatform.Services.OgImageGenerator.EnsureGenerated(), WeddingPlatform.Services.WeddingOptions.From(), GetBool(), GetFreeLoopbackPort(), GetInt(), IsTcpPortAvailable(), ResolvePath().

다음에 의해서 참조됨 : Main().

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ WriteStartupFailureLog()

void WeddingPlatform.Program.WriteStartupFailureLog ( Exception ex)
inlinestaticprivate

Startup Failure Log 데이터를 씁니다.

매개변수
exex에 사용할 Exception 값입니다.

Program.cs 파일의 266 번째 라인에서 정의되었습니다.

267 {
268 try
269 {
270 var dir = Path.Combine(
271 Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
272 "WeddingPlatform",
273 "Logs");
274 Directory.CreateDirectory(dir);
275 var path = Path.Combine(dir, "startup-error.log");
276 File.AppendAllText(path,
277 $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {ex}\r\n\r\n");
278 }
279 catch
280 {
281 // 마지막 안전망: 오류 로그 작성 실패가 앱 종료 원인이 되지 않게 둡니다.
282 }
283 }

다음에 의해서 참조됨 : Main().

이 함수를 호출하는 함수들에 대한 그래프입니다.:

이 클래스에 대한 문서화 페이지는 다음의 파일로부터 생성되었습니다.: