안녕하세요 아발로니아 에 관심을 가지고 있는 개(발)린이 입니다.
완성까지 못 할 수도 있고 느릴 수도 있지만 꾸준하게 슬로그 올려보겠습니다.
1. 목표
a. 프론트(아발로니아) 완성
b. 백엔드(Asp.net core web api) 완성
c. 개인 블로그 서버에 배포해보기
보시면서 아 저거 왜 저렇게 하지 하는 조언 마음껏 해주시면 감사하겠습니다!
실력이 뛰어난 편이 아니라 부끄러운데 열심히 올려보겠습니다…!
안녕하세요 아발로니아 에 관심을 가지고 있는 개(발)린이 입니다.
완성까지 못 할 수도 있고 느릴 수도 있지만 꾸준하게 슬로그 올려보겠습니다.
1. 목표
a. 프론트(아발로니아) 완성
b. 백엔드(Asp.net core web api) 완성
c. 개인 블로그 서버에 배포해보기
보시면서 아 저거 왜 저렇게 하지 하는 조언 마음껏 해주시면 감사하겠습니다!
실력이 뛰어난 편이 아니라 부끄러운데 열심히 올려보겠습니다…!
최근에 세미나를 다녀오면서 Aspire 라는 걸 알게 됐습니다.
배운 김에 써보자! 하고 현재 프로젝트도
Aspire에 올려서 현재 로컬에서 디버깅 중 입니다.
서버나 웹 관련해서는 정말 문외한이라 실제 배포도 잘 될지 걱정이 많네요
이번에 처음 만져봤는데 모델 만들고 클릭 몇번 하면 GET POST PUT DELETE가 자동으로 생성되더라구요 신기했습니다.
아발로니아에서 Di는 Microsoft.Extensions.DependencyInjection 이걸로 처리하라고 문서에 적혀있어 그대로 진행해보려고 합니다.
뷰 단위로 프로젝트를 나누고 싶은데 그러면 솔루션이 너무 정신없을까봐… 그냥 폴더로 나누기로 했습니다.
아주 멋진말이네요
혹시 아발로니아에 어떤 매력이나 있거나 배우게 된 계기가 있으신가요?
전 이게 궁금합니다.
음… 아발로니아의 명확한 장점을 느끼고 시작했다기 보다는 개인적으로 html css 를 싫어하고
C#과 xaml을 좋아하는데 웹도 가능하대서 도전 중 입니다.
(근데 아발로니아의 css향이 첨가된 스타일 문법은 좋은거 같아요)
예전부터 맛보기로 정말 여러가지 찍먹했는데,
C#과 xaml조합 할 때가 제일 재밌다고 느꼈거든요.
솔루션 구성과 관련해서, 애플리케이션 이름은 역방향 도메인 이름 표기법(Reverse Domain Name Notation)을 따르는 것이 권고됩니다. (닷넷 한정이 아니라 일반적으로)
역방향 도메인 이름 | 도메인 주소 |
---|---|
BaringBlog (솔루션) | baringblog.com |
BaringBlog.Api | api.baringblog.com |
BaringBlog.Browser | browser.baringblog.com |
BaringBlog.Win | win.baringblog.com |
BaringBlog.Dashboard (Aspire) | dashboard.baringblog.com |
역방향 도메인 이름 표기법은 원래 앱 스토어에서 앱을 가리키기 위한 식별자(네임스페이스)였습니다. 다만 그 앱 소유자는 그 도메인 주소의 소유자이어야, 전 세계적 유일성이 담보됩니다. (도메인 주소는 하나 밖에 존재하지 않기 때문에)
이 유일성을 담보하는 특징으로 인해, 프로젝트 혹은 어셈블리 네이밍 컨벤션으로 확대 적용된 것이죠. 마이크로소프트가 제공하는 패키지들도 이 권고를 따르고 있습니다.
xxx.yyy.extentions.microsoft.com → Microsoft.Extensions.yyy.xxx
그리고, 각 앱 프로젝트, 예들 들면, 웹API 프로젝트와 Client 앱 프로젝트는 별도의 애플리케이션입니다. 애플리케이션은 보통 고유의 도메인(관심 영역)을 가집니다.
현재 작성하고 있는 시스템은, 단일 도메인 기반의 Standalone WPF 앱과 달리, 복수의 도메인을 가집니다.
위 언급이 시스템 내부의 복수의 앱이 하나의 도메인 모델을 공유한다는 의미라면, 그렇게 하지 말라고 권고 하고 싶습니다.
도메인 모델은 각 도메인(앱)의 관심사를 반영합니다.
도메인 모델을 공유하면, 시스템이 성장할 수록, 한 객체가 복수의 관심사에 영향을 받아 코드가 상당히 번잡해지고, 복잡도가 일정 수준을 넘어 가면 이러지도 저러지도 못하는 상황에 봉착할 수 있습니다.
예를 들어, API 앱은 User 클래스를 Persitence 라이브러리에 적용하고자 하고, 클라이언트 앱은 MVVM 패턴의 모델이나 뷰모델로 사용하자 하는 경우가 있을 수 있습니다.
이 모든 관심사를 하나의 모델 코드에 다 집어 넣으면, 코드 관리도 어려워지고, 최악의 경우, 관심사 충돌로 구현이 불가능해질 수도 있습니다.
각 애플리케이션의 도메인 모델은 외부 관심사와 격리 시켜야 고유의 관심사에 충실하게 성장할 수 있습니다.
만약, BaringBlog.Model 모듈이 도메인 간 통신을 위한 DTO 모델을 담기 위한 것이라면, 그러한 의도를 반영하기 위해 BaringBlog.Dto 라고 명명하거나, BaringBlog.Api.Dto 로 명명해서, 모듈의 관리 책임이 이름에 드러나게 하는 것이 좋습니다. (Dto 모델의 원천은 API 이므로)
역방향 표기법이 권고되는 부분이 각각의 프로젝트 네이밍 부분으로 이해했는데 맞을까요? 아니면 솔루션 자체만 말씀하신 걸까요
Solution naming convention 위주로 검색해보았는데 역방향에 대해 적용한게 잘 보이지 않더라구요.
뒷단과 앞단 프로젝트는 서로 의존적이라 하나의 프로젝트에서 모델을 바꾸면 다른 프로젝트도 바꿔줘야 한다고 생각했는데 앞단에선 모델의 모든 속성을 알 필요가 없겠네요
BaringBlog.Model은 네이밍과 그 목적을 DTO로 바꾸겠습니다
정성스런 조언 감사합니다
역방향 표기법이 권고되는 부분이 각각의 프로젝트 네이밍 부분으로 이해했는데 맞을까요? 아니면 솔루션 자체만 말씀하신 걸까요
Api → Api.Dto ← Win, Browser, …
아발로니아의 크로스플랫폼 생성시
하나의 솔루션 기준으로 각각
총 5개 프로젝트가 생성됩니다.
솔루션 폴더도 같이 사용해보시면 어떨까싶네요
프로젝트 이름 변경이 쉽지 않네요
광석님이 솔루션 폴더에 대해 알려주셔서 바로 적용했고, 덕분에 정리가 좀 더 깔끔해졌습니다
전보다는 깔끔해진 모습입니다
Aspire.Hosting.DistributedApplicationException:
'Failed to get effective launch profile for project resource 'webapp'.
There is malformed JSON in the project's launch settings file at
'**\BaringBlog\BaringBlog\BaringBlog\BaringBlog.
Browser\Properties\launchSettings.json'.'
Aspire에 프로젝트를 올리고 실행했더니 다음과 같은 오류가 발생했습니다:
{
"profiles": {
"BaringBlog.Browser": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:7169;http://localhost:5235",
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
}
}
}
launchSettings.json
파일에서 마지막 줄에 있는 **불필요한 콤마(,)**가 오류를 일으켰습니다. VS에서 경고도 띄워주니 바로 제거하고
실행 후 대시보드에서 Broswer의 엔드포인트를 눌러보면,
브라우저가 띄워지면서 잘 보이는걸 확인할 수 있습니다.
(글 쓰기 전에 조금 만들어놓은 상태입니다)
- Desktop의 경우 Avalonia를 개별적으로 편하게 디버깅하기 위해 추가했습니다.
- Avalonia 프로젝트는 BaringBlog.App으로 이름을 변경하는 것이 더 나을까요?
axaml Preview를 사용하기 위해선 Desktop이 필수로 필요하기 때문에… 디버깅 목적 외에도 디자인적으로 필요한 요소입니다.
이건 또 엄연한…제 개인적인 생각이라… 조심스럽게 말해보겠습니다. (선택은 @Ko_Cho 님이니깐요!)
프로젝트의 이름을 바꾸는것보다
솔루션 폴더의 Avalonia
대신 App
으로 변경하시는건 어떨까 싶네요
현재 솔루션 트리
사실은 아발로니아를 짚어보고, 이후에 API구현을 먼저 하려고 했는데
정말 간단한 SignalR 채팅 서버만 만들어본적만 있고
백단에 대해 아무것도 모르는데 먼저 할 이유가 있을까? 라는 생각이 들어
프론트 먼저 구현하기로 했습니다.
현재 폴더 구조는 위 댓글에 브라우저 사진에 나오는것들만 구현해놓은건데요,
해당 프로젝트에 다 박아넣으면 너무너무 복잡해질 것 같아서
View 단위로 프로젝트를 만들려고 시도할 예정입니다.
WPF같은 경우 컨트롤 라이브러리로 템플릿이 있는데 아발로니아엔 없더라구요.
Microsoft.Extensions.DependencyInjection
해당 누겟을 사용하겠습니다.
public static class ServiceCollectionExtensions
{
public static void AddServices(this IServiceCollection collection)
{
}
}
ServiceCollectionExtensions 클래스를 만들어줍니다. (공식 문서에 있어요)
public override void OnFrameworkInitializationCompleted()
{
//추가
BindingPlugins.DataValidators.RemoveAt(0);
var collection = new ServiceCollection();
collection.AddServices();
var services = collection.BuildServiceProvider();
//
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow
{
DataContext = new MainViewModel()
};
}
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
{
singleViewPlatform.MainView = new MainView
{
DataContext = new MainViewModel()
};
}
base.OnFrameworkInitializationCompleted();
}
주석이 써진 부분을 추가해줍니다.
ViewModelLocator 라는 클래스가 포함되고 App.xaml에 등록되는데요
ViewModel 의 이름과 VIew 이름을 매칭시켜줍니다.
예를들어
<TransitioningContentControl
Grid.Row="1"
Grid.Column="1"
Content="{Binding MainViewCurrentPage}" >
</TransitioningContentControl>
가령 ContentControl에 Content로
public MainViewModel()
{
MainViewCurrentPage = new HomePageViewModel();
}
보여주고 싶은 뷰(HomePageView)의 뷰모델(HomepageViewModel)을 넣어주면
ViewModelLocator로 인해 HomePageView가 보여지게 됩니다.
어제도 오늘도 약속이 있어 작업을 많이 못했는데 내일은 더 달려보겠습니다 숑숑숑
**글을 쓰다보니 제가 글을 정말 못쓴다는걸 다시 한번 느껴봅니다…