{"id":848,"date":"2012-03-09T07:06:48","date_gmt":"2012-03-09T07:06:48","guid":{"rendered":"http:\/\/fanzung.tk\/?p=848"},"modified":"2026-06-13T18:32:05","modified_gmt":"2026-06-13T18:32:05","slug":"gi%e1%bb%9bi-thi%e1%bb%87u-th%c6%b0-vi%e1%bb%87n-mvppattern-dung-xay-d%e1%bb%b1ng-mo-hinh-%e1%bb%a9ng-d%e1%bb%a5ng-d%e1%bb%b1a-tren-ki%e1%ba%bfn-truc-mvp","status":"publish","type":"post","link":"https:\/\/dongson.info\/?p=848","title":{"rendered":"Gi\u1edbi thi\u1ec7u th\u01b0 vi\u1ec7n MvpPattern d\u00f9ng x\u00e2y d\u1ef1ng m\u00f4 h\u00ecnh \u1ee9ng d\u1ee5ng d\u1ef1a tr\u00ean ki\u1ebfn tr\u00fac MVP"},"content":{"rendered":"<p><strong><br \/>\n<\/strong><\/p>\n<p>b\u1edfi <a href=\"http:\/\/www.facebook.com\/ngthman\">Nguy\u1ec5n Th\u00e0nh M\u00e3n<\/a> v\u00e0o 8 th\u00e1ng 1 2013 l\u00fac 17:20 \u00b7<\/p>\n<p><strong>Gi\u1edbi thi\u1ec7u th\u01b0 vi\u1ec7n MvpPattern d\u00f9ng \u0111\u1ec3 x\u00e2y d\u1ef1ng m\u00f4 h\u00ecnh \u1ee9ng d\u1ee5ng d\u1ef1a tr\u00ean ki\u1ebfn tr\u00fac Model \u2013 View \u2013 Presenter\u00a0<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p><strong>1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Gi\u1edbi thi\u1ec7u<\/strong><\/p>\n<p>Trong qu\u00e1 tr\u00ecnh th\u1ef1c hi\u1ec7n d\u1ef1 \u00e1n <em>Ph\u1ea7n m\u1ec1m qu\u1ea3n l\u00fd t\u01b0 li\u1ec7u v\u00e0 Website Nh\u00e3 nh\u1ea1c cung \u0111\u00ecnh Hu\u1ebf<\/em>, t\u1eeb kinh nghi\u1ec7m c\u1ee7a c\u00e1c d\u1ef1 \u00e1n tr\u01b0\u1edbc v\u00e0 qua t\u00ecm hi\u1ec3u tham kh\u1ea3o tr\u00ean Internet, nh\u00f3m th\u1ef1c hi\u1ec7n d\u1ef1 \u00e1n \u0111\u00e3 h\u1ecdc h\u1ecfi, c\u1ea3i ti\u1ebfn v\u00e0 t\u1ed5 ch\u1ee9c l\u1ea1i th\u00e0nh th\u01b0 vi\u1ec7n MvpPattern ch\u1ea1y tr\u00ean n\u1ec1n t\u1ea3ng .NET, v\u1edbi m\u1ee5c ti\u00eau n\u00e2ng cao t\u00ednh t\u00e1i s\u1eed d\u1ee5ng, gi\u1ea3m b\u1edbt kh\u1ed1i l\u01b0\u1ee3ng m\u00e3 c\u1ea7n vi\u1ebft cho c\u00e1c thao t\u00e1c th\u01b0\u1eddng g\u1eb7p khi x\u00e2y d\u1ef1ng ph\u1ea7n m\u1ec1m \u00e1p d\u1ee5ng theo m\u00f4 h\u00ecnh Model-View-Presenter (MVP). M\u00f4 h\u00ecnh <a href=\"http:\/\/www.facebook.com\/l.php?u=http%3A%2F%2Fwww.fpt.edu.vn%2Fstory%2Fkien-truc-model-view-presenter-trong-net&amp;h=lAQH0SGzt&amp;s=1\" target=\"_blank\">MVP<\/a> \u0111\u00e3 kh\u00e1 quen thu\u1ed9c v\u1edbi gi\u1edbi l\u1eadp tr\u00ecnh n\u00ean vi\u1ec7c gi\u1edbi thi\u1ec7u n\u1eb1m ngo\u00e0i ph\u1ea1m vi b\u00e0i vi\u1ebft n\u00e0y. \u0110\u00e2y l\u00e0 phi\u00ean b\u1ea3n \u0111\u1ea7u ti\u00ean, b\u01b0\u1edbc \u0111\u1ea7u ch\u1ec9 m\u1edbi kh\u00e1i qu\u00e1t h\u00f3a v\u1ea5n \u0111\u1ec1 \u1edf m\u1ee9c \u0111\u1ed9 c\u01a1 b\u1ea3n, n\u00ean c\u00f3 m\u1ed9t s\u1ed1 \u0111i\u1ec3m v\u1eabn ch\u01b0a \u0111\u01b0\u1ee3c ho\u00e0n thi\u1ec7n, ch\u01b0a \u0111\u01b0\u1ee3c nh\u01b0 mong mu\u1ed1n. Trong qu\u00e1 tr\u00ecnh \u1ee9ng d\u1ee5ng th\u1ef1c ti\u1ec5n, th\u01b0 vi\u1ec7n s\u1ebd ti\u1ebfp t\u1ee5c \u0111\u01b0\u1ee3c c\u1ea3i ti\u1ebfn cho ph\u00f9 h\u1ee3p v\u00e0 ti\u1ec7n l\u1ee3i h\u01a1n. Ch\u00fang t\u00f4i chia s\u1ebb m\u1ed9t s\u1ed1 kinh nghi\u1ec7m v\u00e0 mong nh\u1eadn \u0111\u01b0\u1ee3c \u00fd ki\u1ebfn \u0111\u00f3ng g\u00f3p.<\/p>\n<p>C\u00e1c v\u00ed d\u1ee5 s\u1eed d\u1ee5ng theo c\u00e1ch l\u1eadp tr\u00ecnh truy\u1ec1n th\u1ed1ng, ch\u01b0a \u0111\u00e1p \u1ee9ng ho\u00e0n to\u00e0n nguy\u00ean l\u00fd <em>\u0111\u1ea3o ng\u01b0\u1ee3c ph\u1ee5 thu\u1ed9c<\/em> (Dependency Inversion Principle \u2013 DIP[*], c\u00e1ch g\u1ecdi kh\u00e1c l\u00e0 Inversion of Control \u2013 IoC), vi\u1ec7c \u00e1p d\u1ee5ng nguy\u00ean l\u00fd n\u00e0y l\u00e0m gi\u1ea3m b\u1edbt s\u1ef1 k\u1ebft n\u1ed1i (decoupling) ch\u1eb7t ch\u1ebd gi\u1eefa c\u00e1c \u0111\u1ed1i t\u01b0\u1ee3ng trong ph\u1ea7n m\u1ec1m, t\u0103ng \u0111\u1ed9 linh ho\u1ea1t v\u00e0 gi\u00fap ph\u1ea7n m\u1ec1m c\u00f3 t\u00ednh module h\u00f3a cao. Trong khu\u00f4n kh\u1ed5 b\u00e0i vi\u1ebft kh\u00f4ng th\u1ec3 tr\u00ecnh b\u00e0y \u0111\u1ea7y \u0111\u1ee7, xin tham kh\u1ea3o m\u00e3 ngu\u1ed3n v\u00ed d\u1ee5 \u00e1p d\u1ee5ng th\u01b0 vi\u1ec7n <a href=\"http:\/\/www.facebook.com\/l.php?u=http%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fhh237493.aspx&amp;h=eAQEi5M5Q&amp;s=1\" target=\"_blank\">Unity Application Block<\/a> (phi\u00ean b\u1ea3n 2.1) \u0111\u1ec3 c\u00e0i \u0111\u1eb7t m\u1eabu thi\u1ebft k\u1ebf (design pattern) <em>dependency injection<\/em>.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>2\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 C\u1ea5u tr\u00fac g\u00f3i<\/strong><\/p>\n<p><strong>2.1\u00a0\u00a0\u00a0\u00a0\u00a0 Bi\u1ec3u \u0111\u1ed3 g\u00f3i<\/strong><\/p>\n<p>C\u00e1c giao di\u1ec7n v\u00e0 l\u1edbp c\u1ee7a th\u01b0 vi\u1ec7n.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.dropbox.com\/scl\/fi\/aujt0e1x2zgqk1m0ztbnb\/MvpPattern_1.png?rlkey=tpdn1lpuevkoqarcthcq0sg9j&#038;st=qzmi041t&#038;dl=1\" alt=\"\" width=\"707\" height=\"703\" \/><\/p>\n<p>V\u1ecb tr\u00ed c\u1ee7a th\u01b0 vi\u1ec7n trong m\u00f4 h\u00ecnh MVP.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.dropbox.com\/scl\/fi\/o5itftjyzwlyi7nde7qya\/MvpPattern_2.png?rlkey=cq817i3tr7elckry0hnbbtxg9&#038;st=f59m0dl4&#038;dl=1\" alt=\"\" width=\"720\" height=\"619\" \/><\/p>\n<p>Ghi ch\u00fa: <em>C\u00e1c giao di\u1ec7n v\u00e0 l\u1edbp c\u00f3 m\u00e0u \u0111en l\u00e0 m\u00e3 v\u00ed d\u1ee5, kh\u00f4ng thu\u1ed9c th\u00e0nh ph\u1ea7n c\u1ee7a th\u01b0 vi\u1ec7n.<\/em><\/p>\n<p><strong>2.2\u00a0\u00a0\u00a0\u00a0\u00a0 T\u1ed5ng quan<\/strong><\/p>\n<p>\u00c1p d\u1ee5ng th\u01b0 vi\u1ec7n MvpPattern cho ph\u00e1t tri\u1ec3n m\u00f4 h\u00ecnh ph\u1ea7n m\u1ec1m d\u1ef1a theo ki\u1ebfn tr\u00fac ba t\u1ea7ng Model \u2013 View \u2013 Presenter(MVP). MvpPattern theo c\u01a1 ch\u1ebf Passive View, t\u1ea5t c\u1ea3 c\u00e1c t\u01b0\u01a1ng t\u00e1c t\u1eeb t\u1ea7ng giao di\u1ec7n (View) \u0111i xu\u1ed1ng v\u00e0 t\u1ea7ng d\u1eef li\u1ec7u (Model) tr\u1edf l\u00ean \u0111\u1ec1u th\u00f4ng qua t\u1ea7ng trung gian nghi\u1ec7p v\u1ee5 (Presenter).<\/p>\n<p>T\u1ea7ng d\u1eef li\u1ec7u s\u1eed d\u1ee5ng <a href=\"http:\/\/www.facebook.com\/l.php?u=http%3A%2F%2Fcongthuong.googlecode.com%2Ffiles%2FLINQ%2520tieng%2520viet.pdf&amp;h=jAQHUMyq8&amp;s=1\" target=\"_blank\">LINQ<\/a> (LINQ \u0111\u01b0\u1ee3c Microsoft t\u00edch h\u1ee3p v\u00e0o Visual Studio t\u1eeb phi\u00ean b\u1ea3n 2008. tuy nhi\u00ean v\u1eabn c\u00f3 th\u1ec3 d\u00f9ng trong phi\u00ean b\u1ea3n 2005, l\u01b0u \u00fd l\u00e0 LINQ ch\u1ec9 d\u00f9ng \u0111\u01b0\u1ee3c cho h\u1ec7 qu\u1ea3n tr\u1ecb c\u01a1 s\u1edf d\u1eef li\u1ec7u MS SQL Server) v\u00e0 k\u1ebft h\u1ee3p v\u1edbi th\u01b0 vi\u1ec7n <a href=\"http:\/\/www.facebook.com\/l.php?u=http%3A%2F%2Fweblogs.asp.net%2Fscottgu%2Farchive%2F2008%2F01%2F07%2Fdynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&amp;h=rAQF1JPnN&amp;s=1\" target=\"_blank\">Dynamic LINQ<\/a> \u0111\u1ec3 t\u1ea1o c\u00e1c c\u00e2u truy v\u1ea5n c\u00f3 \u0111i\u1ec1u ki\u1ec7n t\u01b0\u01a1ng t\u1ef1 c\u00e2u l\u1ec7nh truy v\u1ea5n SQL quen thu\u1ed9c.<\/p>\n<p><strong>2.2.1\u00a0\u00a0\u00a0\u00a0\u00a0 T\u1ea7ng Business<\/strong><\/p>\n<p><strong>2.2.1.1\u00a0 Giao di\u1ec7n IGenericView<\/strong><\/p>\n<p>Giao di\u1ec7n g\u1ed1c, v\u1edbi m\u1ee5c \u0111\u00edch cho c\u00e1c giao di\u1ec7n kh\u00e1c k\u1ebf th\u1eeba.<\/p>\n<p>public interface IGenericView<\/p>\n<p>{<\/p>\n<p>}<\/p>\n<p><strong>2.2.1.2\u00a0 Giao di\u1ec7n IListManipulationView <\/strong><\/p>\n<p>\u0110\u1ecbnh ngh\u0129a c\u00e1c thu\u1ed9c t\u00ednh v\u00e0 s\u1ef1 ki\u1ec7n thao t\u00e1c c\u01a1 b\u1ea3n l\u00e0 th\u00eam m\u1edbi, ch\u1ec9nh s\u1eeda, x\u00f3a b\u1ecf v\u00e0 l\u1ef1a ch\u1ecdn khi x\u1eed l\u00fd d\u1eef li\u1ec7u tr\u00ean m\u1ed9t danh s\u00e1ch, d\u1eabn xu\u1ea5t t\u1eeb IGenericView.<\/p>\n<p>public interface IListManipulationView : IGenericView<\/p>\n<p>{<\/p>\n<p>\/\/ Tr\u1ea3 v\u1ec1 ho\u1eb7c thi\u1ebft l\u1eadp danh s\u00e1ch c\u00e1c \u0111\u1ed1i t\u01b0\u1ee3ng c\u1ee7a view<\/p>\n<p>IList ListItem { set; get; }<\/p>\n<p>&nbsp;<\/p>\n<p>\/\/ Tr\u1ea3 v\u1ec1 \u0111\u1ed1i t\u01b0\u1ee3ng \u0111\u01b0\u1ee3c t\u1ea1o m\u1edbi tr\u00ean view<\/p>\n<p>TEntity NewItem { get; }<\/p>\n<p>&nbsp;<\/p>\n<p>\/\/ Tr\u1ea3 v\u1ec1 \u0111\u1ed1i t\u01b0\u1ee3ng hi\u1ec7n h\u00e0nh tr\u00ean danh s\u00e1ch c\u1ee7a view<\/p>\n<p>TEntity CurrentItem { get; }<\/p>\n<p>&nbsp;<\/p>\n<p>\/\/ Tr\u1ea3 v\u1ec1 danh s\u00e1ch c\u00e1c \u0111\u1ed1i t\u01b0\u1ee3ng \u0111\u01b0\u1ee3c l\u1ef1a ch\u1ecdn tr\u00ean view<\/p>\n<p>IList SelectedItems { get; }<\/p>\n<p>&nbsp;<\/p>\n<p>\/\/ S\u1ef1 ki\u1ec7n ph\u00e1t sinh khi th\u00eam m\u1ed9t h\u1ea1ng m\u1ee5c d\u1eef li\u1ec7u m\u1edbi<\/p>\n<p>event EventHandler OnAddEventHandler;<\/p>\n<p>&nbsp;<\/p>\n<p>\/\/ S\u1ef1 ki\u1ec7n ph\u00e1t sinh khi l\u01b0u tr\u1eef th\u00f4ng tin c\u1ee7a h\u1ea1ng m\u1ee5c d\u1eef li\u1ec7u<\/p>\n<p>event EventHandler OnSaveEventHandler;<\/p>\n<p>&nbsp;<\/p>\n<p>\/\/ S\u1ef1 ki\u1ec7n ph\u00e1t sinh khi x\u00f3a b\u1ecf c\u00e1c h\u1ea1ng m\u1ee5c d\u1eef li\u1ec7u<\/p>\n<p>event EventHandler OnDeleteEventHandler;<\/p>\n<p>&nbsp;<\/p>\n<p>\/\/ S\u1ef1 ki\u1ec7n ph\u00e1t sinh khi c\u00e1c h\u1ea1ng m\u1ee5c d\u1eef li\u1ec7u \u0111\u01b0\u1ee3c l\u1ef1a ch\u1ecdn<\/p>\n<p>event EventHandler OnSelectEventHandler;<\/p>\n<p>}<\/p>\n<p><em>V\u00ed d\u1ee5:<\/em> Form danh s\u00e1ch ng\u01b0\u1eddi d\u00f9ng c\u00f3 c\u00e1c thao t\u00e1c th\u00eam m\u1edbi, c\u1eadp nh\u1eadt v\u00e0\u00a0 x\u00f3a b\u1ecf. \u0110\u1ecbnh ngh\u0129a giao di\u1ec7n IUserView k\u1ebf th\u1eeba t\u1eeb giao di\u1ec7n IListManipulationView, \u0111\u1ecbnh ngh\u0129a th\u00eam m\u1ed9t s\u1ed1 thu\u1ed9c t\u00ednh c\u1ea7n thi\u1ebft kh\u00e1c v\u00e0 thi h\u00e0nh giao di\u1ec7n n\u00e0y cho form.<\/p>\n<p>public interface IUserView : <strong>IListManipulationView<\/strong><\/p>\n<p>Thi h\u00e0nh \u00a0giao di\u1ec7n m\u1edbi cho form:<\/p>\n<p>public partial class frmUser : Form, <strong>IUserView<\/strong><\/p>\n<p><strong>2.2.1.3\u00a0 Giao di\u1ec7n IListSelectionView <\/strong><\/p>\n<p>\u0110\u1ecbnh ngh\u0129a c\u00e1c thu\u1ed9c t\u00ednh v\u00e0 s\u1ef1 ki\u1ec7n khi l\u1ef1a ch\u1ecdn c\u00e1c h\u1ea1ng m\u1ee5c d\u1eef li\u1ec7u tr\u00ean m\u1ed9t danh s\u00e1ch, d\u1eabn xu\u1ea5t t\u1eeb IGenericView.<\/p>\n<p>public interface IListSelectionView : IGenericView<\/p>\n<p>{<\/p>\n<p>\/\/ Tr\u1ea3 v\u1ec1 ho\u1eb7c thi\u1ebft l\u1eadp danh s\u00e1ch c\u00e1c \u0111\u1ed1i t\u01b0\u1ee3ng c\u1ee7a view<\/p>\n<p>IList ListItem { set; get; }<\/p>\n<p>&nbsp;<\/p>\n<p>\/\/ Tr\u1ea3 v\u1ec1 danh s\u00e1ch c\u00e1c \u0111\u1ed1i t\u01b0\u1ee3ng \u0111\u01b0\u1ee3c l\u1ef1a ch\u1ecdn tr\u00ean view<\/p>\n<p>IList SelectedItems { get; }<\/p>\n<p>&nbsp;<\/p>\n<p>\/\/ S\u1ef1 ki\u1ec7n ph\u00e1t sinh khi c\u00e1c h\u1ea1ng m\u1ee5c d\u1eef li\u1ec7u \u0111\u01b0\u1ee3c l\u1ef1a ch\u1ecdn<\/p>\n<p>event EventHandler OnSelectEventHandler;<\/p>\n<p>}<\/p>\n<p>Ng\u01b0\u1eddi ph\u00e1t tri\u1ec3n c\u00f3 th\u1ec3 \u0111\u1ecbnh ngh\u0129a ra c\u00e1c giao di\u1ec7n m\u1edbi t\u00f9y theo nhu c\u1ea7u ho\u1eb7c k\u1ebf th\u1eeba t\u1eeb c\u00e1c giao di\u1ec7n tr\u00ean.<\/p>\n<p><em>V\u00ed d\u1ee5:<\/em> C\u00f3 m\u1ed9t form danh s\u00e1ch ng\u01b0\u1eddi d\u00f9ng v\u00e0 s\u1eed d\u1ee5ng \u0111\u1ec3 l\u1ef1a ch\u1ecdn ra m\u1ed9t s\u1ed1 ng\u01b0\u1eddi d\u00f9ng t\u1eeb danh s\u00e1ch \u0111\u00f3, ta \u0111\u1ecbnh ngh\u0129a giao di\u1ec7n IUserSelectionView k\u1ebf th\u1eeba t\u1eeb giao di\u1ec7n IListSelectionView, \u0111\u1ecbnh ngh\u0129a th\u00eam m\u1ed9t s\u1ed1 thu\u1ed9c t\u00ednh c\u1ea7n thi\u1ebft kh\u00e1c v\u00e0 thi h\u00e0nh giao di\u1ec7n n\u00e0y cho form.<\/p>\n<p>public interface IUserSelectionView : <strong>IListSelectionView<\/strong><\/p>\n<p>Thi h\u00e0nh giao di\u1ec7n cho form:<\/p>\n<p>public partial class dlgUser : Form, <strong>IUserSelectionView<\/strong><\/p>\n<p><strong>2.2.1.4\u00a0 L\u1edbp t\u1ed5ng qu\u00e1t GenericPresenter <\/strong><\/p>\n<p>L\u1edbp ch\u1ee9a c\u00e1c ph\u01b0\u01a1ng th\u1ee9c ph\u1ed5 bi\u1ebfn khi th\u1ef1c hi\u1ec7n c\u00e1c thao t\u00e1c x\u1eed l\u00fd tr\u00ean danh s\u00e1ch. Ng\u01b0\u1eddi ph\u00e1t tri\u1ec3n c\u00f3 th\u1ec3 override c\u00e1c ph\u01b0\u01a1ng th\u1ee9c n\u00e0y t\u00f9y theo nhu c\u1ea7u s\u1eed d\u1ee5ng.<\/p>\n<p>V\u00ed d\u1ee5 t\u1ea1o presenter k\u1ebf th\u1eeba t\u1eeb GenericPresenter, m\u1ed7i presenter g\u1eafn v\u1edbi view m\u00e0 n\u00f3 \u0111i\u1ec1u khi\u1ec3n:<\/p>\n<p>public class UserPresenter : <strong>GenericPresenter<\/strong><\/p>\n<p>Kh\u1edfi t\u1ea1o \u0111\u1ed1i t\u01b0\u1ee3ng UserPresenter t\u1eeb view nh\u01b0 sau:<\/p>\n<p>public partial class frmUser : Form, <strong>IUserView<\/strong><\/p>\n<p>{<\/p>\n<p>private UserPresenter presenter;<\/p>\n<p>&nbsp;<\/p>\n<p>private void frmUser_Load(object sender, EventArgs e)<\/p>\n<p>{<\/p>\n<p>\/\/ Kh\u1edfi t\u1ea1o \u0111\u1ed1i t\u01b0\u1ee3ng presenter<\/p>\n<p>presenter = new UserPresenter();<\/p>\n<p>\/\/ G\u1eafn tham chi\u1ebfu c\u1ee7a form th\u1ef1c thi giao di\u1ec7n cho presenter<\/p>\n<p>presenter.View = this;<\/p>\n<p><strong>2.2.1.4.1\u00a0\u00a0 Thu\u1ed9c t\u00ednh View<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3:<\/em> Tr\u1ea3 v\u1ec1 ho\u1eb7c thi\u1ebft l\u1eadp tham chi\u1ebfu \u0111\u1ebfn view g\u1eafn v\u1edbi presenter. Thao t\u00e1c g\u00e1n gi\u00e1 tr\u1ecb cho thu\u1ed9c t\u00ednh View g\u1ecdi ph\u01b0\u01a1ng th\u1ee9c OnViewSet.<\/p>\n<p><em>C\u00fa ph\u00e1p: <\/em><\/p>\n<p>TView View { get; set; }<\/p>\n<p><em>V\u00ed d\u1ee5:<\/em> Thi\u1ebft l\u1eadp gi\u00e1 tr\u1ecb View cho presenter.<\/p>\n<p>presenter = new UserSelectionPresenter();<\/p>\n<p>presenter.View = this;<\/p>\n<p><strong>2.2.1.4.2\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c OnViewSet<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3:<\/em> Ph\u01b0\u01a1ng th\u1ee9c \u0111\u01b0\u1ee3c g\u1ecdi khi thu\u1ed9c t\u00ednh view c\u1ee7a presenter \u0111\u01b0\u1ee3c g\u00e1n gi\u00e1 tr\u1ecb (xem 2.2.1.4.1).<\/p>\n<p><em>C\u00fa ph\u00e1p:<\/em> public abstract void OnViewSet();<\/p>\n<p><em>V\u00ed d\u1ee5:<\/em><\/p>\n<p>public <strong>override<\/strong> void OnViewSet()<\/p>\n<p>{<\/p>\n<p>\/\/ Kh\u1edfi t\u1ea1o d\u1ecbch v\u1ee5 x\u1eed l\u00fd d\u1eef li\u1ec7u<\/p>\n<p>service = UserGroupService.Instance;<\/p>\n<p>\/\/ \u0110\u0103ng k\u00fd h\u00e0m nh\u1eadn th\u00f4ng b\u00e1o m\u1ed7i khi d\u1eef li\u1ec7u c\u00f3 s\u1ef1 thay \u0111\u1ed5i<\/p>\n<p>service.DataChanged += new DataChangeHandler(FillData);<\/p>\n<p>\/\/ \u0110\u0103ng k\u00fd c\u00e1c h\u00e0m x\u1eed l\u00fd s\u1ef1 ki\u1ec7n<\/p>\n<p>RegisterEvents();<\/p>\n<p>\/\/ \u0110i\u1ec1n th\u00f4ng tin v\u00e0o giao di\u1ec7n trong l\u1ea7n \u0111\u1ea7u ch\u1ea1y \u1ee9ng d\u1ee5ng<\/p>\n<p>FillData();<\/p>\n<p>}<\/p>\n<p><strong>2.2.1.4.3\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c RegisterEvents<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3:<\/em> \u0110\u0103ng k\u00fd c\u00e1c ph\u01b0\u01a1ng th\u1ee9c x\u1eed l\u00fd s\u1ef1 ki\u1ec7n x\u1ea3y ra tr\u00ean view. C\u00f3 s\u1eb5n b\u1ed1n\u00a0 s\u1ef1 ki\u1ec7n th\u01b0\u1eddng g\u1eb7p l\u00e0 t\u1ea1o m\u1edbi, ch\u1ec9nh s\u1eeda, x\u00f3a b\u1ecf v\u00e0 l\u1ef1a ch\u1ecdn h\u1ea1ng m\u1ee5c d\u1eef li\u1ec7u, th\u00f4ng th\u01b0\u1eddng v\u1edbi view d\u1eabn xu\u1ea5t t\u1eeb IListManipulationView th\u00ec s\u1eed d\u1ee5ng c\u1ea3 b\u1ed1n s\u1ef1 ki\u1ec7n tr\u00ean, c\u00f2n view d\u1eabn xu\u1ea5t t\u1eeb IListSelectiontionView th\u00ec ch\u1ec9 \u0111\u0103ng k\u00fd s\u1ef1 ki\u1ec7n OnSelectEventHandler.<\/p>\n<p><em>C\u00fa ph\u00e1p: <\/em>public virtual void RegisterEvents();<\/p>\n<p><em>V\u00ed d\u1ee5:<\/em><\/p>\n<p>public override void RegisterEvents()<\/p>\n<p>{<\/p>\n<p>View.OnAddEventHandler += new EventHandler(OnAddEventHandler);<\/p>\n<p>View.OnSaveEventHandler += new EventHandler(OnSaveEventHandler);<\/p>\n<p>View.OnDeleteEventHandler += new EventHandler(OnDeleteEventHandler);<\/p>\n<p>View.OnSelectEventHandler += new EventHandler(OnSelectEventHandler);<\/p>\n<p>}<\/p>\n<p><strong>2.2.1.4.4\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c OnAddEventHandler<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3:<\/em> X\u1eed l\u00fd s\u1ef1 ki\u1ec7n t\u1ea1o h\u1ea1ng m\u1ee5c d\u1eef li\u1ec7u m\u1edbi tr\u00ean view.<\/p>\n<p><em>C\u00fa ph\u00e1p: <\/em>public virtual void OnAddEventHandler;<\/p>\n<p><em>V\u00ed d\u1ee5:<\/em><\/p>\n<p>public override void OnAddEventHandler(object sender, EventArgs e)<\/p>\n<p>{<\/p>\n<p>userService.Insert(View.NewItem);<\/p>\n<p>}<\/p>\n<p><strong>2.2.1.4.5\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c OnSaveEventHandler<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3:<\/em> X\u1eed l\u00fd s\u1ef1 ki\u1ec7n l\u01b0u th\u00f4ng tin h\u1ea1ng m\u1ee5c tr\u00ean view.<\/p>\n<p><em>C\u00fa ph\u00e1p:<\/em> public virtual void OnSaveEventHandler;<\/p>\n<p><em>V\u00ed d\u1ee5:<\/em><\/p>\n<p>public override void OnSaveEventHandler(object sender, EventArgs e)<\/p>\n<p>{<\/p>\n<p>userService.Update(View.CurrentItem, &#8220;UserID=&#8221; + View.CurrentItem.UserID);<\/p>\n<p>}<\/p>\n<p><strong>2.2.1.4.6\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c OnDeleteEventHandler<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3<\/em>: X\u1eed l\u00fd s\u1ef1 ki\u1ec7n x\u00f3a b\u1ecf h\u1ea1ng m\u1ee5c d\u1eef li\u1ec7u tr\u00ean view.<\/p>\n<p><em>C\u00fa ph\u00e1p:<\/em> public virtual void OnDeleteEventHandler;<\/p>\n<p><em>V\u00ed d\u1ee5:<\/em><\/p>\n<p>public override void OnDeleteEventHandler(object sender, EventArgs e)<\/p>\n<p>{<\/p>\n<p>userService.Delete(View.SelectedItems);<\/p>\n<p>}<\/p>\n<p><strong>2.2.1.4.7\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c OnSelectEventHandler<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3:<\/em> X\u1eed l\u00fd s\u1ef1 ki\u1ec7n l\u1ef1a ch\u1ecdn h\u1ea1ng m\u1ee5c d\u1eef li\u1ec7u tr\u00ean view<\/p>\n<p><em>C\u00fa ph\u00e1p:<\/em> public virtual void OnSelectEventHandler;<\/p>\n<p><em>V\u00ed d\u1ee5:<\/em><\/p>\n<p>public override void OnSelectEventHandler(object sender, EventArgs e)<\/p>\n<p>{<\/p>\n<p>userService.AddToGroup(View.CurrentGroup, View.SelectedItems);<\/p>\n<p>}<\/p>\n<p><strong>2.2.2\u00a0\u00a0\u00a0\u00a0\u00a0 T\u1ea7ng Data<\/strong><\/p>\n<p><strong>2.2.2.1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Giao di\u1ec7n IGenericService <\/strong><\/p>\n<p>Giao di\u1ec7n g\u1ed1c, v\u1edbi m\u1ee5c \u0111\u00edch cho c\u00e1c giao di\u1ec7n kh\u00e1c d\u1eabn xu\u1ea5t.<strong> <\/strong><\/p>\n<p>public interface IGenericService<\/p>\n<p>{<\/p>\n<p>}<\/p>\n<p><strong>2.2.2.2\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Giao di\u1ec7n IGenericDataAccessService <\/strong><\/p>\n<p>\u0110\u1ecbnh ngh\u0129a c\u00e1c ph\u01b0\u01a1ng th\u1ee9c x\u1eed l\u00fd d\u1eef li\u1ec7u th\u00f4ng d\u1ee5ng, d\u1eabn xu\u1ea5t t\u1eeb IGenericService. G\u1ed3m c\u00e1c ph\u01b0\u01a1ng th\u1ee9c c\u01a1 b\u1ea3n nh\u01b0 truy v\u1ea5n, c\u00e1c thao t\u00e1c th\u00eam m\u1edbi, c\u1eadp nh\u1eadt, x\u00f3a b\u1ecf \u0111\u1ed1i t\u01b0\u1ee3ng v\u00e0 g\u1eedi th\u00f4ng b\u00e1o m\u1ed7i khi d\u1eef li\u1ec7u c\u00f3 s\u1ef1 thay \u0111\u1ed5i.<\/p>\n<p><strong>2.2.2.3\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 L\u1edbp t\u1ed5ng qu\u00e1t GenericDataAccessService <\/strong><\/p>\n<p>L\u1edbp t\u1ed5ng qu\u00e1t n\u00e0y thi h\u00e0nh \u00a0t\u1eeb giao di\u1ec7n IGenericDataAccessService.<\/p>\n<p><strong>2.2.2.3.1\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c kh\u1edfi t\u1ea1o \u0111\u1ed1i t\u01b0\u1ee3ng GenericDataAccessService<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3:<\/em> Ph\u01b0\u01a1ng th\u1ee9c kh\u1edfi t\u1ea1o \u0111\u1ed1i t\u01b0\u1ee3ng (constructor).<\/p>\n<p><em>C\u00fa ph\u00e1p:<\/em> GenericDataAccessService(System.Data.Linq.DataContext dataContext)<\/p>\n<p><em>Tham s\u1ed1:<\/em> \u0110\u1ed1i t\u01b0\u1ee3ng Linq.LINQ.DataContext. Th\u00f4ng b\u00e1o bi\u1ec7t l\u1ec7 ArgumentNullException n\u1ebfu tham s\u1ed1 b\u1eb1ng Null. Tham s\u1ed1 c\u1ee7a \u0111\u1ed1i t\u01b0\u1ee3ng LINQ.DataContext l\u00e0 chu\u1ed7i k\u1ebft n\u1ed1i t\u1edbi c\u01a1 s\u1edf d\u1eef li\u1ec7u.<\/p>\n<p><em>Tr\u1ea3 v\u1ec1:<\/em> \u0110\u1ed1i t\u01b0\u1ee3ng GenericDataAccessService<\/p>\n<p><em>V\u00ed d\u1ee5:<\/em><\/p>\n<p>public class UserService : GenericDataAccessService, IUserService<\/p>\n<p>{<\/p>\n<p>\/\/ Constructor (strConnectionString l\u00e0 chu\u1ed7i k\u1ebft n\u1ed1i t\u1edbi c\u01a1 s\u1edf d\u1eef li\u1ec7u)<\/p>\n<p>public UserService() : base(new MvpExampleDataContext(strConnectionString)) { }<\/p>\n<p><strong>2.2.2.3.2\u00a0\u00a0 Thu\u1ed9c t\u00ednh DataContext<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>Tr\u1ea3 v\u1ec1 tham chi\u1ebfu DataContext c\u1ee7a \u0111\u1ed1i t\u01b0\u1ee3ng GenericDataAccessService.<\/p>\n<p><em>Tr\u1ea3 v\u1ec1:<\/em> \u0110\u1ed1i t\u01b0\u1ee3ng LINQ.DataContext<\/p>\n<p><em>V\u00ed d\u1ee5: <\/em><\/p>\n<p>\/\/ Vi\u1ebft ra chu\u1ed7i k\u1ebft n\u1ed1i \u0111\u1ebfn c\u01a1 s\u1edf d\u1eef li\u1ec7u<\/p>\n<p>Console.WriteLine(DataContext.Connection.ConnectionString);<\/p>\n<p><strong>2.2.2.3.3\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c SelectAll<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3:<\/em> Tr\u1ea3 v\u1ec1 t\u1ea5t c\u1ea3 \u0111\u1ed1i t\u01b0\u1ee3ng c\u1ee7a m\u1ed9t l\u1edbp.<\/p>\n<p><em>C\u00fa ph\u00e1p:<\/em> virtual IList SelectAll(string orderByExpression)<\/p>\n<p><em>Tham s\u1ed1:<\/em><\/p>\n<p>orderByExpression: Th\u1ee9 t\u1ef1 s\u1eafp x\u1ebfp k\u1ebft qu\u1ea3 truy v\u1ea5n, g\u1ed3m t\u00ean tr\u01b0\u1eddng v\u00e0 th\u1ee9 t\u1ef1 s\u1eafp x\u1ebfp ASC ho\u1eb7c DESC, ho\u1eb7c \u0111\u1ec3 chu\u1ed7i r\u1ed7ng n\u1ebfu kh\u00f4ng c\u1ea7n s\u1eafp x\u1ebfp.<\/p>\n<p><em>Tr\u1ea3 v\u1ec1:<\/em> Danh s\u00e1ch c\u00e1c \u0111\u1ed1i t\u01b0\u1ee3ng.<\/p>\n<p><em>V\u00ed d\u1ee5:<\/em> IList users = SelectAll(\u201cUserName ASC\u201d);<\/p>\n<p><strong>2.2.2.3.4\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c SelectBy<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>Truy v\u1ea5n \u0111\u1ed1i t\u01b0\u1ee3ng theo \u0111i\u1ec1u ki\u1ec7n l\u1ecdc.<\/p>\n<p><em>C\u00fa ph\u00e1p:\u00a0 <\/em><\/p>\n<p>virtual IList SelectBy(string searchCondition, string orderByExpression)<\/p>\n<p><em>Tham s\u1ed1: <\/em><\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 searchCondition: \u0110i\u1ec1u ki\u1ec7n l\u1ecdc.<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 orderByExpression: Th\u1ee9 t\u1ef1 s\u1eafp x\u1ebfp k\u1ebft qu\u1ea3 truy v\u1ea5n, g\u1ed3m t\u00ean tr\u01b0\u1eddng v\u00e0 th\u1ee9 t\u1ef1 s\u1eafp x\u1ebfp ASC ho\u1eb7c DESC, ho\u1eb7c \u0111\u1ec3 chu\u1ed7i r\u1ed7ng n\u1ebfu kh\u00f4ng c\u1ea7n s\u1eafp x\u1ebfp.<\/p>\n<p><em>V\u00ed d\u1ee5: <\/em>userService.SelectBy(&#8220;GroupID = 1&#8221;, &#8220;UserName ASC&#8221;);<\/p>\n<p><strong>2.2.2.3.5\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c SelectBy<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>Truy v\u1ea5n \u0111\u1ed1i t\u01b0\u1ee3ng theo \u0111i\u1ec1u ki\u1ec7n l\u1ecdc.<\/p>\n<p><em>C\u00fa ph\u00e1p:\u00a0 <\/em><\/p>\n<p>IList SelectBy(int fromItemNumber, int numberOfItems, string searchCondition, string orderByExpression)<\/p>\n<p><em>Tham s\u1ed1: <\/em><\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fromItemNumber: B\u1eaft \u0111\u1ea7u ch\u1ecdn t\u1eeb \u0111\u1ed1i t\u01b0\u1ee3ng th\u1ee9 fromItemNumber.<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 numberOfItems: Tr\u1ea3 v\u1ec1 s\u1ed1 l\u01b0\u1ee3ng numberOfItems \u0111\u1ed1i t\u01b0\u1ee3ng.<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 searchCondition: \u0110i\u1ec1u ki\u1ec7n l\u1ecdc.<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 orderByExpression: Th\u1ee9 t\u1ef1 s\u1eafp x\u1ebfp k\u1ebft qu\u1ea3 truy v\u1ea5n, g\u1ed3m t\u00ean tr\u01b0\u1eddng v\u00e0 th\u1ee9 t\u1ef1 s\u1eafp x\u1ebfp ASC ho\u1eb7c DESC, ho\u1eb7c \u0111\u1ec3 chu\u1ed7i r\u1ed7ng n\u1ebfu kh\u00f4ng c\u1ea7n s\u1eafp x\u1ebfp.<\/p>\n<p><em>V\u00ed d\u1ee5: <\/em>userService.SelectBy(1, 20, &#8220;GroupID Null&#8221;, &#8220;UserName DESC&#8221;);<\/p>\n<p><strong>2.2.2.3.6\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c Delete<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>X\u00f3a b\u1ecf \u0111\u1ed1i t\u01b0\u1ee3ng theo \u0111i\u1ec1u ki\u1ec7n l\u1ecdc.<\/p>\n<p><em>C\u00fa ph\u00e1p:\u00a0 <\/em>virtual void Delete(string searchCondition)<\/p>\n<p><em>Tham s\u1ed1: <\/em><\/p>\n<p>searchCondition: \u0110i\u1ec1u ki\u1ec7n l\u1ecdc.<\/p>\n<p><em>V\u00ed d\u1ee5: <\/em>userService.Delete(&#8220;GroupID = Null&#8221;);<\/p>\n<p><strong>2.2.2.3.7\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c Delete<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>X\u00f3a b\u1ecf m\u1ed9t t\u1eadp c\u00e1c \u0111\u1ed1i t\u01b0\u1ee3ng.<\/p>\n<p><em>C\u00fa ph\u00e1p:\u00a0 <\/em>virtual void Delete(IList entities)<\/p>\n<p><em>Tham s\u1ed1: <\/em><\/p>\n<p>entities: Danh s\u00e1ch c\u00e1c \u0111\u1ed1i t\u01b0\u1ee3ng c\u1ea7n x\u00f3a b\u1ecf.<\/p>\n<p><em>V\u00ed d\u1ee5: <\/em>userService.Delete(View.SelectedItems);<\/p>\n<p><strong>2.2.2.3.8\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c DeleteAll<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>X\u00f3a b\u1ecf to\u00e0n b\u1ed9 c\u00e1c \u0111\u1ed1i t\u01b0\u1ee3ng c\u1ee7a m\u1ed9t l\u1edbp.<\/p>\n<p><em>C\u00fa ph\u00e1p:\u00a0 <\/em>virtual void DeleteAll()<\/p>\n<p><em>V\u00ed d\u1ee5: <\/em>userService.DeleteAll();<\/p>\n<p><strong>2.2.2.3.9\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c Insert<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>Th\u00eam m\u1edbi m\u1ed9t \u0111\u1ed1i t\u01b0\u1ee3ng.<\/p>\n<p><em>C\u00fa ph\u00e1p<\/em>: virtual TEntity Insert(TEntity entity)<\/p>\n<p><em>Tham s\u1ed1: <\/em><\/p>\n<p>entity: \u0110\u1ed1i t\u01b0\u1ee3ng m\u1edbi.<\/p>\n<p><em>V\u00ed d\u1ee5: <\/em><\/p>\n<p>User user = new User() { UserName = &#8220;X&#8221; };<\/p>\n<p>userService.Insert(user);<\/p>\n<p><strong>2.2.2.3.10\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c Update<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>Override ph\u01b0\u01a1ng th\u1ee9c n\u00e0y \u0111\u1ec3 th\u1ef1c hi\u1ec7n c\u1eadp nh\u1eadt th\u00f4ng tin m\u1ed9t \u0111\u1ed1i t\u01b0\u1ee3ng.<\/p>\n<p><em>C\u00fa ph\u00e1p: <\/em>virtual void Update(TEntity entity, string searchCondition)<\/p>\n<p><em>Tham s\u1ed1: <\/em><\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 entity: \u0110\u1ed1i t\u01b0\u1ee3ng ch\u1ee9a th\u00f4ng tin c\u1eadp nh\u1eadt.<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 searchCondition: \u0110i\u1ec1u ki\u1ec7n l\u1ecdc.<\/p>\n<p><em>V\u00ed d\u1ee5: <\/em><\/p>\n<p>user.UserName = &#8220;Y&#8221;;<\/p>\n<p>userService.Update(user, &#8220;UserID = 1&#8221;);<\/p>\n<p><strong>2.2.2.3.11\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c NotifyDataChanged<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>G\u1ecdi ph\u01b0\u01a1ng th\u1ee9c n\u00e0y \u0111\u1ec3 th\u00f4ng b\u00e1o m\u1ed7i khi d\u1eef li\u1ec7u v\u1eeba c\u00f3 s\u1ef1 thay \u0111\u1ed5i. Ph\u01b0\u01a1ng th\u1ee9c n\u00e0y k\u00edch ho\u1ea1t s\u1ef1 ki\u1ec7n DataChanged tr\u00ean c\u00e1c presenter v\u00e0 g\u1ecdi ph\u01b0\u01a1ng th\u1ee9c FillData c\u1eadp nh\u1eadt l\u1ea1i d\u1eef li\u1ec7u tr\u00ean to\u00e0n b\u1ed9 c\u00e1c presenter c\u00f3 thi h\u00e0nh giao di\u1ec7n IObserver.<\/p>\n<p><em>C\u00fa ph\u00e1p:\u00a0 <\/em>void NotifyDataChanged()<\/p>\n<p><em>V\u00ed d\u1ee5: <\/em><\/p>\n<p>UserGroup group = DataContext.GetTable().Where(obj =&gt; obj.GroupID == entity.GroupID).SingleOrDefault();<\/p>\n<p>IList users = SelectBy(searchCondition, &#8220;&#8221;);<\/p>\n<p>foreach (User user in users)<\/p>\n<p>{<\/p>\n<p>user.UserName = entity.UserName;<\/p>\n<p>user.UserGroup = group;<\/p>\n<p>}<\/p>\n<p>DataContext.SubmitChanges();<\/p>\n<p><strong>NotifyDataChanged<\/strong>();<\/p>\n<p><strong>2.2.2.3.12\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c ClearCache<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>X\u00f3a b\u1ed9 \u0111\u1ec7m d\u1eef li\u1ec7u.<\/p>\n<p><em>C\u00fa ph\u00e1p:\u00a0 <\/em>static void ClearCache()<\/p>\n<p><strong>2.2.2.3.13\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 H\u00e0m delegate DataChangeHandler<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>\u0110\u0103ng k\u00fd nh\u1eadn s\u1ef1 ki\u1ec7n m\u1ed7i khi d\u1eef li\u1ec7u c\u00f3 s\u1ef1 thay \u0111\u1ed5i.<\/p>\n<p><em>V\u00ed d\u1ee5:<\/em> \u0110\u0103ng k\u00fd m\u1ed9t h\u00e0m c\u00f3 t\u00ean FillData, ph\u01b0\u01a1ng th\u1ee9c n\u00e0y \u0111\u01b0\u1ee3c k\u00edch ho\u1ea1t m\u1ed7i khi d\u1eef li\u1ec7u c\u00f3 s\u1ef1 thay \u0111\u1ed5i.<\/p>\n<p>public override void OnViewSet()<\/p>\n<p>{<\/p>\n<p>service = new UserGroupService();<\/p>\n<p>service.DataChanged += new DataChangeHandler(FillData);<\/p>\n<p>&#8230;<\/p>\n<p>&nbsp;<\/p>\n<p>\/\/ Ph\u01b0\u01a1ng th\u1ee9c n\u00e0y th\u1ef1c hi\u1ec7n c\u1eadp nh\u1eadt l\u1ea1i th\u00f4ng tin tr\u00ean view<\/p>\n<p>private void FillData()<\/p>\n<p>{<\/p>\n<p>View.ListItem = service.SelectAll(&#8220;GroupName ASC&#8221;);<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>C\u00f3 hai c\u00e1ch ch\u1eb7n b\u1eaft s\u1ef1 ki\u1ec7n d\u1eef li\u1ec7u c\u00f3 s\u1ef1 thay \u0111\u1ed5i, d\u00f9ng h\u00e0m delegate DataChangeHandler ho\u1eb7c d\u00f9ng ph\u01b0\u01a1ng th\u1ee9c AttachObserver. \u00a0S\u1ef1 kh\u00e1c bi\u1ec7t c\u1ee7a hai ph\u01b0\u01a1ng c\u00e1ch th\u1ee9c n\u00e0y l\u00e0:<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 D\u00f9ng h\u00e0m delegate: Ch\u1ec9 presenter n\u00e0o \u0111\u0103ng k\u00fd m\u1edbi nh\u1eadn \u0111\u01b0\u1ee3c th\u00f4ng b\u00e1o.<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 D\u00f9ng AttachObserver: T\u1ea5t c\u1ea3 c\u00e1c presenter n\u00e0o c\u00f3 \u0111\u0103ng k\u00fd s\u1ebd c\u00f9ng nh\u1eadn \u0111\u01b0\u1ee3c th\u00f4ng b\u00e1o.<\/p>\n<p><strong>2.2.2.4\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Giao di\u1ec7n IObserver<\/strong><\/p>\n<p>Giao di\u1ec7n IObserver ch\u1ec9 \u0111\u1ecbnh ngh\u0129a m\u1ed9t ph\u01b0\u01a1ng th\u1ee9c duy nh\u1ea5t l\u00e0 FillData, ph\u01b0\u01a1ng th\u1ee9c \u0111\u01b0\u1ee3c g\u1ecdi m\u1ed7i khi l\u1edbp \u0111\u1ed1i t\u01b0\u1ee3ng Subject c\u00f3 s\u1ef1 thay \u0111\u1ed5i d\u1eef li\u1ec7u,\u00a0 d\u00f9ng \u0111\u1ec3 th\u1ef1c hi\u1ec7n c\u00e1c thao t\u00e1c c\u1eadp nh\u1eadt l\u1ea1i giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng.<\/p>\n<p>public interface IObserver<\/p>\n<p>{<\/p>\n<p>void FillData();<\/p>\n<p>}<\/p>\n<p><strong>2.2.2.5\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Giao di\u1ec7n ISubject <\/strong><\/p>\n<p>\u0110\u1ecbnh ngh\u0129a c\u00e1c ph\u01b0\u01a1ng th\u1ee9c cho l\u1edbp Subject thi h\u00e0nh \u00a0(d\u1ef1a theo Observer pattern).<\/p>\n<p><strong>2.2.2.6\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 L\u1edbp t\u1ed5ng qu\u00e1t Subject <\/strong><\/p>\n<p>L\u1edbp \u0111\u1ed1i t\u01b0\u1ee3ng thi h\u00e0nh \u00a0giao ti\u1ebfp ISubject.<\/p>\n<p><strong>2.2.2.6.1\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c AttachObserver<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>\u0110\u0103ng k\u00fd l\u00e0m m\u1ed9t observer, l\u1edbp \u0111\u0103ng k\u00fd s\u1ebd nh\u1eadn \u0111\u01b0\u1ee3c th\u00f4ng b\u00e1o m\u1ed7i khi c\u00f3 s\u1ef1 thay \u0111\u1ed5i d\u1eef li\u1ec7u t\u1eeb data service (xem m\u1ee5c 2.2.2.3.14).<\/p>\n<p><em>C\u00fa ph\u00e1p<\/em>: void AttachObserver(IObserver observer)<\/p>\n<p><em>Tham s\u1ed1: <\/em><\/p>\n<p>observer: T\u00ean l\u1edbp \u0111\u1ed1i t\u01b0\u1ee3ng thi h\u00e0nh giao ti\u1ebfp IObserver.<\/p>\n<p><em>V\u00ed d\u1ee5: <\/em><\/p>\n<p>public class UserPresenter : GenericPresenter, IObserver<\/p>\n<p>{<\/p>\n<p>private IUserService userService;<\/p>\n<p>&nbsp;<\/p>\n<p>public override void OnViewSet()<\/p>\n<p>{<\/p>\n<p>\/\/ L\u1ea5y single instance c\u1ee7a UserService<\/p>\n<p>userService = UserService.Instance;<\/p>\n<p>\/\/ D\u0103ng k\u00fd presenter n\u00e0y l\u00e0 observer nh\u1eadn th\u00f4ng b\u00e1o t\u1eeb data service.<\/p>\n<p>\/\/ H\u00e0m FillData t\u1ef1 \u0111\u1ed9ng \u0111\u01b0\u1ee3c g\u1ecdi m\u1ed7i khi d\u1eef li\u1ec7u c\u00f3 s\u1ef1 thay \u0111\u1ed5i.<\/p>\n<p>userService.AttachObserver(this);<\/p>\n<p><strong>2.2.2.6.2\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c DetachObserver<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>H\u1ee7y \u0111\u0103ng k\u00fd m\u1ed9t observer.<\/p>\n<p><em>C\u00fa ph\u00e1p:\u00a0 <\/em>void DetachObserver(IObserver observer)<\/p>\n<p><em>Tham s\u1ed1: <\/em><\/p>\n<p>observer: T\u00ean l\u1edbp \u0111\u1ed1i t\u01b0\u1ee3ng thi h\u00e0nh giao ti\u1ebfp IObserver.<\/p>\n<p><em>V\u00ed d\u1ee5:<\/em><strong> <\/strong>userService.DetachObserver(this);<\/p>\n<p><strong>2.2.2.6.3\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c DetachAll<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>H\u1ee7y \u0111\u0103ng k\u00fd to\u00e0n b\u1ed9 observer.<\/p>\n<p><em>C\u00fa ph\u00e1p:\u00a0 <\/em>void DetachAll()<\/p>\n<p><strong>2.2.2.6.4\u00a0\u00a0 Ph\u01b0\u01a1ng th\u1ee9c NotifyObservers<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>Th\u00f4ng b\u00e1o d\u1eef li\u1ec7u c\u00f3 s\u1ef1 thay \u0111\u1ed5i t\u1edbi c\u00e1c observer \u0111\u00e3 \u0111\u0103ng k\u00fd<\/p>\n<p><em>C\u00fa ph\u00e1p:\u00a0 <\/em>void NotifyObservers()<\/p>\n<p><em>V\u00ed d\u1ee5: <\/em>userService.NotifyObservers();<\/p>\n<p><strong>2.2.2.6.5\u00a0\u00a0 Thu\u1ed9c t\u00ednh Observers<\/strong><\/p>\n<p><em>M\u00f4 t\u1ea3: <\/em>Tr\u1ea3 v\u1ec1 danh s\u00e1ch c\u00e1c observer \u0111\u00e3 \u0111\u0103ng k\u00fd<\/p>\n<p><em>Tr\u1ea3 v\u1ec1:\u00a0 <\/em>IList<\/p>\n<p><em>V\u00ed d\u1ee5: <\/em><\/p>\n<p>\/\/ T\u1ed5ng s\u1ed1 c\u00e1c observer \u0111\u01b0\u1ee3c \u0111\u0103ng k\u00fd<\/p>\n<p>Console.WriteLine(Observers.Count);<\/p>\n<p>&nbsp;<\/p>\n<p><strong>3\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Ngu\u1ed3n th\u00f4ng tin tham kh\u1ea3o<\/strong><\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Ki\u1ebfn tr\u00fac Model-View-Presenter trong .NET (<a href=\"http:\/\/www.facebook.com\/l.php?u=http%3A%2F%2Fwww.fpt.edu.vn%2Fstory%2Fkien-truc-model-view-presenter-trong-net&amp;h=4AQEge8C_&amp;s=1\" target=\"_blank\">http:\/\/www.fpt.edu.vn\/story\/kien-truc-model-view-presenter-trong-net<\/a>)<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Creating a generic Model-View-Presenter\u00a0framework (<a href=\"http:\/\/www.facebook.com\/l.php?u=https%3A%2F%2Fdotnetchris.wordpress.com%2F2009%2F02%2F16%2Fcreating-a-generic-model-view-presenter-framework&amp;h=3AQFasreN&amp;s=1\" target=\"_blank\">https:\/\/dotnetchris.wordpress.com\/2009\/02\/16\/creating-a-generic-model-view-presenter-framework<\/a>)<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Smart Client Software Factory (<a href=\"http:\/\/www.facebook.com\/l.php?u=http%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fff648753.aspx&amp;h=nAQHfoED7&amp;s=1\" target=\"_blank\">http:\/\/msdn.microsoft.com\/en-us\/library\/ff648753.aspx<\/a>)<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 T\u00e0i li\u1ec7u LINQ b\u1ea3n ti\u1ebfng Vi\u1ec7t (<a href=\"http:\/\/www.facebook.com\/l.php?u=http%3A%2F%2Fcongthuong.googlecode.com%2Ffiles%2FLINQ%2520tieng%2520viet.pdf&amp;h=XAQE1t4WC&amp;s=1\" target=\"_blank\">http:\/\/congthuong.googlecode.com\/files\/LINQ%20tieng%20viet.pdf<\/a>)<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Dynamic LINQ (<a href=\"http:\/\/www.facebook.com\/l.php?u=http%3A%2F%2Fweblogs.asp.net%2Fscottgu%2Farchive%2F2008%2F01%2F07%2Fdynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx&amp;h=lAQH0SGzt&amp;s=1\" target=\"_blank\">http:\/\/weblogs.asp.net\/scottgu\/archive\/2008\/01\/07\/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx<\/a>)<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Unity Application Block (<a href=\"http:\/\/www.facebook.com\/l.php?u=http%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fhh237493.aspx&amp;h=vAQF4HYzd&amp;s=1\" target=\"_blank\">http:\/\/msdn.microsoft.com\/en-us\/library\/hh237493.aspx<\/a>)<\/p>\n<p>&nbsp;<\/p>\n<p><strong>4\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 V\u00ed d\u1ee5 s\u1eed d\u1ee5ng<\/strong><\/p>\n<p>T\u1ea1o hai l\u1edbp User v\u00e0 UserGroup v\u1edbi c\u00e1c thu\u1ed9c t\u00ednh v\u00e0 quan h\u1ec7 nh\u01b0 sau:<\/p>\n<p>Thi\u1ebft k\u1ebf c\u00e1c form cho \u0111\u1ed1i t\u01b0\u1ee3ng User v\u00e0 UserGroup v\u1edbi c\u00e1c thao t\u00e1c th\u00eam m\u1edbi, c\u1eadp nh\u1eadt v\u00e0 x\u00f3a b\u1ecf. Form UserGroup c\u00f3 th\u00eam ch\u1ee9c n\u0103ng ch\u1ecdn th\u00eam c\u00e1c th\u00e0nh vi\u00ean v\u00e0o nh\u00f3m ch\u1ec9 \u0111\u1ecbnh. C\u1ee5 th\u1ec3 c\u00f3 ba form nh\u01b0 sau:<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <em>frmUser<\/em> qu\u1ea3n l\u00fd danh s\u00e1ch ng\u01b0\u1eddi d\u00f9ng.<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <em>frmUserGroup<\/em> qu\u1ea3n l\u00fd danh s\u00e1ch nh\u00f3m ng\u01b0\u1eddi d\u00f9ng.<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <em>dlgUser<\/em> \u0111\u1ec3 l\u1ef1a ch\u1ecdn ra m\u1ed9t s\u1ed1 ng\u01b0\u1eddi d\u00f9ng t\u1eeb danh s\u00e1ch ng\u01b0\u1eddi d\u00f9ng.<\/p>\n<p>1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 T\u1ea1o m\u1ed9t solution v\u1edbi ba project t\u00ean l\u00e0 <em>UI<\/em>, <em>Bussiness<\/em> v\u00e0 <em>Data<\/em> (t\u00ean project t\u00f9y ch\u1ecdn) t\u01b0\u01a1ng \u1ee9ng v\u1edbi ba t\u1ea7ng View, Presenter v\u00e0 Model.<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Project <em>UI<\/em> ch\u1ee9a c\u00e1c form, l\u00e0 l\u1edbp giao di\u1ec7n t\u01b0\u01a1ng t\u00e1c v\u1edbi ng\u01b0\u1eddi ph\u00e1t tri\u1ec3n (view).<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Project <em>Business<\/em> ch\u1ee9a c\u00e1c l\u1edbp x\u1eed l\u00fd nghi\u1ec7p v\u1ee5 (business).<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Project <em>Data<\/em> ch\u1ee9a c\u00e1c l\u1edbp \u0111\u1ed1i t\u01b0\u1ee3ng d\u1eef li\u1ec7u v\u00e0 c\u00e1c l\u1edbp d\u1ecbch v\u1ee5 truy c\u1eadp d\u1eef li\u1ec7u (model).<\/p>\n<p>Th\u00eam tham chi\u1ebfu t\u1edbi th\u01b0 vi\u1ec7n MvpPattern v\u00e0o References c\u1ee7a ba project tr\u00ean.<\/p>\n<p>2\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Trong project Data s\u1eed d\u1ee5ng LINQ \u0111\u1ec3 \u00e1nh x\u1ea1 c\u00e1c b\u1ea3ng t\u1eeb c\u01a1 s\u1edf d\u1eef li\u1ec7u quan h\u1ec7 ra c\u00e1c \u0111\u1ed1i t\u01b0\u1ee3ng v\u00e0 \u0111\u1ec3 truy xu\u1ea5t c\u01a1 s\u1edf d\u1eef li\u1ec7u.<\/p>\n<ol start=\"1\">\n<li>Right click v\u00e0o th\u01b0 m\u1ee5c Data, ch\u1ecdn <em>Add New Item<\/em>, <em>LINQ to SQL Classes<\/em>, \u0111\u1eb7t t\u00ean cho file DBML.<\/li>\n<li>V\u00e0o menu <em>View<\/em>, ch\u1ecdn <em>Server Explorer<\/em>.<\/li>\n<li>Right click v\u00e0o <em>Data Connections<\/em>, ch\u1ecdn <em>Add Connection<\/em>, ch\u1ecdn t\u00ean m\u00e1y ch\u1ee7 v\u00e0 c\u01a1 s\u1edf d\u1eef li\u1ec7u.<\/li>\n<li>K\u00e9o hai b\u1ea3ng Users v\u00e0 UserGroups th\u1ea3 v\u00e0o file DBML.<\/li>\n<li>L\u01b0u file DBML, c\u00e1c l\u1edbp \u0111\u1ed1i t\u01b0\u1ee3ng \u0111\u01b0\u1ee3c t\u1ef1 \u0111\u1ed9ng sinh m\u00e3 trong file MvpExample.designer.cs, ng\u01b0\u1eddi ph\u00e1t tri\u1ec3n c\u00f3 th\u1ec3 ch\u1ec9nh s\u1eeda, b\u1ed5 sung th\u00eam m\u00e3 b\u1eb1ng c\u00e1ch right click v\u00e0o file DBML, ch\u1ecdn <em>View Code<\/em>.<\/li>\n<\/ol>\n<p>3\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Trong project <em>Data<\/em>, \u0111\u1ecbnh ngh\u0129a c\u00e1c giao di\u1ec7n v\u00e0 vi\u1ebft m\u00e3 x\u1eed l\u00fd cho t\u1ea7ng d\u1eef li\u1ec7u.<\/p>\n<p>Giao di\u1ec7n cho l\u1edbp UserService \u0111\u1ecbnh ngh\u0129a c\u00e1c ph\u01b0\u01a1ng th\u1ee9c thao t\u00e1c v\u1edbi l\u1edbp User.<\/p>\n<p>public interface IUserService : IGenericDataAccessService<\/p>\n<p>{<\/p>\n<p>\/\/ Th\u00eam c\u00e1c th\u00e0nh vi\u00ean v\u00e0o nh\u00f3m ng\u01b0\u1eddi d\u00f9ng<\/p>\n<p>void AddToGroup(UserGroup group, IList users);<\/p>\n<p>}<\/p>\n<p>Thi h\u00e0nh giao di\u1ec7n IUserService v\u00e0 vi\u1ebft m\u00e3 cho l\u1edbp UserService.<\/p>\n<p>public class UserService : GenericDataAccessService, <strong>IUserService<\/strong><\/p>\n<p>{<\/p>\n<p>\/\/ Constructor<\/p>\n<p>public UserService() : base(new MvpExampleDataContext(LocalConfig.ConnectionString)) { }<\/p>\n<p>Override c\u00e1c ph\u01b0\u01a1ng th\u1ee9c Insert, Update t\u01b0\u01a1ng \u1ee9ng.<\/p>\n<p>Giao di\u1ec7n cho l\u1edbp UserGroupService \u0111\u1ecbnh ngh\u0129a c\u00e1c ph\u01b0\u01a1ng th\u1ee9c thao t\u00e1c v\u1edbi l\u1edbp UserGroup.<\/p>\n<p>public interface IUserGroupService : IGenericDataAccessService<\/p>\n<p>{<\/p>\n<p>}<\/p>\n<p>Th\u1ef1c hi\u1ec7n c\u00e1c b\u01b0\u1edbc t\u01b0\u01a1ng t\u1ef1 nh\u01b0 v\u1edbi l\u1edbp UserService.<\/p>\n<p>4\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Trong project <em>Bussiness<\/em>, t\u1ea1o c\u00e1c giao di\u1ec7n t\u01b0\u01a1ng \u1ee9ng cho c\u00e1c form tr\u00ean.<\/p>\n<p>\u0110\u1ecbnh ngh\u0129a giao di\u1ec7n cho form frmUser v\u00e0 vi\u1ebft m\u00e3 cho presenter:<\/p>\n<p>public interface IUserView : IListManipulationView<\/p>\n<p>{<\/p>\n<p>IList GroupList { set; }<\/p>\n<p>UserGroup CurrentGroup { get; }<\/p>\n<p>}<\/p>\n<p>UserPresenter qu\u1ea3n l\u00fd giao di\u1ec7n IUserView.<\/p>\n<p>public class UserPresenter : <strong>GenericPresenter<\/strong>, IObserver<\/p>\n<p>{<\/p>\n<p>private IUserService userService;<\/p>\n<p>&nbsp;<\/p>\n<p>public override void OnViewSet()<\/p>\n<p>{<\/p>\n<p>userService = new UserService.Instance;<\/p>\n<p>userService.AttachObserver(this);<\/p>\n<p>&nbsp;<\/p>\n<p>groupService = UserGroupService.Instance;<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>public void FillData()<\/p>\n<p>{<\/p>\n<p>\/\/ C\u1eadp nh\u1eadt th\u00f4ng tin c\u1ee7a view \u1edf \u0111\u00e2y<\/p>\n<p>}<\/p>\n<p>\u0110\u1ecbnh ngh\u0129a giao di\u1ec7n cho h\u1ed9p tho\u1ea1i dlgUser v\u00e0 vi\u1ebft m\u00e3 cho presenter:<\/p>\n<p>public interface IUserSelectionView : IListSelectionView<\/p>\n<p>{<\/p>\n<p>UserGroup CurrentGroup { get; set; }<\/p>\n<p>}<\/p>\n<p>UserSelectionPresenter qu\u1ea3n l\u00fd giao di\u1ec7n IUserSelectionView.<\/p>\n<p>&nbsp;<\/p>\n<p>public class UserSelectionPresenter : <strong>GenericPresenter<\/strong><\/p>\n<p>{<\/p>\n<p>private IUserService userService;<\/p>\n<p>&nbsp;<\/p>\n<p>public override void OnViewSet()<\/p>\n<p>{<\/p>\n<p>userService = UserService.Instance;<\/p>\n<p>\u0110\u1ecbnh ngh\u0129a giao di\u1ec7n cho form frmUserGroup v\u00e0 vi\u1ebft m\u00e3 cho presenter:<\/p>\n<p>public interface IUserGroupView : IListManipulationView<\/p>\n<p>{<\/p>\n<p>}<\/p>\n<p>UserGroupPresenter qu\u1ea3n l\u00fd giao di\u1ec7n IUserGroupView. Ngo\u00e0i c\u00e1ch \u0111\u0103ng k\u00fd l\u00e0m m\u1ed9t observer, c\u00f2n c\u00e1ch kh\u00e1c l\u00e0 \u0111\u0103ng k\u00fd m\u1ed9t h\u00e0m nh\u1eadn s\u1ef1 ki\u1ec7n. Trong v\u00ed d\u1ee5 d\u01b0\u1edbi \u0111\u00e2y h\u00e0m c\u00f3 t\u00ean l\u00e0 FillData.<\/p>\n<p>public class UserGroupPresenter : <strong>GenericPresenter<\/strong><\/p>\n<p>{<\/p>\n<p>private IUserGroupService groupService;<\/p>\n<p>&nbsp;<\/p>\n<p>public override void OnViewSet()<\/p>\n<p>{<\/p>\n<p>groupService = new UserGroupService();<\/p>\n<p>groupService.DataChanged += new DataChangeHandler(FillData);<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>private void FillData()<\/p>\n<p>{<\/p>\n<p>\/\/ C\u1eadp nh\u1eadt th\u00f4ng tin c\u1ee7a view \u1edf \u0111\u00e2y<\/p>\n<p>}<\/p>\n<p>5\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Trong project UI, t\u1ea1o c\u00e1c form fmrUser, frmUserGroup v\u00e0 dlgUser.<\/p>\n<p>T\u1ea1o form frmUser v\u00e0 thi h\u00e0nh giao di\u1ec7n IUserView<\/p>\n<p>public partial class frmUser : Form, <strong>IUserView<\/strong><\/p>\n<p>T\u1ea1o h\u1ed9p tho\u1ea1i dlgUser v\u00e0 thi h\u00e0nh giao di\u1ec7n IUserSelectionView<\/p>\n<p>public partial class dlgUser : Form, <strong>IUserSelectionView<\/strong><\/p>\n<p>T\u1ea1o form frmUserGroup v\u00e0 thi h\u00e0nh giao di\u1ec7n IUserGroupView<\/p>\n<p>public partial class frmUserGroup : Form, <strong>IUserGroupView<\/strong><\/p>\n<p>6. T\u01b0\u01a1ng t\u00e1c gi\u1eefa c\u00e1c t\u1ea7ng v\u1edbi nhau:<\/p>\n<p>Khi ng\u01b0\u1eddi d\u00f9ng c\u1eadp nh\u1eadt th\u00f4ng tin c\u1ee7a m\u1ed9t \u0111\u1ed1i t\u01b0\u1ee3ng, \u1ea5n n\u00fat <em>L\u01b0u<\/em>, t\u1ea7ng UI s\u1ebd g\u1eedi th\u00f4ng tin t\u1edbi t\u1ea7ng nh\u01b0 sau:<\/p>\n<p>private void btnSave_Click(object sender, EventArgs e)<\/p>\n<p>{<\/p>\n<p>\/\/ CurrentItem l\u00e0 \u0111\u1ed1i t\u01b0\u1ee3ng hi\u1ec7n h\u00e0nh \u0111\u01b0\u1ee3c c\u1eadp nh\u1eadt d\u1eef li\u1ec7u<\/p>\n<p>CurrentItem.UserName = tbxName.Text.Trim();<\/p>\n<p>CurrentItem.UserGroup = CurrentGroup;<\/p>\n<p>\/\/ Ph\u00e1t sinh s\u1ef1 ki\u1ec7n l\u01b0u tr\u1eef g\u1eedi t\u1edbi presenter<\/p>\n<p>if (OnSaveEventHandler != null)<\/p>\n<p><strong>OnSaveEventHandler<\/strong>(this, e);<\/p>\n<p>T\u1ea7ng presenter l\u1ea5y \u0111\u1ed1i t\u01b0\u1ee3ng v\u1eeba r\u1ed3i, g\u1ecdi ph\u01b0\u01a1ng th\u1ee9c Update c\u1ee7a userService \u0111\u1ec3 c\u1eadp nh\u1eadt v\u00e0o c\u01a1 s\u1edf d\u1eef li\u1ec7u:<\/p>\n<p>public override void OnSaveEventHandler(object sender, EventArgs e)<\/p>\n<p>{<\/p>\n<p>userService.Update(View.CurrentItem, &#8220;UserID=&#8221; + View<strong>.<\/strong>CurrentItem.UserID);<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p><strong>T\u1ea3i m\u00e3 ngu\u1ed3n v\u00ed d\u1ee5:<\/strong><\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MvpPatternExample.rar (<a href=\"http:\/\/www.facebook.com\/l.php?u=http%3A%2F%2Fwww.mediafire.com%2F%3Ffqcznsk5s4euvu4&amp;h=7AQEu2zuL&amp;s=1\" target=\"_blank\">http:\/\/www.mediafire.com\/?fqcznsk5s4euvu4<\/a>)<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MvpPatternDIPExample.rar (<a href=\"http:\/\/www.facebook.com\/l.php?u=http%3A%2F%2Fwww.mediafire.com%2F%3Fu91e7keg8qr8mv5&amp;h=kAQFoVzRM&amp;s=1\" target=\"_blank\">http:\/\/www.mediafire.com\/?u91e7keg8qr8mv5<\/a>)<\/p>\n<p>&nbsp;<\/p>\n<p><strong>ManNT \u2013 R&amp;D, HueCIT<\/strong><em> (b\u00e0i cho HW)<strong>\u00a0<\/strong><\/em><\/p>\n<p><strong>09\/01\/2013<\/strong><\/p>\n<p><strong><em>\u00a0<\/em><\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>[*] <strong><em>Nguy\u00ean l\u00fd \u0111\u1ea3o ng\u01b0\u1ee3c ph\u1ee5 thu\u1ed9c (Dependency Injection)<\/em><\/strong><em>: L\u1edbp c\u1ea5p cao kh\u00f4ng n\u00ean ph\u1ee5 thu\u1ed9c v\u00e0o l\u1edbp c\u1ea5p th\u1ea5p, c\u1ea3 hai n\u00ean ph\u1ee5 thu\u1ed9c v\u00e0o m\u1ed9t l\u1edbp t\u1ed5ng qu\u00e1t (abstract class\/interface); v\u00e0, l\u1edbp t\u1ed5ng qu\u00e1t (abstract) kh\u00f4ng n\u00ean ph\u1ee5 thu\u1ed9c v\u00e0o l\u1edbp c\u1ee5 th\u1ec3 (concrete), ng\u01b0\u1ee3c l\u1ea1i l\u1edbp c\u1ee5 th\u1ec3 n\u00ean ph\u1ee5 thu\u1ed9c v\u00e0o l\u1edbp tr\u1eebu t\u01b0\u1ee3ng. Do l\u1edbp t\u1ed5ng qu\u00e1t \u00edt c\u00f3 s\u1ef1 thay \u0111\u1ed5i, \u1ed5n \u0111\u1ecbnh h\u01a1n so v\u1edbi l\u1edbp c\u1ee5 th\u1ec3 th\u01b0\u1eddng xuy\u00ean c\u00f3 s\u1ef1 thay \u0111\u1ed5i, ch\u1ec9nh s\u1eeda n\u00e2ng c\u1ea5p; v\u00e0 khi ph\u1ee5 thu\u1ed9c v\u00e0o c\u00e1c l\u1edbp t\u1ed5ng qu\u00e1t, h\u1ec7 th\u1ed1ng v\u1eabn ho\u1ea1t \u0111\u1ed9ng b\u00ecnh th\u01b0\u1eddng n\u1ebfu c\u00f3 s\u1ef1 thay \u0111\u1ed5i di\u1ec5n ra t\u1ea1i m\u1ed9t l\u1edbp c\u1ee5 th\u1ec3 n\u00e0o \u0111\u00f3. B\u1edfi v\u1eady, c\u1ea7n \u0111\u1ea3o ng\u01b0\u1ee3c s\u1ef1 ph\u1ee5 thu\u1ed9c \u0111\u00f3 th\u00e0nh l\u1edbp c\u1ee5 th\u1ec3 ph\u1ee5 thu\u1ed9c v\u00e0o l\u1edbp t\u1ed5ng qu\u00e1t.<\/em><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>b\u1edfi Nguy\u1ec5n Th\u00e0nh M\u00e3n v\u00e0o 8 th\u00e1ng 1 2013 l\u00fac 17:20 \u00b7 Gi\u1edbi thi\u1ec7u th\u01b0 vi\u1ec7n MvpPattern d\u00f9ng \u0111\u1ec3 x\u00e2y d\u1ef1ng m\u00f4 h\u00ecnh \u1ee9ng d\u1ee5ng d\u1ef1a tr\u00ean ki\u1ebfn tr\u00fac Model \u2013 View \u2013 Presenter\u00a0 &nbsp; 1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Gi\u1edbi thi\u1ec7u Trong qu\u00e1 tr\u00ecnh th\u1ef1c hi\u1ec7n d\u1ef1 \u00e1n Ph\u1ea7n m\u1ec1m qu\u1ea3n l\u00fd t\u01b0 li\u1ec7u v\u00e0 Website Nh\u00e3 nh\u1ea1c [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[],"class_list":["post-848","post","type-post","status-publish","format-standard","hentry","category-k-thut"],"_links":{"self":[{"href":"https:\/\/dongson.info\/index.php?rest_route=\/wp\/v2\/posts\/848","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dongson.info\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dongson.info\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dongson.info\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dongson.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=848"}],"version-history":[{"count":7,"href":"https:\/\/dongson.info\/index.php?rest_route=\/wp\/v2\/posts\/848\/revisions"}],"predecessor-version":[{"id":2892,"href":"https:\/\/dongson.info\/index.php?rest_route=\/wp\/v2\/posts\/848\/revisions\/2892"}],"wp:attachment":[{"href":"https:\/\/dongson.info\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=848"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dongson.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=848"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dongson.info\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=848"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}