初めに
c#を触り始めて、とりあえずCRUDを実装することが出来たので公開します。
Railsとは違ってフォルダ構成など自由度が高いし
データの取ってきかたとかよくわかっていない部分が多いので
もっとこうしたら良いなどあれば指摘してほしいです。
github
実装したフォルダはgithubに投稿しています。
https://github.com/Sibakeny/C-Crud
フォルダ構成
フォルダ構成に関しては
├── Domain
│ ├── Entities
│ └── Repositories
├── Infrastructure
├── Winform
│ ├── ViewModel
│ └── Views
DomainのEntitiesでPostクラスを定義している。
このPostクラスは投稿、表示する際のひな型として使う。
DomainのRepositoriesではIPostRepositoryというインターフェイスを実装していて
Save Update GetAllなどのメソッドを定義している
InfrastructureではSQLServerへの接続関係の処理を書いてる
Winformのviewsではフォームを設定し、ここでは基本的に処理は書かないようにしている。
具体的な処理はviewModelに書いており、viewで使う値はviewModelのインスタンス変数として設定し、viewModelから取り出して使う形にしている。
実装内容
Homeのコード
usingMyCRUD.Winform.ViewModel;usingMyCRUD.Winform.Views;usingSystem;usingSystem.Windows.Forms;namespaceMyCRUD{publicpartialclassForm1:Form{privatestaticForm1_form1Instance;publicstaticForm1Form1Instance{get{return_form1Instance;}set{_form1Instance=value;}}publicPanelPanelContainer{get{returnthis.panelContainer;}}privateHomeViewModel_viewModel=newHomeViewModel();publicForm1(){InitializeComponent();Form1.Form1Instance=this;}privatevoidbutton1_Click(objectsender,EventArgse){NewPostf=newNewPost();changeForm(f);}privatevoidForm1_Load(objectsender,EventArgse){}publicvoidchangeForm(objectform){if(this.panelContainer.Controls.Count>0){this.panelContainer.Controls.RemoveAt(0);}Formfh=formasForm;fh.TopLevel=false;fh.Dock=DockStyle.Fill;this.panelContainer.Controls.Add(fh);this.panelContainer.Tag=fh;fh.Show();}privatevoidbtnPosts_Click(objectsender,EventArgse){Postsf=newPosts();changeForm(f);}}}
上から順番に public static でForm1Instanceを定義して
コンストラクタにて
Form1.Form1Instance=this;
とすることで外部からフォームにアクセスできるようにしている。
メイン画面のパネルに投稿画面、投稿表示画面に表示するためにchangeFormメソッドを作っています。
外部のフォームからchangeFormを実行する場合はForm.Form1Instance.changeFormのように呼びだします。
投稿作成
usingMyCRUD.Winform.ViewModel;usingSystem;usingSystem.Windows.Forms;namespaceMyCRUD.Winform.Views{publicpartialclassNewPost:Form{privateNewPostViewModel_viewModel=newNewPostViewModel();publicNewPost(){InitializeComponent();titleTextBox.DataBindings.Add("Text",_viewModel,nameof(_viewModel.TitleText));bodyTextBox.DataBindings.Add("Text",_viewModel,nameof(_viewModel.BodyText));}privatevoidpostButton_Click(objectsender,EventArgse){try{_viewModel.Save();}catch(Exceptionex){MessageBox.Show(ex.Message);}MessageBox.Show("保存しました。");this.Close();}}}
保存処理はviewModelで行います。
title,bodyをviewModelにて使えるようにviewModelのプロパティのTitleText,BodyTextを設定します。
NewPostViewModelでは
usingMyCRUD.Domain.Entities;usingMyCRUD.Domain.Repositories;usingMyCRUD.Infrastructure;namespaceMyCRUD.Winform.ViewModel{classNewPostViewModel{privateIPostRepository_post;publicNewPostViewModel():this(newPostSQLite()){}publicNewPostViewModel(IPostRepositorypost){_post=post;}publicstringTitleText{get;set;}publicstringBodyText{get;set;}publicvoidSave(){PostEntityentity=newPostEntity(TitleText,BodyText);_post.Save(entity);}}}
引数なしでインスタンスが作成されたときは
new PostSQLiteが引数に渡されます。
IPostRepositoryではSaveメソッドが定義されているので
_post.Saveメソッドの実行が出来ます。
Saveメソッド自体はPostSQLiteクラスで定義されていて
PostEntityをもとにデータの作成を行います。
SQL
sql関係に関してはInfrastructureフォルダで書いていて
SQLHeperにてexecuteメソッドを実装
internalstaticvoidExecute(stringsql,SqlParameter[]parameters){using(varconnection=newSqlConnection(ConnectionString))using(varcommand=newSqlCommand(sql,connection)){connection.Open();if(parameters!=null){command.Parameters.AddRange(parameters);}command.ExecuteNonQuery();}}
このexecuteメソッドをもとにsave処理を
publicvoidSave(PostEntitypost){stringinsert=@"
INSERT INTO Posts
(title,body)
VALUES
(@title,@body)
";varargs=newList<SqlParameter>{newSqlParameter("@title",post.Title),newSqlParameter("@body",post.Body)};SQLHelper.Execute(insert,args.ToArray());}
このように書いています。
これでPostEntityをもとに保存処理が行われます。
終わりに
大体こんな感じでCRUDを実装してみました。
実装の仕方に関してはUdemyの
C#でドメイン駆動開発とテスト駆動開発を使って保守性の高いプログラミングをする方法
https://www.udemy.com/course/domain-1/
を参考にしました。
ドメイン駆動自体全然理解出来てないのでおそらく実装の仕方がだいぶ変だと思います。
ドメイン駆動に関して少し調べてみたのですが結構情報少ないんですよね、
それにドメイン駆動以外ではどんな感じに実装するんでしょうか.....
終わり