[✨] Blog 페이지 생성 #8
|
@ -1,4 +1,5 @@
|
||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABoolean_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fabfadfcf168b17dd25ad62a3a2b89c89b9a3587ade1ccf7d80e4740274ef_003FBoolean_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AComponentBase_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F0691f2c61b694470b2385ca13b1109b2ddc00_003Ffb_003F9d185c09_003FComponentBase_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AComponentBase_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F0691f2c61b694470b2385ca13b1109b2ddc00_003Ffb_003F9d185c09_003FComponentBase_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATask_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F35f3a54f5acb408a3e219b2de039f1a39557b7e4515f11238cba07b60c0ce_003FTask_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATask_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F35f3a54f5acb408a3e219b2de039f1a39557b7e4515f11238cba07b60c0ce_003FTask_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F6780d13016c376c4491c5618b257d84da7eacf747ed2719783e775546b79b_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F6780d13016c376c4491c5618b257d84da7eacf747ed2719783e775546b79b_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
|
|
@ -37,5 +37,12 @@
|
||||||
<span class="oi oi-list-rich" aria-hidden="true"></span> Validation
|
<span class="oi oi-list-rich" aria-hidden="true"></span> Validation
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="nav-item px-3">
|
||||||
|
<NavLink class="nav-link" href="blog">
|
||||||
|
<span class="oi oi-list-rich" aria-hidden="true"></span> Blog
|
||||||
|
</NavLink>
|
||||||
|
</div>
|
||||||
|
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
56
BlazorApp/Components/Pages/BlogPage/Blog.razor
Normal file
56
BlazorApp/Components/Pages/BlogPage/Blog.razor
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
@page "/blog"
|
||||||
|
@rendermode InteractiveServer
|
||||||
|
|
||||||
|
<h3>Blog</h3>
|
||||||
|
|
||||||
|
@*
|
||||||
|
Dependency Injection (DI)를 사용하는 블로그 앱
|
||||||
|
|
||||||
|
목표: Blazor의 DI 패턴을 이해하고 데이터 관리
|
||||||
|
|
||||||
|
포인트
|
||||||
|
• @inject 사용
|
||||||
|
• 서비스 라이프사이클 관리 (싱글턴, 트랜지언트, 스코프드)
|
||||||
|
|
||||||
|
설명: 블로그 포스트를 추가, 삭제, 수정할 수 있는 간단한 블로그 앱을 만들어보세요. 데이터를 관리하는 서비스 클래스를 DI로 주입해 데이터를 처리합니다.
|
||||||
|
|
||||||
|
*@
|
||||||
|
|
||||||
|
@if (BlogService.Instance.ReadPosts() == null || BlogService.Instance.ReadPosts().Count == 0)
|
||||||
|
{
|
||||||
|
<p>No posts available.</p>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<ul>
|
||||||
|
@foreach (var post in BlogService.Instance.ReadPosts())
|
||||||
|
{
|
||||||
|
<li>
|
||||||
|
<h4>@post.Title</h4>
|
||||||
|
<p>@post.Content</p>
|
||||||
|
|
||||||
|
|
||||||
|
<button disabled="@(isEdit)" @onclick="() => EditPost(post.Id)">Edit</button>
|
||||||
|
<button disabled="@(isEdit)" @onclick="() => RemovePost(post.Id)">Delete</button>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
}
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
@* *@
|
||||||
|
<h3>@(isEdit ? "Edit Post" : "Add New Post")</h3>
|
||||||
|
@* *@
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Title:</label>
|
||||||
|
<InputText @bind-Value="title" />
|
||||||
|
</div>
|
||||||
|
@* *@
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Content:</label>
|
||||||
|
<InputTextArea @bind-Value="content" />
|
||||||
|
</div>
|
||||||
|
@* *@
|
||||||
|
<button @onclick = "SavePost">@(isEdit ? "Done" : "Add")</button>
|
||||||
|
|
102
BlazorApp/Components/Pages/BlogPage/Blog.razor.cs
Normal file
102
BlazorApp/Components/Pages/BlogPage/Blog.razor.cs
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
using BlazorApp.PrefixCSharp;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
|
||||||
|
namespace BlazorApp.Components.Pages.BlogPage;
|
||||||
|
|
||||||
|
public class PostItem
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Content { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public partial class Blog : ComponentBase
|
||||||
|
{
|
||||||
|
// BlogService BS = BlogService.Instance;
|
||||||
|
|
||||||
|
// private PostItem post = new PostItem();
|
||||||
|
private string title = string.Empty;
|
||||||
|
private string content = string.Empty;
|
||||||
|
private int id = 0;
|
||||||
|
private bool isEdit = false;
|
||||||
|
|
||||||
|
public void SavePost()
|
||||||
|
{
|
||||||
|
if (isEdit)
|
||||||
|
{
|
||||||
|
Console.WriteLine(this.id);
|
||||||
|
EditPost(this.id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PostItem post = new PostItem
|
||||||
|
{
|
||||||
|
Title = this.title,
|
||||||
|
Content = this.content
|
||||||
|
};
|
||||||
|
CreatePost(post);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
title = string.Empty;
|
||||||
|
content = string.Empty;
|
||||||
|
}
|
||||||
|
public void CreatePost(PostItem post)
|
||||||
|
{
|
||||||
|
BlogService.Instance.CreatePost(post);
|
||||||
|
BlogService.Instance.ReadPosts();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemovePost(int id)
|
||||||
|
{
|
||||||
|
BlogService.Instance.DeletePost(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EditPost(int id)
|
||||||
|
{
|
||||||
|
isEdit = Prefix.Toggle(isEdit);
|
||||||
|
if (isEdit)
|
||||||
|
{
|
||||||
|
PostItem post = BlogService.Instance.ReadPost(id);
|
||||||
|
title = post.Title;
|
||||||
|
content = post.Content;
|
||||||
|
this.id = post.Id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BlogService.Instance.UpdatePost(BlogService.Instance.ReadPost(id),this.title, this.content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class Singleton
|
||||||
|
{
|
||||||
|
// Lazy 선언으로 사용시에만 객체를 생성하게 하면서 외부에서 접근할 수 없는 단일 인스턴스를 저장한다.
|
||||||
|
private static Lazy<Singleton> _instance = new Lazy<Singleton>(() => new Singleton());
|
||||||
|
|
||||||
|
// 외부에서 해당 인스턴스에 접근하려면 이 속성을 통해서만 접근이 가능
|
||||||
|
public static Singleton Instance => _instance.Value;
|
||||||
|
|
||||||
|
private int value = 0;
|
||||||
|
|
||||||
|
// 싱글턴이니까 외부에서 인스턴스 생성 불가하게
|
||||||
|
private Singleton()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public int DoSomething(int value)
|
||||||
|
{
|
||||||
|
Console.WriteLine("DO SINGLETON");
|
||||||
|
this.value++;
|
||||||
|
return this.value + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkValue()
|
||||||
|
{
|
||||||
|
Console.WriteLine($"CHECK VALUE:{this.value}");
|
||||||
|
}
|
||||||
|
}
|
14
BlazorApp/Components/Pages/BlogPage/Blog.razor.css
Normal file
14
BlazorApp/Components/Pages/BlogPage/Blog.razor.css
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
.form-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.form-group label {
|
||||||
|
width: 100px;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
padding-right: 4px;
|
||||||
|
}
|
54
BlazorApp/Components/Pages/BlogPage/BlogService.cs
Normal file
54
BlazorApp/Components/Pages/BlogPage/BlogService.cs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
namespace BlazorApp.Components.Pages.BlogPage;
|
||||||
|
|
||||||
|
public class BlogService
|
||||||
|
{
|
||||||
|
private static Lazy<BlogService> _instance = new Lazy<BlogService>(() => new BlogService());
|
||||||
|
|
||||||
|
public static BlogService Instance = _instance.Value;
|
||||||
|
|
||||||
|
private List<PostItem> posts = new List<PostItem>();
|
||||||
|
private BlogService() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreatePost(PostItem post)
|
||||||
|
{
|
||||||
|
if(posts.Count > 0)
|
||||||
|
post.Id = posts[^1].Id + 1;
|
||||||
|
else
|
||||||
|
post.Id = 1;
|
||||||
|
|
||||||
|
posts.Add(post);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PostItem> ReadPosts()
|
||||||
|
{
|
||||||
|
foreach (var post in posts)
|
||||||
|
Console.WriteLine($"READ {post.Id} : {post.Title} = {post.Content}");
|
||||||
|
return this.posts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostItem ReadPost(int id)
|
||||||
|
{
|
||||||
|
foreach (var post in posts)
|
||||||
|
{
|
||||||
|
if (post.Id == id)
|
||||||
|
return post;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdatePost(PostItem post,string title, string content)
|
||||||
|
{
|
||||||
|
post.Title = title;
|
||||||
|
post.Content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void DeletePost(int id)
|
||||||
|
{
|
||||||
|
PostItem post = ReadPost(id);
|
||||||
|
posts.Remove(post);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
namespace BlazorApp.Components.Pages.TodoPage
|
namespace BlazorApp.Components.Pages.TodoPage
|
||||||
{
|
{
|
||||||
|
|
||||||
public partial class Todo : ComponentBase
|
public partial class Todo : ComponentBase
|
||||||
{
|
{
|
||||||
private List<TodoItem> todos = new();
|
private List<TodoItem> todos = new();
|
||||||
|
@ -37,6 +38,7 @@ namespace BlazorApp.Components.Pages.TodoPage
|
||||||
|
|
||||||
private void ToggleTodo(TodoItem todo, int index)
|
private void ToggleTodo(TodoItem todo, int index)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (todo.IsDone)
|
if (todo.IsDone)
|
||||||
{
|
{
|
||||||
todo.SuccessDate = string.Empty;
|
todo.SuccessDate = string.Empty;
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.form-group label {
|
.form-group label {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
@ -21,8 +20,10 @@
|
||||||
|
|
||||||
.form-actions {
|
.form-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
flex-grow: 1;
|
||||||
|
/*justify-content: flex-end;*/
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.success-message {
|
.success-message {
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -13,7 +13,7 @@ using System.Reflection;
|
||||||
[assembly: System.Reflection.AssemblyCompanyAttribute("BlazorApp")]
|
[assembly: System.Reflection.AssemblyCompanyAttribute("BlazorApp")]
|
||||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+4781a17b00b8e21414f02e947102acf72c5c6178")]
|
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+22a9ed453132bd81e3b047b70a2c7c8fecf41cf5")]
|
||||||
[assembly: System.Reflection.AssemblyProductAttribute("BlazorApp")]
|
[assembly: System.Reflection.AssemblyProductAttribute("BlazorApp")]
|
||||||
[assembly: System.Reflection.AssemblyTitleAttribute("BlazorApp")]
|
[assembly: System.Reflection.AssemblyTitleAttribute("BlazorApp")]
|
||||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
d6262563cb144b1b24689bcb852f66331e78b742afea34cc7526f77806d8fefb
|
0de9e1463f1e76d9de8902e22e93a1f278b71d472a502e3acfe4ed33a0f2e63e
|
||||||
|
|
|
@ -54,6 +54,10 @@ build_metadata.AdditionalFiles.CssScope = b-fekawvbbds
|
||||||
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50cy9MYXlvdXQvTmF2TWVudS5yYXpvcg==
|
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50cy9MYXlvdXQvTmF2TWVudS5yYXpvcg==
|
||||||
build_metadata.AdditionalFiles.CssScope = b-zswk0q6kaa
|
build_metadata.AdditionalFiles.CssScope = b-zswk0q6kaa
|
||||||
|
|
||||||
|
[/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/Components/Pages/BlogPage/Blog.razor]
|
||||||
|
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50cy9QYWdlcy9CbG9nUGFnZS9CbG9nLnJhem9y
|
||||||
|
build_metadata.AdditionalFiles.CssScope = b-yzv2llfl6l
|
||||||
|
|
||||||
[/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/Components/Pages/TodoPage/Todo.razor]
|
[/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/Components/Pages/TodoPage/Todo.razor]
|
||||||
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50cy9QYWdlcy9Ub2RvUGFnZS9Ub2RvLnJhem9y
|
build_metadata.AdditionalFiles.TargetPath = Q29tcG9uZW50cy9QYWdlcy9Ub2RvUGFnZS9Ub2RvLnJhem9y
|
||||||
build_metadata.AdditionalFiles.CssScope = b-n64y2ur3f8
|
build_metadata.AdditionalFiles.CssScope = b-n64y2ur3f8
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
50edfd86d0e1da31fa31883ae82e1f3520bbce7f4aabb52fd74698655be3fe0f
|
ef301e20d32eb1a6f2108ec68675e157089016ae7ab00873f44aef4cee05680c
|
||||||
|
|
|
@ -33,3 +33,4 @@
|
||||||
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/ref/BlazorApp.dll
|
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/ref/BlazorApp.dll
|
||||||
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/Components/Pages/TodoPage/Todo.razor.rz.scp.css
|
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/Components/Pages/TodoPage/Todo.razor.rz.scp.css
|
||||||
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/Components/Pages/ValidationPage/Validation.razor.rz.scp.css
|
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/Components/Pages/ValidationPage/Validation.razor.rz.scp.css
|
||||||
|
/Users/seankim/1.Program/Project(ASP)/BlazorApp/BlazorApp/obj/Debug/net8.0/scopedcss/Components/Pages/BlogPage/Blog.razor.rz.scp.css
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,14 @@
|
||||||
|
.form-group[b-yzv2llfl6l] {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.form-group label[b-yzv2llfl6l] {
|
||||||
|
width: 100px;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
padding-right: 4px;
|
||||||
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
|
|
||||||
/* todo 용 CSS */
|
|
||||||
.list-item[b-n64y2ur3f8] {
|
.list-item[b-n64y2ur3f8] {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.form-group label[b-z8q1q1jnjv] {
|
.form-group label[b-z8q1q1jnjv] {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
@ -21,8 +20,10 @@
|
||||||
|
|
||||||
.form-actions[b-z8q1q1jnjv] {
|
.form-actions[b-z8q1q1jnjv] {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
flex-grow: 1;
|
||||||
|
/*justify-content: flex-end;*/
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.success-message[b-z8q1q1jnjv] {
|
.success-message[b-z8q1q1jnjv] {
|
||||||
|
|
|
@ -206,6 +206,21 @@ main[b-fekawvbbds] {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* _content/BlazorApp/Components/Pages/BlogPage/Blog.razor.rz.scp.css */
|
||||||
|
.form-group[b-yzv2llfl6l] {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.form-group label[b-yzv2llfl6l] {
|
||||||
|
width: 100px;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
padding-right: 4px;
|
||||||
|
}
|
||||||
/* _content/BlazorApp/Components/Pages/TodoPage/Todo.razor.rz.scp.css */
|
/* _content/BlazorApp/Components/Pages/TodoPage/Todo.razor.rz.scp.css */
|
||||||
|
|
||||||
.list-item[b-n64y2ur3f8] {
|
.list-item[b-n64y2ur3f8] {
|
||||||
|
@ -266,7 +281,6 @@ main[b-fekawvbbds] {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.form-group label[b-z8q1q1jnjv] {
|
.form-group label[b-z8q1q1jnjv] {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
@ -281,8 +295,10 @@ main[b-fekawvbbds] {
|
||||||
|
|
||||||
.form-actions[b-z8q1q1jnjv] {
|
.form-actions[b-z8q1q1jnjv] {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
flex-grow: 1;
|
||||||
|
/*justify-content: flex-end;*/
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.success-message[b-z8q1q1jnjv] {
|
.success-message[b-z8q1q1jnjv] {
|
||||||
|
|
|
@ -206,6 +206,21 @@ main[b-fekawvbbds] {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* _content/BlazorApp/Components/Pages/BlogPage/Blog.razor.rz.scp.css */
|
||||||
|
.form-group[b-yzv2llfl6l] {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.form-group label[b-yzv2llfl6l] {
|
||||||
|
width: 100px;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
padding-right: 4px;
|
||||||
|
}
|
||||||
/* _content/BlazorApp/Components/Pages/TodoPage/Todo.razor.rz.scp.css */
|
/* _content/BlazorApp/Components/Pages/TodoPage/Todo.razor.rz.scp.css */
|
||||||
|
|
||||||
.list-item[b-n64y2ur3f8] {
|
.list-item[b-n64y2ur3f8] {
|
||||||
|
@ -266,7 +281,6 @@ main[b-fekawvbbds] {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.form-group label[b-z8q1q1jnjv] {
|
.form-group label[b-z8q1q1jnjv] {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
@ -281,8 +295,10 @@ main[b-fekawvbbds] {
|
||||||
|
|
||||||
.form-actions[b-z8q1q1jnjv] {
|
.form-actions[b-z8q1q1jnjv] {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
flex-grow: 1;
|
||||||
|
/*justify-content: flex-end;*/
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.success-message[b-z8q1q1jnjv] {
|
.success-message[b-z8q1q1jnjv] {
|
||||||
|
|
|
@ -191,3 +191,7 @@ WebAssembly의 개념을 이해하고, Blazor를 사용하여 클라이언트
|
||||||
## **결론**
|
## **결론**
|
||||||
|
|
||||||
이미 다양한 개발 경험과 기본기를 갖추고 계신 만큼, .NET Core와 Blazor, EF6를 체계적으로 학습하신다면 빠르게 실력을 향상시킬 수 있을 것입니다. 제안드린 단계별 학습 방법을 따라가며, 실습과 프로젝트를 통해 이론을 실제로 적용해보세요. 학습 과정에서 궁금한 점이나 어려운 부분이 생기면 언제든지 질문해 주세요. 성공적인 학습과 개발 여정을 응원합니다! 화이팅하세요!
|
이미 다양한 개발 경험과 기본기를 갖추고 계신 만큼, .NET Core와 Blazor, EF6를 체계적으로 학습하신다면 빠르게 실력을 향상시킬 수 있을 것입니다. 제안드린 단계별 학습 방법을 따라가며, 실습과 프로젝트를 통해 이론을 실제로 적용해보세요. 학습 과정에서 궁금한 점이나 어려운 부분이 생기면 언제든지 질문해 주세요. 성공적인 학습과 개발 여정을 응원합니다! 화이팅하세요!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ex, 경로탐색 알고리즘, 충돌회피 알고리즘, 교통 트래픽 분산 알고리즘 트래픽 잼 탈출 알고리즘 등
|
|
@ -24,3 +24,55 @@
|
||||||
- 코드에서 어떤 동작이나 정보를 제공하거나, 특정 조건에 따라 처리되는 방식을 지정할 수 있다.
|
- 코드에서 어떤 동작이나 정보를 제공하거나, 특정 조건에 따라 처리되는 방식을 지정할 수 있다.
|
||||||
- 이미 존재하는(Required, Range, Obsolte, 등) 속성들도 있지만, 사용자가 직접 정의해서 사용할 수 있다.
|
- 이미 존재하는(Required, Range, Obsolte, 등) 속성들도 있지만, 사용자가 직접 정의해서 사용할 수 있다.
|
||||||
- 2의 EditForm과 엮으면 좋음
|
- 2의 EditForm과 엮으면 좋음
|
||||||
|
|
||||||
|
## 4. Dependency Injection (DI)
|
||||||
|
- 의존성 관리를 쉽게 하기 위한 설계 패턴으로 객체가 필요로 하는 의존성을 직접 생성하지 않고,<br>
|
||||||
|
외부에서 주입해주는 방식으로 객체 간 결합도를 줄이고 테스트 가능성과 유연성을 높이는 역할을 한다.
|
||||||
|
- 의존성(Dependency)란?
|
||||||
|
- 간단하게 한 객체가 다른 객체의 기능, 데이터를 필요로 할 때 이를 의존성이라고 한다.
|
||||||
|
- A 클래스가 B 클래스의 기능을 사용하면 A는 B에 의존한다고 보면 된다.
|
||||||
|
- 핵심 개념
|
||||||
|
- 제어 역전(inversion of Control) : DI도 결국 이 개념의 한 형태로서<br>
|
||||||
|
전통적으로 객체는 스스로 필요한 의존성을 직접 생성하지만 DI에서는 외부에서 의존성 주입해 객체간 결합도 줄임
|
||||||
|
- 느슨한 결합 : DI는 클래스 간 결합도 낮추는 방법으로 객체가 다른 객체의 구체적 구현에 의존하지 않고 인터페이스나 추상 클래스에 의존하게 한다.<br>
|
||||||
|
그로 인해 시스템의 유지보수성과 확장성을 높인다.
|
||||||
|
|
||||||
|
## 5. 싱글턴 패턴
|
||||||
|
- 가장 유명하고 자주 쓰이면서 남발하면 절대 안되는 패턴
|
||||||
|
```csharp
|
||||||
|
public class Singleton
|
||||||
|
{
|
||||||
|
// Lazy 선언으로 사용시에만 객체를 생성하게 하면서 외부에서 접근할 수 없는 단일 인스턴스를 저장한다.
|
||||||
|
private static Lazy<Singleton> _instance = new Lazy<Singleton>(() => new Singleton());
|
||||||
|
|
||||||
|
// 외부에서 해당 인스턴스에 접근하려면 이 속성을 통해서만 접근이 가능
|
||||||
|
public static Singleton Instance => _instance.Value;
|
||||||
|
|
||||||
|
private int value = 0;
|
||||||
|
|
||||||
|
// 싱글턴이니까 외부에서 인스턴스 생성 불가하게
|
||||||
|
private Singleton()
|
||||||
|
{
|
||||||
|
// 초기화
|
||||||
|
}
|
||||||
|
|
||||||
|
public int DoSomething(int value)
|
||||||
|
{
|
||||||
|
// 그냥 아무 동작이나
|
||||||
|
Console.WriteLine("DO SINGLETON");
|
||||||
|
this.value++;
|
||||||
|
return this.value + value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Base
|
||||||
|
{
|
||||||
|
private void CheckSingle()
|
||||||
|
{
|
||||||
|
Singleton ton1 = Singleton.Instance;
|
||||||
|
Singleton ton2 = Singleton.Instance;
|
||||||
|
if (ton1 == ton2)
|
||||||
|
Console.WriteLine("Same");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
Loading…
Reference in New Issue
Block a user