From 05dc6a67116f3accf02ec22ba4b37d8a9a0de42d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BE=D1=84=D1=8C=D1=8F=20=D0=AF=D0=BA=D0=BE=D0=B1?= =?UTF-8?q?=D1=87=D1=83=D0=BA?= Date: Thu, 20 Jun 2024 23:14:06 +0400 Subject: [PATCH] =?UTF-8?q?=D0=B8=D0=B7=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MotorPlantContracts.dll | Bin 0 -> 30720 bytes .../MotorPlantDataModels.dll | Bin 0 -> 6656 bytes .../MotorPlantDatabaseImplement.dll | Bin 0 -> 75776 bytes .../MotorPlantFileImplement.dll | Bin 0 -> 40448 bytes .../MotorPlantListImplement.dll | Bin 0 -> 26112 bytes .../MotorPlantBusinessLogic/BackUpLogic.cs | 98 ++++++ .../Attributes/ColumnAttribute.cs | 26 ++ .../Attributes/GridViewAutoSize.cs | 20 ++ .../BindingModels/BackUpSaveBinidngModel.cs | 13 + .../BusinessLogicsContracts/IBackUpLogic.cs | 14 + .../DI/DependencyManager.cs | 58 ++++ .../DI/IDependencyContainer.cs | 37 +++ .../DI/IImplementationExtension.cs | 17 + .../DI/ServiceDependencyContainer.cs | 56 ++++ .../DI/ServiceProviderLoader.cs | 54 ++++ .../StoragesContracts/IBackUpInfo.cs | 14 + .../MotorPlantDatabaseImplement/BackUpInfo.cs | 31 ++ .../ImplementationExtension.cs | 21 ++ .../20240620185256_InitialCreate.Designer.cs | 296 ++++++++++++++++++ .../20240620185256_InitialCreate.cs | 214 +++++++++++++ .../MotorPlantFileImplement/BackUpInfo.cs | 41 +++ .../ImplementationExtension.cs | 21 ++ .../MotorPlantListImplement/BackUpInfo.cs | 21 ++ .../ImplementationExtension.cs | 21 ++ .../MotorPlantView/DataGridViewExtension.cs | 51 +++ 25 files changed, 1124 insertions(+) create mode 100644 MotorPlant/ImplementationExtensions/MotorPlantContracts.dll create mode 100644 MotorPlant/ImplementationExtensions/MotorPlantDataModels.dll create mode 100644 MotorPlant/ImplementationExtensions/MotorPlantDatabaseImplement.dll create mode 100644 MotorPlant/ImplementationExtensions/MotorPlantFileImplement.dll create mode 100644 MotorPlant/ImplementationExtensions/MotorPlantListImplement.dll create mode 100644 MotorPlant/MotorPlantBusinessLogic/BackUpLogic.cs create mode 100644 MotorPlant/MotorPlantContracts/Attributes/ColumnAttribute.cs create mode 100644 MotorPlant/MotorPlantContracts/Attributes/GridViewAutoSize.cs create mode 100644 MotorPlant/MotorPlantContracts/BindingModels/BackUpSaveBinidngModel.cs create mode 100644 MotorPlant/MotorPlantContracts/BusinessLogicsContracts/IBackUpLogic.cs create mode 100644 MotorPlant/MotorPlantContracts/DI/DependencyManager.cs create mode 100644 MotorPlant/MotorPlantContracts/DI/IDependencyContainer.cs create mode 100644 MotorPlant/MotorPlantContracts/DI/IImplementationExtension.cs create mode 100644 MotorPlant/MotorPlantContracts/DI/ServiceDependencyContainer.cs create mode 100644 MotorPlant/MotorPlantContracts/DI/ServiceProviderLoader.cs create mode 100644 MotorPlant/MotorPlantContracts/StoragesContracts/IBackUpInfo.cs create mode 100644 MotorPlant/MotorPlantDatabaseImplement/BackUpInfo.cs create mode 100644 MotorPlant/MotorPlantDatabaseImplement/ImplementationExtension.cs create mode 100644 MotorPlant/MotorPlantDatabaseImplement/Migrations/20240620185256_InitialCreate.Designer.cs create mode 100644 MotorPlant/MotorPlantDatabaseImplement/Migrations/20240620185256_InitialCreate.cs create mode 100644 MotorPlant/MotorPlantFileImplement/BackUpInfo.cs create mode 100644 MotorPlant/MotorPlantFileImplement/ImplementationExtension.cs create mode 100644 MotorPlant/MotorPlantListImplement/BackUpInfo.cs create mode 100644 MotorPlant/MotorPlantListImplement/ImplementationExtension.cs create mode 100644 MotorPlant/MotorPlantView/DataGridViewExtension.cs diff --git a/MotorPlant/ImplementationExtensions/MotorPlantContracts.dll b/MotorPlant/ImplementationExtensions/MotorPlantContracts.dll new file mode 100644 index 0000000000000000000000000000000000000000..cc410945cc6f458d9dee6cb43796edce155d8099 GIT binary patch literal 30720 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 ls}?O8!l>`wtEo7+Z@ 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 literal 0 HcmV?d00001 diff --git a/MotorPlant/ImplementationExtensions/MotorPlantDatabaseImplement.dll b/MotorPlant/ImplementationExtensions/MotorPlantDatabaseImplement.dll new file mode 100644 index 0000000000000000000000000000000000000000..71b079881741e6513b5cb215e650e8ad0767301a GIT binary patch literal 75776 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 P>xX}TP5gspgFW#7AhOuB literal 0 HcmV?d00001 diff --git a/MotorPlant/ImplementationExtensions/MotorPlantFileImplement.dll b/MotorPlant/ImplementationExtensions/MotorPlantFileImplement.dll new file mode 100644 index 0000000000000000000000000000000000000000..887b88304e69c4aec1a8b6cfb5ae45b7837a610a GIT binary patch literal 40448 zcmeIbdwf*owKu-@o|!$9naO1)7j6L(2|ADv!yOcra5c(JE{cLBLo#3_$-qodCj|Ut>@W$_9W5M^Zwp{ z-p~7v&f4qtthJu?tmoN#KYLG@d(jQ#AtEonpMOrYA4mR775L>K198F79~ICedCyhu zH|9K7x%iTnbj8|Ka&;=+R?!r1Z%=kqtV~p-*0)!*v{%fSzo?=u*_^1&&kt5<(+g%2 z%`rUm#_!Mip6%@@om3Gr>WIDtj-|M@kKkB=??HTtiUc=R+|1zk)yE(LpFbXIyqZ<{ z|Ljqd%);lj9}vxF@z z$fU12Zcy^6AZn~lrBh9yB({SI5v}fG!>o9e1!;E{9pQG!74Xzk|HfDIqj@8r#sft;`&f;b&T*N10V z5`#`Pal1Tehcfo2`fipYcsWzQBIth`XQs-Co}aN zqwLO1{h3kZ*K5X*S`>?^2Poe_AX6c54G>INJhm7hmc(GVnt{cwWOypMRef$NtcO;5 zfV5&s3^7#4;7MA^;GD{>Ft6Oc9^+O6r4>tJ2)CMnw34AYom)-MZS^B=HAq^qge#{y zh60yXlHdkzH6ypxkGWO3v|EnJ>$1q{5L;mzBXnkio2Iz^603;e2 z>^BlN?0A6^#lQ)cC1I!9#<3tdIA*AWW7au1D%8O-I~*Jpk21%qCI!Ze6D+HxM-VVz zUNHm#13nZ(5HR3KF$6)p9-4ztQSj1tUUz&{5~`k(uEq!qH4Kh>c-P`$}EuD2!$HI0o8v>ZU$q zI+E0P`;cV=LrgqIu!b`X`s`6_t%s^lF+I{h4hjY9Npk;UVig4UFD7P2{vnOUEI3@M z(MnDLj?{1sTFHr;K>1n8Nt&o)0xL7lL{e*4!#96YJn*<_ep_Er*Wa8L^eWV2z$B#x|5ig@HbCa=oDPA(XYa;a#Pi^NrL zs7zHnf}omEo{Av|7^qRj5QKB>A*{7XXpj0jHH}><3o(@m)P*i7 z*z(e4ec4*2ZDrHfv!=BD)I)a0li8Zm?o!Y7mc{COgdnwp$=|bf2BJbZ_Lvw0!Li3A z_K}aKr-49)U?y3~>A<;MP+V3Li=+^k0akJ*6KV~yXbpT|agL<;^dU7eppP11i@7!8 zbWnM4YQ*WB8DnR`D8**MpOULen5V~_htf6XSZvgY3W6cVc}p<_0RyKb#SjDxoNW|C z5ai59m!Lm5ZD5VrgtLmiz?q-^8Da^MpRd!b&iN3SW();kZJrHWPMC-iS2RBXFAW|} zm@M(1u%2Pg+2HVMSl!7+we4^<1xE6k{!RGANhfz*yD|-nTzBW7Eze3RwR4%kd=did zVK9kFAp~Y%a5Mb4qd5p!dL9JBGc4KMkSp%aidhmvo~pSzvUP0HTRmb6V9lNMD=>9< zUtG#M+L#B6V7`~q6Wcvk4c0eB=6w3Jsrv>mL;2^;}$=a6|+S0 z9+SMAB~l<*xfgIZ%ovttD|sGpo{Csst>i*YV12Zbi!?EniN#E)c^RPZqaQ(@mwbWt zg=;sP&z+afXeoEjymUs&jIrn3c{zMQcA)gUK-Ias{50C6mms9!8J5H_;d)%7oC4v< zZ|SMcGuBL>4^}5nO`R6kWG@F-?sf#hR32oT3Qb_P zSjk3Bpct)WoC!Yvd+AYFbmv0m{#{_|bbRsL*C|S!?#$QhX-sDKdUY~{`aCvufNXC62gZDx!Usrdu45t}hi zBhQbO$fTAJ%m!@6IOn-?bzXZ|7e809M!9y)vQDm894h#by{N7PDRV#&6g1XE#SjFH zVKze$FmPq1Gz0--xXlm*jFWAKAYfo#swRTS99e~&=J%W<=cilHFU*l9bUWD$9F@n% zU=oQCBEbaeQwSIda#0Jhnh6xB5SK8~$b>VFUV5R2PpQS9fT`W4ZgMK3j@#ps#)%?z zdml0#RO*4=GAT8->qMLSNpCGX_|%Ji$aG&)@Aa0&F74evkF!sfUIQtnEV5`NTY>ZZ z#hkQ~ZJNN`x03Cez!G64lbXPEw~}i$ff;Tk*D)d27!M*<{E-`5IUkhU^T5fR^6Fg1 zJ6Tf!Xny}}#>^PUaviR{2WjDeY@*B<$ENuMvq>^z9H!8; zflFGWT)Sp0g|2mS)oL!+t46s}UGpRcQs#*uDCrS4Ll7{qh$;<1z^Jwvf`Earl!hQ+ zjItSmfKh8R1Oekzn;{4os7qx-5R3(%Z?4C&pyyobOm`s{m_BKAGPwyj&!r9~P#!|8 zX96W51a3BhJk~;7&IB3?v4IKb3bBz1h=uqn6W|B|7eOu~XUfU?f2~1O=!#9|+y*cu zyl}w$;uC1s0BRwZen25R{dy=!-=I+X1s2r&l$fD4`U|vFR-kZ39}4x{ zYspmL2*$*ST>*xfn%P@bZdGHQ5Z}#;DxUR_ATSJA$=u4 zbzanSq7=8UgYwiU1=M25djhEMp4Se1U&mt|ld%TD!yA*~<#V}*Fd*_tXCT0m0=bn$ zmC5=7uU7JFn!uuCCAVk->x`AWN)v0DxLOmKe^&AuO`tTb!TMxqF5#ytr~%@buZ&Qst(pTY-a2iuHs7xSZ@*uP}u<=L?|W8CXvZ`6CD zj7QM5(V-T#h2|9_u^5~vEr!%ysUFq{whSX^-ib39?lL#=A$cwQ3@u4shePKWUPfe0 z&p|Gs8cAaj2?ohJQU-HU#GU^Nj=70dtrONaL8Na0hz-JJx7uI~Da)}N!R`p7opY`= z2@5er+4PZoY-ozX2$(VojCiYCJW=F?< zU~Xb=(g%Z^mjRQCxCqDz>vfLdZb>#vconSX9Z`4fu7{n0+?O|@%(aUvO0Hc#B=136 zsa;i+-vcQ{>3Bp@9%U!HS#cOFZ^jt7LwF+_0!y+X$e_VD&mWvzX%NS7OvkW7#lVMb z3^o0&O~Tp3VMNW?y*QSgFw~rp5v+D41EIa;goaBw=Yhv~a3#C&t!lZP^N3n@x|O_- zP3u~AxSKD|?b~nJ{Qb}zo?!`ZhI1`H01j$-jPxb9mK{@8^82i%U1AO7TIRrVYI!i{ z1^bjxMD>AjzgqU&;9FF%iMyW5^ybxXYu0~KRLBLg#Emu{h+ve`gymPAG?;F z4*8RN(IM1wZ%1EH%jm6L%RK%=Ifg&!7*=r%)+RnAAB0`Ceq#KE^AI>+IR0!lnFl+_ z&!0K&hq?X9uJNA%u08%9S`Xh9?E8J~d$sb-hpcZ^|36^IyePY!{Kau{3Y=_iLOYp) zD}kJ_-ec(_Xg55=k{FhjYFwSwqfwNYyf?x74y@ zD7g>b?OJxYn-jU_|H$Sal{i_#59+v#}3YO73SZ9eXiUQOlg z5J~@s*zt5;0vC1zJyst;lpU*HwahK}Q32Pocosi?@#EAoRv4;cKY!JJT6+8W&oB4G zExy!G&n0;R8X#G+j`28R5#VuTb`n=L*5)<9q#!N@a>DvA_Wzh9nkBJnE{GZcXB<8B zFR+7(jif);{lL{R&j&sve}uMbKH%y>I6t;I&eg-?;7Fl5VPH1=gFPQ$-BED2xfRA- zas53T7fZ5n=|bgo`gFvFB9Ej$(Q#qo@;JJ^eCl|qg%|rF^CEC_uOBcGq)wf-$tMt+ zU8fFrb6akhAF=tLKy!G8CH#1a>+~QvsMGT#uG}@(F=ZvYSxbjo236E42bNQ(Be;K` zi5*Yp+TQ&;0g=ig_peu-atq!%=QRz3oH~sokEoeQ`g84PU2i{l`K5;+d(Cw^ zFg zu=FXo8lGVZpHQn~V*#X)xDPzvP|G~uoESHEFou(6bqvdz zUIe&rbI=AUj-zsM15q6R7NV-tl z-NXj1O?*fmh7s49Rb7SW&&0b4s8}rj>M} zbJZwL(S(AEq$4^Pu-h}a(VV{K%=Z}X7q~@ov-nVBtNi)1{?w(0%(>O@hoO$7i?zSb z-u_B@`Qv$CYj=lB$DjNqI*55M+3Ulhp8ewU4fsT5Mbf3(CxYei<^vYWVsFG-6DTS6 zP1*-VZ88r|FwA8f%ENFamruBn7k?oo?8m~}SvV9!6V}3fCG5|_11#i4G9Ncto?Z9e*HVA=C5QgvUJml`iz(K~As&9OK#m!G#EK>Kl3YHoHO!Aq(?^V!(5L9*VtvF# zsRgG`;Ek8Ho)9K%EG8}sgJ^YT9Whw>E-w7ity~mS$1+3(&05tB6d&2UeWJFe~6qN5OO>~L}$H_NFTg9=I`-6ec8Er>;p-Wnuehr2*7xf%itaCE3_K~Y7 z>*y=;0vqD_3Y)qIjwH!h1sV4iC%-FfH8q;(I2JQB&+@rDqt4KrJs{l4l@iWwSgI!VoCuu9a#y+;IuZ5}3%4r~J^G2|%XOza3jI7y z`kCe1{S?kaJ^IPE&Fqc&f8S4xgK~h=p>o_~9FPcQRBrmt>758A#YlPOr6sHmwdubh zjLfAy6S0Upj;U@RXEW`T9?x^sm3+(|cUPQ;2I*Qm`}q-~P_q|>E}S2O<5b4ESxx5K zvp1*E)w*&MyiJt(o3!mZR+PUipYvX`+T0|ZV<6o1#a-zkItmrn?vX4l!eD=}D zlvLK&a)_ALJ*T9Su5(Fi(LwYvh0ZUG&LG$8v!dQWl2y#T1_l)SP9FY@=%!RWIqRBEQ z8`;5OSa32OlSf<#HAj@=bj4);rGnOYTcR^!$8oF~?MWhJ3s**pME6OxOkGgqR4+zI65*+V}=2TzkcZ~Edq=ZJD6Jnb8j zA<_7=yL)R*b^pTQ@k2L>e3^&eUf{BE8ieh#F?*Da+Dt~-Wcw?PY=gSL$};-fYvtyu zGS%HcT5^-^I+imf#r30Cp0v9!XPm`uGfUrBZNVHO2Hi}xe&CcU>xU;fJFD>*os8Uc zjhwdVoM{HvCO%<&FB?}|S3979#3Snq`rVnAR{-)K##nwx#NKfQ z#`houH-uXQ!UW^zWrVQl7--al{2mJ-&_(!SeUx^798bd6i!asze3s$XlRp;C&3`6h z(Juv_8{QWwq>m%azbhOouxMZYKZ-2+Jk0QMfv*bOBK+$F?;mChZ{=SOos}gF$A%eR zP|EO)&^}1l!E%tE_nhXlDCWJqsDSpDUL1+ij-p4sWz?4cM$tg}Ug4Y3fwaUousBLD z7n}+>q$pKfMngpU2&7SZPx!Uq52TKQH={v1*UL6fh0Q2+iS$rms@S3_!XJZv4WwHN z+2#`>{Rq;5bUCb9wBN%KHiWqC%_4nCq+2DDb4$0O)&0VM5Bw<2h{Q@PS`guEd=ITG z`gz$u(DrY6v63h)C_E23-XP;E1;11HpBFIyMZqTv{~^I6fuTEzH6 z(SH>2ct5};fSSPQ8%0=9pNWols1+DTrnvfw=r&|-Ja8{KMKmb#QfWPY$Kn%eXAx82 z3UzPkCsC$`2sONnsS@m2al3ekseY(Brf!QcRgQNbnVKY2C0!uYMxkPKsZcW`J4))Y zzw$Mq{wt5Ev2?Xiz93WM@br|e+$FN{bdyjo2{nPX3-z#26KSVVPYX4P?jcWQ5smQ? z)#Gfn*G0{u1LQ&9KSO%z@r%iy2~~`lTTcrx+gP?!sPpI-u67IQIg#x~ZtL-@q8Ehv zNT>_wC84ern@j0sp$-alA-&?VauNNz%gR^iO_!Awbj)R?k=}M$iPJkSD=X=DBE!iB zv8NTK6JHfr;mkFJxbCiE-P#4GnbWh^tsDQiVTBu zreax7KA}`BmyzGdj>F}Y=aOxtuu#h1CMpz4W$+4$2&FRENyS3dplIu{E|wZ6(_PU6 z{*!4~LAO6bYw`~HE9u$bA)}IR6}Um*0fBo2ejU)DF@a~W!}_-W2;k5CuK*4R90mNu z|9ij({r>?t)cOd}Yq5U9&v2*Uia$~~`vRXhntv7Pk1ghm37i1TFZE-yR_P!2Wi4#; zv*j1WzLJiWwqLjULBBvO9}5fxzAC`2ej#w4=zm?{C8BvpfbCr2XOHs&RnTwnbE_)@ zBLLYl@*p`mH99t6k+eL>t6KIcja-a<7oihNp(rmy3bRJ-xu?%pvkpSFbFsIl| z0*>%(1U%~50{9j0^?;XqzYTbUcV~dD-3R>F#$LdB^8ny94@2}G@ClRQAY#rdBF#5m z3s@4fMdSPZ0r*!#_j}mRe?sR1`a9rXO@{LgBhRAxqM!>F3SOAU`o(#y-w*JwCd2tg zrASA*;HiS2D*9tZa}wZd#BjbbU8Hkd@I1lK6aDj{a{(=rRt)DGt3;Y~!4APYM1P}b zZU%gfHVc2Nh8*p`iiMkma~t3j(VY%nUv#(N3f`NypaPSfuIaxUX9I&Sbf|rK2BjS8 zN1(puP%OJqQGwr-90avpsII`fC5J)XrDe|)znEvzeOmTn@#~--(Xx5bck?{-xRzZM z{R^n4v@Binah{i+)3Pf|%%GQE*0T4C!$BYYR?GfTTng%US{8^74O;XUEh~-2Kz$_C zw`fJ)n4q6dsU&=^p`oP~e#x{#Q>$=3_tUpE^;?`x{q!qMU5m4}pZt6YgmxjJ&eGIL z(r$xLU6MgRl~l3jHX7uc2!9(iRpmQ37@{YHdN;4U-*%&r4k^m`Ju+WNCl417Vx^Ey z73$r*3w^9PQK+s!Bc2l#(o`+`%zFpc$FsF8_@v57055@2==Gr zntG`8=Xe`u{VCZ#^r!C%rTWmHz9*FGLw|Zu%Laz-Fb2?mEvpF?;eDEJExV@dIb$Fl z7V4V7H_KiI^^#B==f>b5s)(^arZU07v`eUK5a-u}L+Lk)LY&tJD=08RA`5Vw6?CPd zB-a&mlTa$o3c6J&6=wzQ(z4$M@4#8$el7cRu!t&YpO&4O_ndJO9ni9~^Iit^v{2Vz zcH9^oM!(ducS~*q^@?uyx03VBDw;FW?!)(j!|C@9wKsSQy;3bvqeqVhN6^X|)rb6| z1HqBBLsQ(Nk#x~0kx7q6Qbs7%qmlFtp;V7X(l#yo4XUS_{!PpN;4PwRx>L)zLTcz< zp{@yVh1AdwwCu5>?Zznjv6lU!$iUOTLt566x810vXSM9>SP5$B6`^>Ho(!IfKf_@6 z=oi7!bc3QWMlS@%&~c$y^A%9LPgT9;{*9vx>azVCM^_1@`iE;dp;Z6I(JflG+INRB zo^IE&^_U&w=^icX_Pu3JpzmwhFMU3o6Mm>=pJJpZ(oeK3go>O<&uH1vvOk)Wh+iKj z>I!^NR_K{TuWH#>O7Acx(=jc(w6qA zG}~nAcfm7g!5F5lL0;Yuo<$F8iZgK*wc=jUUa!xh`-OTpZwuCmv*;0_x&k*~oj8jQ zXjwO8Q|T!!`z2&k>6cn|J2FvEFKgLeWTKwl)Us2{wj0yvcUm^N%)lSV_zx|+w&*!y zI(?*NHx<1M%HUf^dN*%;=}Dd$lqXbIU~1{bprTs#lh7Z{nKV$#eioj2#xa-rTe z)|3ql&8J05Nf8HskVo&fjXqA{h_agR#8p8l6?s3 z61rI^<>6AgU(42%T^qt(f~J<0-2&>mX{ud!>7Ai9^pd9Ll-(CO)ZLsD1{^l!r7e6^e8HNGMJFHMOklKxjRc&s0{{l>Iz(88vHaPT5PKzAu!rvVjgc zns0Pnh=Hp{M| z-{o21E*jCmR2MZ;Vfbq_QK)VGzaQxr-a^xbQn75IIYMp0d>#bZVolvdCxx%3<(m2# zjR=38nl*KrQ5W7yt(sbAOblO39h$n=7!kgnuF%wA^UUx!=_*Z)^~?<4K-X#N51u*U zZFIAyF7Yl3-$=J^#(_$Jz=sqNl)_-49aDAk8sXunXZ54TXa)_l{rBzz0~TvO+o z>F~GcMNQ4|q{H8)W10%l)#2}u_Z-gB7JA0KI{a^Ril&BBI=r3gH1!s&+)7h5)z7## zd>h>%l=6N%?bfojo^OY5r}tg5@6zA3EZ@5){9OuTug$Kd9aJjR7JATp$g_ja5=!-N zC!Ook+)0bIW+Uwl@1*6L`o!EDzLT0YwbXbtd>6I4+U=qZTDIMMJiLp%bF$v=rXr!X z&{oLqrq^Avd*~f4OG0)J{lg{u9(m@nl`V7yWZ$FyLaC^CQ1uZ$&C{~&=AQ6Nx#9`~)3wY5s&>)v~ST=i#5w2QJw``c%udLw1nPIFI90{<^6_C{>Z&v{0xmwAAqB zchf~K*-xoi%eI@L{GZZZ-p)pqU+XChKS@6oN?AEX&uZCLXda^PE@Dk3dx~}o#d!(k zKSc*zvZv{3ExQ7;r|C79>}Pab%a&oJe?}i`YPsj}@H14jSjFJ;L{De&052JM~2hV++rgGGtEgNdBk#%7Sg1kIJ%b z=gWM#z1#XKs@~D|-8;7hcO-qq@XuPvwb?t8EXR)dLX1wX$E?nm^S@kb+y63a|Gb5N zUh|9m_O{TQ^F?jleAUXJJMrYn=Kuf2m9_u9(2i|9p12t_Q6R_p&v}`EdHT<3{_{5f zdCmXb-YvX?;iovh2|NW{k8c8hrKStt1m5$z9p420I>a7)6L^Yw0N(`uD!_A8KyP42 z>K*Jn{TVwwk* zjew=tN8244M2`vQn84A-?nouI2p$HUfagUF%LP^mtP$7+XkqVwrBejX5I9HRVu8yA zR+_b?PtXYSHQ$qf)60HNqs`9JU(saq+a)hkgLzr$+klssd5vc1H#PMGV&@;Za}S=Jf66SL0XJ)U(2?*gqecu!}Y!Mitc<2z+# zo~;t+R)hCYw!%I`-uu{U@Gi$zgZDGG8oYC{)!;pftp@L!>@lVUr+c=V4~OP>)|n&v zJwdx9hHc_~oAhg&!8>J+arE*@UqrQ*K*QvZ< zulG+Pecs?o`%o-=syP=TC%4fj`5v!VvKK}kCeR0B!E3MuufZ0MNp&4V&fhXiM5kOb zRwa0iv>hk-0LfvEw4EZH52Thpkoadvt2x47EUlIcUN5Z{ORL4=(J;AMnnl_wutTI* z2!55oh{^F>Cw6WY&Q`H=ooHSscD6~iZ!>sSZj*|=&3K~B^6%2{gZzR1`;Dde6PULd z3f~5^3Bxx8O>D#2gigp=RQOE6wqxTm6q4JPMB+Y$sxJt!|SF-zIfi zi#2>-el1q%CjbZ08-T;;UBGIpDyYSi@_NA2X%66Yx)AVO;V%N5PRr8?kPw};NVkY|i%7RX`lo`cMY==yci|nA;=;RxbGN{Q!hcHe zqk_LJI&TZ-ZAv4CD-#TSPx2nq3;Q z{ua^SB05_{|7yW^h|W$8S@SN@yi25a3p^;&ZVg%INzr*yq)!PvEPjuQ&M^&H^KH?5 zTXfzL_?~Ez$(b}XWKEALSv5JUK7n~A=d)6DDoxfICOX4JI$U7ANb5y9U8K{6KT}{_ zq;ZipiL^=h&44!+Bm{2}FI}S9C7N3VzgnbQMY>ZsJ4Jez;Jd`a9+7qnr(2{?3VuvO z$$;SRnFFZ`uL(%6Janf30|)ubEXU4;Nd*PJp*ZHL6dNrJsf|F@VkW5B{sJR zzE$`;1>Y(By9D1Qt@eoYpm4f1WM5ATepsYO1wW=COWzipyb`~L%=ZXhA+SHW zdqk&OINe^BJ}LNN;U5$HnDE~g{J6AwPo#!V`s?FX9>FU$WX>?b>osJ~bio^ZGG2nm zrEQboEyB+T-lZY8+9LQ?k?s(Dr-m%OOYl7+Jt%m$hAe$j@WUcKD)=!CS^Bo%$95+!4;}Ja1;+QK0A0}{waHb1B!(s~!!f6uD7J+vOBtP4%5LoHw`8!qcdjCLr zprBFkxZur@-dKUiYoSnki1$bk@LE&@@ z=cwSv1gD^Q#2dML^SppJ7E}seFK~u%;(~Vxyh=Db1@9JkNH|Bu&N1N-p0QxH#LLj= zh2WKfR{^3I!l@Tdqu_DDn?;%tPM2_Y2);X%svzct-Fp!LJg{oq~4@JS3cBf*bjgB|v0J@TvLiv0m^-!Q+BAi%v#3 zUBcNR_)fuhiS(dwx`lI8@MD4>7bz7;Ukaozf>#P&1&F=~r(QUXg2x4K7HLK}UBcNR z_)ftO3f?XFA<;Z4oMXbFLh)EA9tE!yyb2H=g;Ot_M#1BPH;Xh=coKBFgtJrNF5w>( zez$Or3#S?HcNQ1!5_nu-72dxrE^HRKOW<*VUc8@LTv#P=hQMZlR|(uzyoKrt50;*U zu|8PJkyn&4K2>0&z>L5h0uKs2DvK(QdOQQ!`NM-_h%OEUs@2s|i|%Eg+%jKG5eD+UW+V57ht0*?x;7{by< zfd>U16-Yy+mB5U^g952S^aW-F9u!EG!WXzh;6Z_OlGqWL5qMDGQGqm!rKiv%xcj}? z*l+yIc+GgzIM=+_e8GIheBCVfjPF=H3z0|wTd#m?u?>_H~-uJzqc}sjl zeItF-d~1DQ_1);Z!*{RmS>GRg|LF@^{j6cuc~Hel?&tSsUK$++_|1|Uz`~O8 zfG0=K1gz*c8}Jn$!$RM=fJ=%P7UeOF6wL?RSGpKb>C}aoe^c3oBE7hW^n)Nv=j5?; zSm{c@g3?yNNKq%C+s^ymte0OEvG;597)FY=^w8WWQN7^X3Vxw@|6AFOz}rjN!eeC& zBSqfvwhK`8D^j!md_6 zV4UXwpot9ofd>IiWH}Fb7|_JdR|t3kpo!hDeBecZCJh2*;$7wlI70zVs=ydwp9IjP zlkj(+4BTs#0pSTboQ?)6N( zN5SuHpABeI1KxEp=o~;3cYXYenmK?b&4pFG6AEbJ&E_+JF90-Y5v-cD1aHrpczY3V zfY4Gv{yo=B;1>a!v`pUEUJhu|#qeOzR{;6%j-3m<5zxfG<6Ph?0ZrT)&IjHMXwqsr z5AYKBG4XEq67bgm;&}Qr{NezxW>U z{k!ii-={v0HOiW1wOO03yR1XjFYu$>kbkIuvj1kkH^Y0%?$1kjmSedXkN6kj$xu(; zzT)1zBH4YJp8C654D?zcmDEGy#-i>@T&uS z%kdqI?-0y{q4-wdTZ!*U_zuG?sls5 z?u${Y#WV)rvG|U|cRaovNgWNq9z6f`0CgNM#}d37KEO8)GhiGlc^oQo9NuIfhZ-0I z-Wc%4fHwxbF~Zx6%KQu!S&H|IPBG@v6ypL~j&C!*t@w7}dj-B%;d`BN6HPL2qRa5z zX3oYN$HRnn+O$YUvt-HIW?LdOOU902$)fmWiRsCN_sV2f> zi-PosK?!@r;ItSsp6#tpbgV$Lr88R-ZRnYVE&>TtFzI@0i_>pMEJ#CpI+2og4u9+f zJJN=>waTs?uSj}!Q8BrT6YYj`6X|q(wa$xhdp1%`G#Wk0?uW`{?kFi~&&Ha|E~RyC zQ%5o-gDPZCb;V>~li63ceiU8b)P!&s!308PE6~YS5{Maz)`TiJ5XiPG*@`i%rL`lG zN;KQmqqr_g%B*h1Xt#3|GiZ^FW-RM+jL0CQ(W3(#R; zISByWD*@nfVf8s6ea6G)dqji6ZyZhYFsI@xTN6MVX11?yOQbZ#$pLe5vZ1|WEY>RN z?W7gJ++l<46&!e96x_mGa)zU-_4b3WoX602;dhSBTp=7CS(zQsHhixOfRA{lQUs^{+ zt;G((@l$HS> zLK1ob=#}7^ZSj`Y-jOa^-`1OX-uifJ%c_>9I8UbDV&@Fd+lfA9_7dpxVlTdHNYcF> zsS)W*kUib^GP$TD-m$)qHjCD;ycDyfw-?Tu6Gw0H^yGS+e0#Z>p2XEeFYdHt^Tys> z_J9*j%VmjFZz<0`yTD{xI>hWm$Ks7^6Vom6L>`uQ;YZ? zAkC&tSR2|}=YcD@>J;k>>FSijlTJC5t5Xh7uUoberyGs}XF5CGCCe_7rP&EDQWwcm z$D#zu%XThj6UG*<$3!J}>BWk@BZb2WfqR;H=>svTi*tZ3JJKSdG(mA|-@Q zt29}VN@5}F*eHSvF2S`BEr_Sm2~rm|qLW>Cqzf)`Mq=gq)vFV!X{qGpX}&(->6svP z*+on1JMi}bR;~wUX4}d{b916O%i(^ab18`!ja(u}X$fD7Iuy*ZH+GZd*_SC+^7*k1J`cm%W7zm?x<=Sxn=tU#Nx4 zh*d4C*QZ1;YXrHB&qYj$RF)@KKl)0Q%Oaf>sicXGg^AYq2Ekl%HfLY3WLw$Y##lG6 zZ|cYj?BsD1{42Iuf!%`r#oIS#1-j^j-_f$NrM0EQC7rerL(OF^S8alw9ZxF)MW>L< z_zF)hd1zsxEqPgjX0^sw_o(Vxok(0lp!C(BnV{s_6|?0IGPU@Uc>Da+%yl@EF?SB` z0^BUUqRGOl=f|{`_GTDUEZ1U?!~tyvWab2YI1a%zNHn+Cwa&ne0K7|N@DF}i&@oeSD7ojk5pQ?R=n^>GASB|NHucnu*<&}o)1zQO1e`#B5?VOhOb+${vWjwHE zuH`Gv_NI+<qFh`Q7m%t(WyHqWhK-{I zpUrxOoHIJLxVCR=>A*!>+PT%`btp}G`YK||nd4Th=)gaQPIFtDQpt33RY&b~6l8sS zyme!m+0Kn3kETqIbgeqLWV!X(OPp=$YGbeC>00-K;`W%;aLxR_6`bkh7H8eo@>EEZ zt_&x0u3JwTKPf4dc#U%2HOfQdDk!Cv!(inchBQgb4qcxe*H?>ar=xvok#lxZ=W$hP zYGF}9*f{&QaeaPurz3ZeoIs@n^>tN!YBhF3un#Hea28(e#$LOWRFz{7onB0dDcf-7 z23)48_UcYYEmm^VLy~CCo-emM5{AC@QJU&Dh!)98!{lDsP=r>2y3XYQyuQB%U87@I?pkuyH1^)p+W| zJka^`@f4{UcuJ(x@!Y8;t39AWEVP2trny=(G8Z&z7tfeh3r2%_`>Vy%C;YM%e^4yz z#o?8@Bgt~z5jfnTeaDfN=SI_j-mOBv9eHu@*eKuapYR)II}eoaj)D61?VI}b?UV4V zqZvJR+n9xCFZdx_XeP1|M}Co!$O2%TzsnIPd+sZL^Pt0dr#y~7jS-}rtU2<~0@!H5 zGd}26y8G3;-x%|uU#>xe`|h#s#h~->lrb)KvPyi$5m$>;84bQbdb0*kMK_@GxK>m( zNo0A`AZ^A|Mk-tc8!Pd=Gl7`VtB5;WDt|q*iwu=6f_}TMR;TX+W+0jlNM_*6)q5F^ zDfSX^_fxD6>bqwm3vsU2!#?8ib9`->9g9G*_4UX;mD--B!+t`0r9n2gw{7yD3q3@F zU%GR~)`Q~DX-5`5aOuJ7X?H$d^}|W$E^8rgg<%9d6=e8;L?TQU2s&BdOooFCe16l6 zmIO+p=b6!p=n`LrX_WW(290Qi;#EbLFjb|fIz`nfs$5a!ii#;Jrl=*hfhBg^B~jgM zNmRF35_Obo*hx(uf+>y8HHPqCKr`{D@Qi3zX@R$bqDurHP!O&#N~2wsMs!KEYruda zRtGgiF^3R$V+ai~@P`wlONLNUkpT(YQ)>7_alkFb;+_vKhvpEN&xhtb0I7hJ z!R3;uav%P=udWfkI@2&rKg?&|h)$B@JJBg}{9AN}96yVm&BrcZbdJz}j!u>1bJ1~< z>~f3=k4r(I0`^D21v(oj@Ppz`dHk@iT$h`c8lMWN=R+$WxiE};sN@&>J!W)iX*6@S z87PfpwwlrPfiQO;#4TnZ5GZyLw!*L?k4KseF^1^OIVsbrGowL|ZNhFQVOJGZK-cZg z<-yhrIISH{z|WSEPAljE3`Ed_TsttIKe#;K6>oG&C}?*ix&#K;Z9u|^q4Nr>2_T?I z<^hlu6v;ef*@R&fA zUG;d6r5soRXZis)qpWp@Z1Z46{k}kcB-0Jl)`A1HLJWhWndc*24F!HAy-})>YZ7(H z1nSRgK@T=jRnM#GlX>1OE;1m}g{wx#^kJ4{o<|XsmzVne(afu`{A>OO@I~uii_2H7 z3SuUz#)MU11$g_0#rQwqmnji#v*&OdPnPm%8_&SDklz!%MCM?$P3B3oO^si<*&p#Z z(R5+b>C!PRzZq?X9-5Y$cC&KbED%LAxN99r zZ8O`Hc9oeABbl3(KjFeuW?P<=a}_Y2)qIpe*_NmCn%NdWyDDURoAO?z?FB;Y=Q~Oy z_-zVzTHdW}$D*0L*)|`=_T3W6E*;6;u*Z?`5fdwB29W>EZZOz!4EWv3aZD>H$M-9d zIDSy!dECMMXz-ZQtTDrE>TzZNF%?Y>ixCYUC7Q>acpqbjHQZh~#QLpjD|1-2t&3(3 zb6Y-2+r#4EkaBQXd95>L0G@FM;4qu5gW1E%Y@OCq{diW1q#s8V9`)x%GcRE*%B5e2 zP1E$F5_lQJxuY1b)(HV9%Ovv*XVLUn#fH~!M3?iTTMP-DHUhyUGYhyL)e?jGQ&7MY zSV#p2`MoX@6F)omyLrMXPIiImw%3pDGCwb}C{=-2H53(i@T?VAMt&VU&0`JrnHJu7 zikA3Q5-RkuP9LlEv0NYV?|Dd8YfLL(TKNG`vS=1+1P-M0P!q>q3(+y?&QlzaK8qJB zI9&i9*A^}aG=|Fnjo}hNV>tb545xmL;k55yRSs6?VC4=LbFdnCT%0c+5u2R6N?ep3 zd4T&QXOaS!G{9#T-3)e`wNK4$4o29IbJo;0Al3}znG%5|*Vl?RV=nEe!k!}z5mK74xj z$@PYh&u+4K$vI3gn^otq>TFh(!>Y1bSpuh)(T(b$1RGh1cK1k_34K; za(z9kqsaKg3QA66+gOGq?^Mj4!n~UmQEx0mcK0z^!`H1i)jq~dtTj(D6LqTEJteZk zd3A;)bO_m9Z^P+ZQrw36@K@mMha=kH*kbE++B%)l%zLcEN7m_#ZshB?%(iIe1Gy-b zlLH9pr4Y9KdWUtlqj`5U^RdX?$WGxrhH`QAm~fgursbJ^4(qU^c^D-naueQiJ9b$aI?B|0T6`fBExiB#TEJNlomb{Abw8f>JM(sI^ zvcLpI4x>x5I<`=A_{^_@X^Zl;c0eF5N!USWv_e=F692Ynl~4?E?iJqM(U|ZU;%q3q z$D%btF%0m99wc>vn4VBJ;&7^LPPvW5Y^25$!^L`x3cN9tHiIRg@)_yOV}r8D7TK8H zH6P@-FkpB$n^NZxytIi$mYI(MV(ATPkm{sjV`?3v^5ufyGF{P}hKhu22&*9nEFj>pHuC)TZ;RM#|q z;>!5MiOmyNO`14nLVVoBiQ~qv8Z&9k*zxi46UL6ly2im`i8JxH(j{(?Ap>uZ^WSU% zL*w#3t&OwZ$p&4uhIJO3`Sq=>$;;$~LB-wtPt%&vTa_x#7qoM;<@2|Hy&m zGZN`F9m%!JkKFbA*Pq{Zfw!a>cwZh zv+-Se5Oa?g3jNvP83*iqT7+LEoR2-hg}`_xbROsiz*)R2iq8S>Urwm^^Ld8xM;+x4 zGJ^8r%k$d(nE}Fp)j0OzW?|Ql_o(fCU)HOVR*NBxV^1#)xoe+N3_a-OMa@7=9nj(( z@zs4;dL51p^xFP!9QG}d1N=IqKlt|kD*M=o9_jsB$me1=u|sx47l?1(SIoxA`||Ex zb>vR$*&4i;na18I$F&wM_5SMrg55ftr3}aO`LN47{aJgXu}fa(d^wJC=yN7{Pc?-j z?_6ek_CM=aEp}^L@gLz=5PbHS1DmVGB4=(ba>hMejo-g?K&JxVM)A+P@yzE@VgGhs zn35gw|6zW!aj0?Q{c_%mUN8I4+1~xn$L(wQ4F~^L$ZfA@ma{poM*MLagYQISeI57h iYDH!%FgtQbI~xa&x$EeY&s+S=9@->si}xwmq$*V3Y|xAoI|pL%I9w{^g|py`?)AR9e!=% zGsd#lCbn$u$R>I+_NGj#E76wf?zVdq8`6nPUw5LTJJGnZIniaer>l#KBIVljs>MXh z3?I$?)f=xly`7**i2|dB=qhk5#r@3=Tod^A<4aU5xT*YR2Kz6c!+_xP$4BdLVO9QL z?y5;<;d3YKu4JU2=)X7+gFpL-3c>5Wo~UK8>`ZimDCCicKwspct9#SidO`nwEdXRP zR_!+^`6P(eS7)-BHc;YQKM)@1dVD>fI!sq}Cf#X6k$t6o__D2bd_A8!qD3B3(3d%` z_^@v#1?bn%xUZJT5boa&CYi}7QG_ZsXv7?~cLB^z8R>g)Cye?lE_4LGAvApUSDa;D zk9qJ{Ofr2t1pxztRt!PF2sjKu;AUx!j~3#JE=tHOJ8eX)ssNQ0RGyoKKh_k}j=?P( z*<=w2WJJWq{0LFPM1+ZgN(xrMmPylK3+|MVPucQOFD9WgG)wd>rF&oAL3CqY>j1 z7>A-o6*3PdO~w^7S3)-++QVc;bMy^+mA?9sx4ClcugzX$SW={vsF+`R`>~l4NAV=&O zny6x8789QoL$;9=8weZQNQw;*Y$GW)5JPmyF$B-DtATSN<7#pDLeww;AjC{2Ui^ZNwV9#R$KnUz07P~FPg-n1WL>&|8 z5Apwwjz7mzqZ~zZY+%h&krV`>#R8=mf`EZ#PB8=l18bdP2m%HcE5#55 zjI$kvAY-#|HgX-t$oakz*WloJT9aLkAz*3{r-*$CaGoa&D`KzI1cDZ^n>4YA2}DlR z8kqQuCK{Po&V-&c?z07b@`tm5W4sD-dkJt(>lIAEmJk;)0U!i4EbdZ>i`j_LdPM9inef(PAAB>} zx7_(;Gm4D;NQxgI*pH<60fPNViXR}@kEHkkg8fK}A0XI|r1$}X{YZ)*AlQ$j_~F#= z_3(i|*)Y_A=WYhju2Nd0Uw1}&jiFmY+wTY3DM33bcNW+ z1crhX%x&zXO6@Ftbp@B|Y$G#?F;Z}qOsGT&&EI`zLBc2K6|rE6#489hp04076fsUwF)cKLmVusoE7(pgQb2d@$ekIx#PP@$XzNLehw?E z-3fFiggrlPAarpG`uH?v=@1qjKii4m^jC+5PZfX@yYpA5{`qXn`(Tv&9~r4! zz6PC1lvKn{8%X-V7 z8@$#=yyc$ngDQ9SL6v(DPN;^1%iZH1m%I3<%iZgrDtDbL)2Xg2mn*-5e<*e&YtFN( zQlE`Ej1(Zhxpsmsu>)PXpFNwu;xVm;{+_HDD8PQpsqcf8+hO$E#wx>D-eS#z+VyS}l6pU+s9-Os*N0hQGaG10ya zQh{$C&Vcf5F2^h9o2y`>t_S(1_I|FXk&<8b%}|j_=X%-&;*9l_GkptGRXyznh9$t4 zGbQy@En^Y$TcE-9l=G!-v-0z1x>^|y}o(8!OMm+8=k4!f&wgrs86)#Q%HAW65ABiH7uBQ6$dF`b-ulARhxJ8S;PpjZ z(d&!H6<=~TG>17ixTCb}+u03^Z_=$#USGzt??a-b)))4f*B5UsIp>BsunrM-qSqJk zSg$W0k3VL88N6eo4?dc?d-gb)!#m&s@7XN1k#?57mwl4+`~LzabJ)oIJ3+~w{dpkH zo{f#z$>=kk-@kx|!`Uabho1+hl%c^n?s1oM zT>RBJ?)5h>$1k9|oz9+S(of;<1U+y0UPNjUA3nsfBYb9eN5W_5oKNb^-t4o#2tDta zy;j_IxZRL?&g?joyTM?43q)C1TcDYDCg)K)XL26md7Iobxo4C^&*b}_a>l7@3y&CZ zRvBgA4I7-N`Que*a+L`_c_J3Fc?fy6#SGMzvcR<^A=kC#amJTi1kGV;%k9&$?_oDA zTSoVZd-vJH&ynoi&IHYZ!JzWlJ(D-U4b&EQqH9Y$*0tsF_+x6z*&h?!zuvn&WB3xf zlpa;Y-2HKo3id}2=UyIoNcoi8A6*6eKFH6!cTblJch2M!*|+TdXvOu-G8@aNWq%nQ zRo@Q)llpF9{)3>TzHy`G)_45V)VGiL{(RCI``du5Q2mAYQ5iBf?pOD*vmA!c{wjJd z4M4zU5f8`()u9wYcY%G{;L|Ja24nnW!Q(mSow$CFx)=1iUTWbKXgT-iW61uTQv)X9 zj+fuN$Qqp=rAXy$6gqp&g^n>s_}szQAU_DS?0rDt3|8z2vWb1s*(83vtnTnUe&}p+ z_SI6VZ&7}5KFx$5n=s4&hmftI}=-J*ByPu8%(D}A-j10P)un^R<7 z4xkO^0n7OHn`J))PC?}aMD1Z<$OALP3#pYvB3kw%+y{sBQ6SU*Nrkj*a5gy4YAPC> zc;elJK{WMDeb$Dd;dbk@zm6Vq=};cB*T4Y}o0GxKf_3x1jWPM`Z*Zdka^fJ6s;ZFP zjz*$3CR zRZBL~6=NPQ!cK_Kd-t?FQNc4YZ8}VSiDbTvMt0tkz28pO^>N_xn1W-1;_pW$v18p~H z3y)9Y!EnZ&H%)DZcuMC9r#f_F$SQAZ=tQw0VdNO1W+^E#9A!TR6GOwL_Ci%HK6#3* zay4%+R2H1sov!ynk1xLDW@rwx7gjqJYS~Y-8VMoio{I zK4+@gTn;Mtd>%Gw9@h9ws72Lnx3tb;9`@85YuU~zyI7kJ1p@;K5 z9=KYLJok#Og8h9SLEe3=dhhTi<`C!fk}Nh$#MZa-Tm+M>>-pk52n^vlU@g3Is-YCB z)@chHrImdKcKJsNl?B?J5lV8P2P{(@oddZC^z!}{5AJw) z_KQ$FZB$$;&jAN9d4DO#ka3zQ@yW?VH#&?)5o~hZ(ijMr;kt@N%@;2+^eYD0VHM3^S2Z1-woq)@5aGZPte)ohco|V(&=H5(4_oggsyv*UqV^n2hC)8wVA zn;LQb0Q5eDaq^;0E_C@|Z8I(#bs!v$g8WZo7T@smf`xM$Ap;2mB!rpZozRDI{VTp0 zkNj3>IEn?npMf`2WDQ9Xue(M`dJLKdwI zT~T1s@gTzo1U@5hg7CKp{=UU+cZ5ESSQL&jj0YM11bBp|N1iB*pzu#Y=f~DxVP_S3 ziPDDf>B1;|JyKs3r_1PlJkOm_@F2WPKtD<=MS3r!5&A>uiNZMThK@zs>BC5r{xigF zFA!-oatio7(Z5DGe+oZ=zAl8OMco$b7m0MaNKNtQsp$HmC`}Rm2JoZwc)>4=EV@VZ zUk?1TXdV5Z0)EQ;YB&Mu{{|;Y|15Zq;M)Y>FZg!^zftf#f`3u){lG2SEs=QvFiJne z7%l27VBh{2V3>iQBkAqHvxrO+#>k&93Y3h)()?TN^M!LTf0!{)7h=Ac;v6ZaxtO;( z!2RG9)0)_Yv3mSshUdGOb`>yX$|tLl^}mu_GST7 zBdAuW{X&hUB|`m3s04mx!2{&+7OI-?YeI~Vv$P)hejmbm-}&zZUgu}aj|fzjEorq-U_$h_`Pss3ANQ5?-wkN^ zxNWQd{=h`qj1ip~TJ&7xp}?vHr_1iq?<0fI)}@|+rHo5G1?nc3V%ZmjIvE~mOhdab z3pEg$U~r~Aq-7W5PQj$dv}~(rlp}s_it!D#%Dw|07 z?4|?O;Xr_vDk`))@=Cy>K1GSw7Tu<0tD`@I>@H2UM}GzC%bL2k=y)JV2Q+n{=y#wV z)6~_4?*&5il%}>8{wJvCH8nQsx59KpQ&XcwpkC9|<3*#a2)&`H9~31(9oN*V!V0T^ zPHO7P!damHB-DU-T}Z1Y@%X+(Re=kvLb_3?li}jxX?U}@OHoD*)}lf>DU_O{Li(fD z4Llon}O z6d6)R7dtZ8FQaBHD+rv6b>y>JHX<+&RJ)dCqc37x>(sK(MSp>(yxW9gKU=KPbW|wL zp3hois2DeH@C@0Lvc}S96eaU8maY~``8k#{LMcDT690&UMAYc+)dJEp?I`AtR($fD4wHTc)G9vw+~J(RnQKh)ErgNE}_&M zRnT57tAou-x<|{FV~UPT$wEPQ+z89oDkW*fgr9 zpJ>_Em;vf_Eh{QG7kkSwEgMlV57ck8>?_g9Mh(5AW#5R-2K8qxJBWpL2K`0Lp0SES z`Oo3eo(zwTony?TLZJpiRk8CyjTVZdw8xr7PYcC){RL|_)#64$<@Np69C}evk`r_2 zCqkVx9*TVpvZI>%v;Uwqm;TYCSxax_Q6Ff{dt*;pwX_+x0PxJXHTEp1ay}%2ip73p z&8I3pDuU{dy=I+Hzt_|O>ow~F+KiJa%Z`IuNdG33TEXhc&qq+m?v4G*s;6E}-5Prn zR9TIZ#bT$dMdY8MsQ%b{RwEtO)B)=~YYElyLmuhjJ?kQRMJUz7#q?`e_JMUVwa;>F zQg9iy%vRK`v2bt&{kx{_jg1Vhr1m*V)*t)8T1knyiaKC@U|mA{gi<{;(=%FjZ!8gP zrsO=wW(BB!)Kn}sFW5qdYaN?)!8No)PW>m116Ez|a{4b#9S3y<-Eu8Tq%1Vm%Y1zH8OfW@d7dTdSfco5pii*W< z3vQsFFLbPYA=plzt5X#6EVz+E^@=(UYBPOasNMA4zyranY5O9Uss6UmO+wv_)%oGz z7P?nc74*$uCw)s(SJ9I}zWXrfzR+O!T!c9a4wZgd4ttcdGrToNN7?+e{W`5at-cy# zeydMAiv0NGdQ{dNn|}#7BXu~e`Dt(!=TD>gX>`tP?ab1Tvw!ARXO^DXra`}maoijj zpvAcJX`&#da2K4$w+X+>y9VDT+*jU$Zxeobb{D=)ICVXOZxhZ`-^JPK1)Pyy#fji` z+yfoM+pM>!lun`D``FP-04>}}zh4l+ozD9O#WX|Ue1Y`>ao-01B?4OorU3bF_5Feo zv>$LBo~twGAo0F=koa7EkoW|BNce|{&)tWJPuPcu&(f!iDa8wDK%_V$qHUSL@dC>Q zRtcOf@IB+~fKBfid#yf(;{%3agK@RG3o0V@tN`%@#*mx@tNmCY4suT ziS9$Rh-VH440 zEQ}EgV+=lfjWM{#F$SNf#u$8Z`cQP{8+_)NZ}6#PzQO06`39ee<{NyznQ!n(rd~Ab z4L*<58+>A^H~1`6Z}4fU-r%!Oy}_rP8OAHIQAVry)@tzSq7^n7@~NQJ;QhbV;GMqJ z;61(7;N82`;PXUEdP#}TDTB`+-K|r{zB|#!!W;W;f}}P**RrQDBf?}X7C(=gSeeCt}lAjIA!>Y4}(7v zp0v>Ip_`2s`dxIJ@w&`ixmYWwKSe$;%IU?ZfwLZuXsz^HDE+oezu1G&Z@ct+zrk5| zzt}t|b_zvWD0T|PPNCQtFP!nh884iJ24}@VX**u*cZ&T^vD_>D_KLL+#qxN;cL={q z^mmE=4&m>TR?kYdJS(GqRxFoDw5vp?N_?miAF9NMJH*;-v39puyF)bZ7Hh9cw!A9Y za?1F6;iJZEkv=G`%B0o9(&|CsKP;_|Nx#PoDmcgZmc;p666YDlk)*}S!c57Ocv=BfpsFS*N}A@M5jTdiv_L+XKFYlIw^y7+C-;Kq-lZuqB9^m z1ERBE@cn|nB=}2$zbtKEmR2W(|CWYq`Cmo)uOj`eKr&^d8nTYhl#!Y|Qa|9-a6s^c z=uFg*H7ASaWRXr0SSQkY4Oyo_bQ(muSm1h*rZi-oHqmJlX*@!3Q*C z&OX8SYsj3#g1@98b502UmWIqR0^(1Aaesh4>=({Hfd|2<3Lh5yguu7J`38Q(&#e*y z>jbVB*pH_QQ^WfNK8&X%_k@q&2@ggc6n%l^LFUv6zFuIvaQX$`C-7n692We9z_*1% zA+aN{F~oLu2|O&EBZ8k0oWiW>53^1}@H&Bw!dWkPzrbC>*(dm6fhPpMEqsbdj{?i_ zW(GY9JS?0ef}aqa3Z%yZ=~3`HfsMjhFL=MeeF7gA{$asS2z*;OR46?PtP|LXw+~ap z>jm!@xJx+u1V1eBh;U8_PDMNme!SPf*afcxtP1xF+$S(mItlYwCvd&MiCD=y=qY-Z z-lg}jhb}d4H6AlwGycW+H{-N1#aw8vHaD4D&3^NC^PA=`%-@@TF$;Wie3$q(`L6Tr z@!jKl(Rb4Ke|;bM&hc;d@Ap6LKjQzTe=454;yE_X#X%~-iMSA_+7hhkBSDP^#gEwT zF}@chT5mlE_)P2vfO{f81pGqu$AFI(9R<9u@EBl4^f!P%EP59(Rrv3KWyRc9S$LP& z!Y?8W-|;it6ZxwvohbIl1lax^Q4@EKdm<%(s_jput!mX8V4KSd819LTg3ernt=(x% z0KQP{ydRqi{9mHXe>28V+1V4pZ^$)%iHz$`fj!dpx)|FWQ@}nv6P*do=PkBV6RQQ> z6KM$XU#|NkVm>kvGmc&e&_vvV!12Qt;60{B=!6VDSz0VcpRXd6+H5qs{v`G6*! zhZY8%4`|{nKLhv$fF|Cb%>up<(4;!zH%|3{CNIto zpw9rB_^aH7z?TD>v;wUS{QC&?z*pg%V&HD60r;i3XESlaT?)7cHVnKAYyy5cY~Wo6 zph;K2hJn+mX#=eW-UevmA1=5IcpA{eUrn|G z-vnsV)v&h^qgalAr9KzV933pXguhzt8`cKN1)n z@b~lmruTCp?m#UMhjz^dIp1dVFuj z_jY{0i0=dVK7{XMlr;i@tWk>ZL_AZV1sArhTi4i;?deQyZ|F>Av$gALXhD5jTRNL< z?zJGXgre|JKB0X?Cw-%JBS6#?e@OT^o6wCM*piiQ{BA{c6VZfv4W>E3ls zU1->q?(R)zmNc!T>`)eKHFS1B#ZkynE!4a{+nesHZm>H$)6#XedTF{lo#|+!rlxk) zMY}SqsO1O;LID}~m7}an|#2*ZmTQ@!biOd4>gON+Zw9i2nj z&3#=%nV0mXIy*LYw52$chl+LZvqL3nT*C-fW-z8<_?{^lMyh6HIDr#~VPwh&H&VlB zH20=@`-bE9ZMYgGG;~-TSJ%^_;s(2~dze-Yc6J!eZ0|`g+KzQ5-Py!z$i`G#T8ds$Q>k;3s)e9C+nYj05*ju+___`Ua+3%*Oi7I(ps%kiB3FUJ|;NKRCr&8E9H zbZ&3y==IuYNo5eaCHPmY(pWCH4Aox(N7rB>z_Kz_*o4H%bjg~N>ik$O?4KJuHuYsh zFK0wWL711OJ5$>P%jV>c$Ez~fk=uH60%zR3FXP{q$_bnnY&q4vJtxpJE&Se&4IP~w zy&mbJ?RthUN@e9>KwJ5EKubDPn+D}dwH_pPK~le;BfDqaQdz(=Et^x_D>I9)!BWiJ zW!SX6EM0t3_d4emb#%AGlwx^`F^?|=naA-IWgcIZVm`}RcJsJ;8AzuxZJUR5-t1wk z#lXYxbnVsCi-1RwV=eohSIxWNsD7KI2aS7-YmTz(5ROSjt3j;kNMEaHPyBLBF`pwn zJ>;0Yb}UWz<`}A15AAfEV|DTJrB*E7rPX33Snk}&$56M!>h?~h--M%|&MJ3VS(354 zguvdeRyJIl+_q8~i?{WrySWTSF>k+@Cixs^iA!(PM@(8_=bTBmFW%Oc?%}fnVI51c zr_D%2tXJATuWl_id16XUeEeJ8!!_?z#j=j>Ye+(j1*(TnLEUZJm#4b1bY;kOA2`CR z_W>NLsk)7!cCoP|wW%BXZbw_zVd-+k0a>k+&FRcm?1x!*iFO%k!P6y_mB?t9vl0}S z;5k+aqXZ7_tR-CQSz6xFma((;#$I&Yp04jsb#BjgWJyXIQumI4VrHT%+Zm%TMz-%Bgy6sjv&;e7mPR;N?We%V)6W*XBQQ+=Jiw4@`G z?ah&DbW$bi#!^gS&T?m1@gbk{F|m;2g)F^drJ*mA!R?2_`PeI#|F$EGR^Z==*d`dCmPJVrma*433&}~@9fr%m zPAT<;Em_**5Nv0dXv%VNVnglf0VSWt#m9R7vU5%S3!l01xd+x19wmRmFhafr837i%jEicyiTs)jn5WK34!I&1dWLI znV}IS+s*jmPz-K)=|V3dEs_GOLTFdge~%FgB&ekS{xG)_+5!d!{A9>uuMw4l5#0i8 zrE{>rX$01&pkE@<1uHKZ@kBhKNHzGburz+jz^^a0f zDV4>`r2AIoOsjUb%<-;Od6&~RM+7a$6%UvFD05B1k5<`8XXSXo{2hI-G|617q|wcw|~P4wuSvMv-{~F()?Mi?{J!rI(B+ zRpY%u_bRbWx~}ZiuH;%EB6^n4+zCzpUhY2WnngtV_qyG)B4`zfBrs%y%BKGPs!3J6 zN_ntfdxEQYQZ+T`a9mB@DQKj(Zszs{OXzEVDCkp&+tVS{z9wFynjF%0ah0BGDudcs zPSe{HY5@P!ZBdTs95kMxn@Un147t%5Y@ww8pz=0XV+S1*2RU*zu5%o@L+)tcEz>G; zHNec0U^u=iUXB#!m>x1sEDiC2fQcCnBur!c=(1wNJPT{aK#?Jr04UQRG2-P~F(Fh! zQ%Rwcp`czKLQgJScVo#Lk@I}kgn((`e<9N<@>%iGIy=kswMJjd^);cdNqwyVyv zH4dxXWtBUugv&}etfb3II;<*}RprNOKAIg##5=^14tAuAIpy)4!U4pJKY$l2aisQb zymaCs%)QL4iuZp-sQpY~4j)%4j|=lqxWimx!&la6jjv|1e;~dyq^|vM6l!~5_P@dFwOUbJY_F@ZH{SoIH1i_2 zxr+N;#r^UA--@Ca`HHJ}$W=TP@Bf1+dXdK+&LIR62`n%nFzHKTJ5FLdPEwIS$#b97 zbMGKE4pQzQ2?t3!NEJ8jigMFjCI-Ok9}u{g6(ub}A`ykTU+{wwEpph0Li`quKWFhD zm$aB8FUzEQR@mL{ZBol-ezs#kFDSWu0bZ09VTcTy| zBNhF2gP%!-xJ3dQ_?zHSA9s2q{N-Cf?rZSxuc5mc_)|XoM>Gq+3>Ts@m71BFSF@qE zrftr=4XJta+UISooi}rCYWBQ&v*&D_SvzyqoYb7Tv+z@9KRb)+GX;Xc0MrM+X!8N% z;nGxtc5T5QSYqHs^_`vewaalv?Z7(@Fv3mUoAFQ_52;vf8UDKOlhoipx+7Efbld4W z-z8)DD(3CO_b1omdnFM4VKshtG!5U)JMg_q3-pEm7Sa2;w7IeQ_^zLiF8hZ+EW7E= zZ|}J4?mzEf8x7~JU5(RhcJ0y6AAS1h^GBaK`oh}AbaqRx-Lv-SL$BZZ`dvp49er}* z+M@@Ker;_o_`{=lHy3N|4Ohby9>A^bPWNK^JZzGmV{{%W>yMUD-AyUs@h4NSlwQ zz{ucma53H( zH{%WQO1x2ChwBQw!(AzwFZlm>TD@cCY~_!-%1`1!`SIl%@qQXX7_gecUtuo6uP-|B zrnrf^@ut`owQ_0I0%;1|EaWNbg`N#ceV)WWp2aqr!OuW~r$@tB`ZYQ>Fly(&*?8lO z7~oC#Xz&|guZw!5kL?&y3RGImFNdTT-wZUl?`}}b&`TEACTYVSvo=c*JF(}Cq!Iiq z-h;DWJ&@=8{#)(VVD&cKajk*f3@qpD&A@LDYTPgTF&_FH$zIXzhVPx8k^OD`SK}>y zC;sDqkHCc8Ww5zPEOO*}@GEN`;U?NFF-Smfz4X6Q^LbXdemGD1>Uv;GLON<(1QY~N`ew#55IP>Pgr+LWX zTELk!7rfcRoeiCh;MC$f3wR3OxxnO4a=_&|uE)G)5#KJ@>O^GuFMac8JLd<_x#!cP S{y!t$Uf|*V5BmR21pXf_mkCG! literal 0 HcmV?d00001 diff --git a/MotorPlant/MotorPlantBusinessLogic/BackUpLogic.cs b/MotorPlant/MotorPlantBusinessLogic/BackUpLogic.cs new file mode 100644 index 0000000..ec4e73f --- /dev/null +++ b/MotorPlant/MotorPlantBusinessLogic/BackUpLogic.cs @@ -0,0 +1,98 @@ +using Microsoft.Extensions.Logging; +using MotorPlantContracts.BindingModels; +using MotorPlantContracts.BusinessLogicsContracts; +using MotorPlantContracts.StoragesContracts; +using MotorPlantDataModels; +using System; +using System.Collections.Generic; +using System.IO.Compression; +using System.Linq; +using System.Reflection; +using System.Runtime.Serialization.Json; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantBusinessLogic.BusinessLogic +{ + public class BackUpLogic : IBackUpLogic + { + private readonly ILogger _logger; + private readonly IBackUpInfo _backUpInfo; + public BackUpLogic(ILogger logger, IBackUpInfo backUpInfo) + { + _logger = logger; + _backUpInfo = backUpInfo; + } + public void CreateBackUp(BackUpSaveBinidngModel model) + { + if (_backUpInfo == null) + { + return; + } + try + { + _logger.LogDebug("Clear folder"); + var dirInfo = new DirectoryInfo(model.FolderName); + if (dirInfo.Exists) + { + foreach (var file in dirInfo.GetFiles()) + { + file.Delete(); + } + } + _logger.LogDebug("Delete archive"); + string fileName = $"{model.FolderName}.zip"; + if (File.Exists(fileName)) + { + File.Delete(fileName); + } + // берем метод для сохранения + _logger.LogDebug("Get assembly"); + var typeIId = typeof(IId); + var assembly = typeIId.Assembly; + if (assembly == null) + { + throw new ArgumentNullException("Сборка не найдена", nameof(assembly)); + } + var types = assembly.GetTypes(); + var method = GetType().GetMethod("SaveToFile", BindingFlags.NonPublic | BindingFlags.Instance); + _logger.LogDebug("Find {count} types", types.Length); + foreach (var type in types) + { + if (type.IsInterface && type.GetInterface(typeIId.Name) != null) + { + var modelType = _backUpInfo.GetTypeByModelInterface(type.Name); + if (modelType == null) + { + throw new InvalidOperationException($"Не найден класс-модель для {type.Name}"); + } + _logger.LogDebug("Call SaveToFile method for {name} type", type.Name); + // вызываем метод на выполнение + method?.MakeGenericMethod(modelType).Invoke(this, new object[] { model.FolderName }); + } + } + _logger.LogDebug("Create zip and remove folder"); + // архивируем + ZipFile.CreateFromDirectory(model.FolderName, fileName); + // удаляем папку + dirInfo.Delete(true); + } + catch (Exception) + { + throw; + } + } + private void SaveToFile(string folderName) where T : class, new() + { + var records = _backUpInfo.GetList(); + if (records == null) + { + _logger.LogWarning("{type} type get null list", typeof(T).Name); + return; + } + var jsonFormatter = new DataContractJsonSerializer(typeof(List)); + using var fs = new FileStream(string.Format("{0}/{1}.json", folderName, typeof(T).Name), FileMode.OpenOrCreate); + jsonFormatter.WriteObject(fs, records); + } + } +} diff --git a/MotorPlant/MotorPlantContracts/Attributes/ColumnAttribute.cs b/MotorPlant/MotorPlantContracts/Attributes/ColumnAttribute.cs new file mode 100644 index 0000000..e9b2332 --- /dev/null +++ b/MotorPlant/MotorPlantContracts/Attributes/ColumnAttribute.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantContracts.Attributes +{ + [AttributeUsage(AttributeTargets.Property)] + public class ColumnAttribute : Attribute + { + public string Title { get; private set; } + public bool Visible { get; private set; } + public int Width { get; private set; } + public GridViewAutoSize GridViewAutoSize { get; private set; } + public bool IsUseAutoSize { get; private set; } + public ColumnAttribute(string title = "", bool visible = true, int width = 0, GridViewAutoSize gridViewAutoSize = GridViewAutoSize.None, bool isUseAutoSize = false) + { + Title = title; + Visible = visible; + Width = width; + GridViewAutoSize = gridViewAutoSize; + IsUseAutoSize = isUseAutoSize; + } + } +} diff --git a/MotorPlant/MotorPlantContracts/Attributes/GridViewAutoSize.cs b/MotorPlant/MotorPlantContracts/Attributes/GridViewAutoSize.cs new file mode 100644 index 0000000..992e7eb --- /dev/null +++ b/MotorPlant/MotorPlantContracts/Attributes/GridViewAutoSize.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantContracts.Attributes +{ + public enum GridViewAutoSize + { + NotSet = 0, + None = 1, + ColumnHeader = 2, + AllCellsExceptHeader = 4, + AllCells = 6, + DisplayedCellsExceptHeader = 8, + DisplayedCells = 10, + Fill = 16 + } +} diff --git a/MotorPlant/MotorPlantContracts/BindingModels/BackUpSaveBinidngModel.cs b/MotorPlant/MotorPlantContracts/BindingModels/BackUpSaveBinidngModel.cs new file mode 100644 index 0000000..742f6c6 --- /dev/null +++ b/MotorPlant/MotorPlantContracts/BindingModels/BackUpSaveBinidngModel.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantContracts.BindingModels +{ + public class BackUpSaveBinidngModel + { + public string FolderName { get; set; } = string.Empty; + } +} diff --git a/MotorPlant/MotorPlantContracts/BusinessLogicsContracts/IBackUpLogic.cs b/MotorPlant/MotorPlantContracts/BusinessLogicsContracts/IBackUpLogic.cs new file mode 100644 index 0000000..1101056 --- /dev/null +++ b/MotorPlant/MotorPlantContracts/BusinessLogicsContracts/IBackUpLogic.cs @@ -0,0 +1,14 @@ +using MotorPlantContracts.BindingModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantContracts.BusinessLogicsContracts +{ + public interface IBackUpLogic + { + void CreateBackUp(BackUpSaveBinidngModel model); + } +} diff --git a/MotorPlant/MotorPlantContracts/DI/DependencyManager.cs b/MotorPlant/MotorPlantContracts/DI/DependencyManager.cs new file mode 100644 index 0000000..3ee20ed --- /dev/null +++ b/MotorPlant/MotorPlantContracts/DI/DependencyManager.cs @@ -0,0 +1,58 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantContracts.DI +{ + public class DependencyManager + { + private readonly IDependencyContainer _dependencyManager; + private static DependencyManager? _manager; + private static readonly object _locjObject = new(); + private DependencyManager() + { + _dependencyManager = new ServiceDependencyContainer(); + } + public static DependencyManager Instance { get { if (_manager == null) { lock (_locjObject) { _manager = new DependencyManager(); } } return _manager; } } + + /// + /// Иницализация библиотек, в которых идут установки зависомстей + /// + public static void InitDependency() + { + var ext = ServiceProviderLoader.GetImplementationExtensions(); + if (ext == null) + { + throw new ArgumentNullException("Отсутствуют компоненты для загрузки зависимостей по модулям"); + } + // регистрируем зависимости + ext.RegisterServices(); + } + /// + /// Регистрация логгера + /// + /// + public void AddLogging(Action configure) => _dependencyManager.AddLogging(configure); + /// + /// Добавление зависимости + /// + /// + /// + public void RegisterType(bool isSingle = false) where U : class, T where T : class => _dependencyManager.RegisterType(isSingle); + /// + /// Добавление зависимости + /// + /// + /// + public void RegisterType(bool isSingle = false) where T : class => _dependencyManager.RegisterType(isSingle); + /// + /// Получение класса со всеми зависмостями + /// + /// + /// + public T Resolve() => _dependencyManager.Resolve(); + } +} diff --git a/MotorPlant/MotorPlantContracts/DI/IDependencyContainer.cs b/MotorPlant/MotorPlantContracts/DI/IDependencyContainer.cs new file mode 100644 index 0000000..1021b53 --- /dev/null +++ b/MotorPlant/MotorPlantContracts/DI/IDependencyContainer.cs @@ -0,0 +1,37 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantContracts.DI +{ + public interface IDependencyContainer + { + /// + /// Регистрация логгера + /// + /// + void AddLogging(Action configure); + /// + /// Добавление зависимости + /// + /// + /// + /// + void RegisterType(bool isSingle) where U : class, T where T : class; + /// + /// Добавление зависимости + /// + /// + /// + void RegisterType(bool isSingle) where T : class; + /// + /// Получение класса со всеми зависмостями + /// + /// + /// + T Resolve(); + } +} diff --git a/MotorPlant/MotorPlantContracts/DI/IImplementationExtension.cs b/MotorPlant/MotorPlantContracts/DI/IImplementationExtension.cs new file mode 100644 index 0000000..24e7a7b --- /dev/null +++ b/MotorPlant/MotorPlantContracts/DI/IImplementationExtension.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantContracts.DI +{ + public interface IImplementationExtension + { + public int Priority { get; } + /// + /// Регистрация сервисов + /// + public void RegisterServices(); + } +} diff --git a/MotorPlant/MotorPlantContracts/DI/ServiceDependencyContainer.cs b/MotorPlant/MotorPlantContracts/DI/ServiceDependencyContainer.cs new file mode 100644 index 0000000..8a13157 --- /dev/null +++ b/MotorPlant/MotorPlantContracts/DI/ServiceDependencyContainer.cs @@ -0,0 +1,56 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantContracts.DI +{ + public class ServiceDependencyContainer : IDependencyContainer + { + private ServiceProvider? _serviceProvider; + private readonly ServiceCollection _serviceCollection; + public ServiceDependencyContainer() + { + _serviceCollection = new ServiceCollection(); + } + public void AddLogging(Action configure) + { + _serviceCollection.AddLogging(configure); + } + public void RegisterType(bool isSingle) where U : class, T where T : class + { + if (isSingle) + { + _serviceCollection.AddSingleton(); + } + else + { + _serviceCollection.AddTransient(); + } + _serviceProvider = null; + } + public void RegisterType(bool isSingle) where T : class + { + if (isSingle) + { + _serviceCollection.AddSingleton(); + } + else + { + _serviceCollection.AddTransient(); + } + _serviceProvider = null; + } + public T Resolve() + { + if (_serviceProvider == null) + { + _serviceProvider = _serviceCollection.BuildServiceProvider(); + } + return _serviceProvider.GetService()!; + } + } +} diff --git a/MotorPlant/MotorPlantContracts/DI/ServiceProviderLoader.cs b/MotorPlant/MotorPlantContracts/DI/ServiceProviderLoader.cs new file mode 100644 index 0000000..c045c9f --- /dev/null +++ b/MotorPlant/MotorPlantContracts/DI/ServiceProviderLoader.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantContracts.DI +{ + public class ServiceProviderLoader + { + /// + /// Загрузка всех классов-реализаций IImplementationExtension + /// + /// + public static IImplementationExtension? GetImplementationExtensions() + { + IImplementationExtension? source = null; + var files = Directory.GetFiles(TryGetImplementationExtensionsFolder(), "*.dll", SearchOption.AllDirectories); + foreach (var file in files.Distinct()) + { + Assembly asm = Assembly.LoadFrom(file); + foreach (var t in asm.GetExportedTypes()) + { + if (t.IsClass && typeof(IImplementationExtension).IsAssignableFrom(t)) + { + if (source == null) + { + source = (IImplementationExtension)Activator.CreateInstance(t)!; + } + else + { + var newSource = (IImplementationExtension)Activator.CreateInstance(t)!; + if (newSource.Priority > source.Priority) + { + source = newSource; + } + } + } + } + } + return source; + } + private static string TryGetImplementationExtensionsFolder() + { + var directory = new DirectoryInfo(Directory.GetCurrentDirectory()); + while (directory != null && !directory.GetDirectories("ImplementationExtensions", SearchOption.AllDirectories).Any(x => x.Name == "ImplementationExtensions")) + { + directory = directory.Parent; + } + return $"{directory?.FullName}\\ImplementationExtensions"; + } + } +} diff --git a/MotorPlant/MotorPlantContracts/StoragesContracts/IBackUpInfo.cs b/MotorPlant/MotorPlantContracts/StoragesContracts/IBackUpInfo.cs new file mode 100644 index 0000000..1911d22 --- /dev/null +++ b/MotorPlant/MotorPlantContracts/StoragesContracts/IBackUpInfo.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantContracts.StoragesContracts +{ + public interface IBackUpInfo + { + List? GetList() where T : class, new(); + Type? GetTypeByModelInterface(string modelInterfaceName); + } +} diff --git a/MotorPlant/MotorPlantDatabaseImplement/BackUpInfo.cs b/MotorPlant/MotorPlantDatabaseImplement/BackUpInfo.cs new file mode 100644 index 0000000..424b9e9 --- /dev/null +++ b/MotorPlant/MotorPlantDatabaseImplement/BackUpInfo.cs @@ -0,0 +1,31 @@ +using MotorPlantContracts.StoragesContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantDatabaseImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + using var context = new MotorPlantDataBase(); + return context.Set().ToList(); + } + public Type? GetTypeByModelInterface(string modelInterfaceName) + { + var assembly = typeof(BackUpInfo).Assembly; + var types = assembly.GetTypes(); + foreach (var type in types) + { + if (type.IsClass && type.GetInterface(modelInterfaceName) != null) + { + return type; + } + } + return null; + } + } +} diff --git a/MotorPlant/MotorPlantDatabaseImplement/ImplementationExtension.cs b/MotorPlant/MotorPlantDatabaseImplement/ImplementationExtension.cs new file mode 100644 index 0000000..2e711fe --- /dev/null +++ b/MotorPlant/MotorPlantDatabaseImplement/ImplementationExtension.cs @@ -0,0 +1,21 @@ +using MotorPlantContracts.DI; +using MotorPlantContracts.StoragesContracts; +using MotorPlantDatabaseImplement.Implements; + +namespace MotorPlantDatabaseImplement +{ + public class ImplementationExtension : IImplementationExtension + { + public int Priority => 3; + public void RegisterServices() + { + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + } + } +} diff --git a/MotorPlant/MotorPlantDatabaseImplement/Migrations/20240620185256_InitialCreate.Designer.cs b/MotorPlant/MotorPlantDatabaseImplement/Migrations/20240620185256_InitialCreate.Designer.cs new file mode 100644 index 0000000..af1ec98 --- /dev/null +++ b/MotorPlant/MotorPlantDatabaseImplement/Migrations/20240620185256_InitialCreate.Designer.cs @@ -0,0 +1,296 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using MotorPlantDatabaseImplement; + +#nullable disable + +namespace MotorPlantDatabaseImplement.Migrations +{ + [DbContext(typeof(MotorPlantDataBase))] + [Migration("20240620185256_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClientFIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Component", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ComponentName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Cost") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("Components"); + }); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Engine", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("EngineName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Price") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("Engines"); + }); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.EngineComponent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ComponentId") + .HasColumnType("int"); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("EngineId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ComponentId"); + + b.HasIndex("EngineId"); + + b.ToTable("EngineComponents"); + }); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Implementer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ImplementerFIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Qualification") + .HasColumnType("int"); + + b.Property("WorkExperience") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Implementers"); + }); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.MessageInfo", b => + { + b.Property("MessageId") + .HasColumnType("nvarchar(450)"); + + b.Property("Body") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("DateDelivery") + .HasColumnType("datetime2"); + + b.Property("SenderName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Subject") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("MessageId"); + + b.HasIndex("ClientId"); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("DateCreate") + .HasColumnType("datetime2"); + + b.Property("DateImplement") + .HasColumnType("datetime2"); + + b.Property("EngineId") + .HasColumnType("int"); + + b.Property("ImplementerId") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Sum") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.HasIndex("EngineId"); + + b.HasIndex("ImplementerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.EngineComponent", b => + { + b.HasOne("MotorPlantDatabaseImplement.Models.Component", "Component") + .WithMany("EngineComponents") + .HasForeignKey("ComponentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MotorPlantDatabaseImplement.Models.Engine", "Engine") + .WithMany("Components") + .HasForeignKey("EngineId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Component"); + + b.Navigation("Engine"); + }); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.MessageInfo", b => + { + b.HasOne("MotorPlantDatabaseImplement.Models.Client", "Client") + .WithMany() + .HasForeignKey("ClientId"); + + b.Navigation("Client"); + }); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Order", b => + { + b.HasOne("MotorPlantDatabaseImplement.Models.Client", "Client") + .WithMany("Orders") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MotorPlantDatabaseImplement.Models.Engine", "Engine") + .WithMany("Orders") + .HasForeignKey("EngineId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MotorPlantDatabaseImplement.Models.Implementer", "Implementer") + .WithMany("Orders") + .HasForeignKey("ImplementerId"); + + b.Navigation("Client"); + + b.Navigation("Engine"); + + b.Navigation("Implementer"); + }); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Client", b => + { + b.Navigation("Orders"); + }); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Component", b => + { + b.Navigation("EngineComponents"); + }); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Engine", b => + { + b.Navigation("Components"); + + b.Navigation("Orders"); + }); + + modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Implementer", b => + { + b.Navigation("Orders"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/MotorPlant/MotorPlantDatabaseImplement/Migrations/20240620185256_InitialCreate.cs b/MotorPlant/MotorPlantDatabaseImplement/Migrations/20240620185256_InitialCreate.cs new file mode 100644 index 0000000..7dae505 --- /dev/null +++ b/MotorPlant/MotorPlantDatabaseImplement/Migrations/20240620185256_InitialCreate.cs @@ -0,0 +1,214 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MotorPlantDatabaseImplement.Migrations +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Clients", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ClientFIO = table.Column(type: "nvarchar(max)", nullable: false), + Email = table.Column(type: "nvarchar(max)", nullable: false), + Password = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Clients", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Components", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ComponentName = table.Column(type: "nvarchar(max)", nullable: false), + Cost = table.Column(type: "float", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Components", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Engines", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + EngineName = table.Column(type: "nvarchar(max)", nullable: false), + Price = table.Column(type: "float", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Engines", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Implementers", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ImplementerFIO = table.Column(type: "nvarchar(max)", nullable: false), + Password = table.Column(type: "nvarchar(max)", nullable: false), + Qualification = table.Column(type: "int", nullable: false), + WorkExperience = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Implementers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Messages", + columns: table => new + { + MessageId = table.Column(type: "nvarchar(450)", nullable: false), + ClientId = table.Column(type: "int", nullable: true), + SenderName = table.Column(type: "nvarchar(max)", nullable: false), + DateDelivery = table.Column(type: "datetime2", nullable: false), + Subject = table.Column(type: "nvarchar(max)", nullable: false), + Body = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Messages", x => x.MessageId); + table.ForeignKey( + name: "FK_Messages_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "EngineComponents", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + EngineId = table.Column(type: "int", nullable: false), + ComponentId = table.Column(type: "int", nullable: false), + Count = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EngineComponents", x => x.Id); + table.ForeignKey( + name: "FK_EngineComponents_Components_ComponentId", + column: x => x.ComponentId, + principalTable: "Components", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_EngineComponents_Engines_EngineId", + column: x => x.EngineId, + principalTable: "Engines", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Orders", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Count = table.Column(type: "int", nullable: false), + Sum = table.Column(type: "float", nullable: false), + Status = table.Column(type: "int", nullable: false), + DateCreate = table.Column(type: "datetime2", nullable: false), + DateImplement = table.Column(type: "datetime2", nullable: true), + EngineId = table.Column(type: "int", nullable: false), + ClientId = table.Column(type: "int", nullable: false), + ImplementerId = table.Column(type: "int", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Orders", x => x.Id); + table.ForeignKey( + name: "FK_Orders_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Orders_Engines_EngineId", + column: x => x.EngineId, + principalTable: "Engines", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Orders_Implementers_ImplementerId", + column: x => x.ImplementerId, + principalTable: "Implementers", + principalColumn: "Id"); + }); + + migrationBuilder.CreateIndex( + name: "IX_EngineComponents_ComponentId", + table: "EngineComponents", + column: "ComponentId"); + + migrationBuilder.CreateIndex( + name: "IX_EngineComponents_EngineId", + table: "EngineComponents", + column: "EngineId"); + + migrationBuilder.CreateIndex( + name: "IX_Messages_ClientId", + table: "Messages", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_ClientId", + table: "Orders", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_EngineId", + table: "Orders", + column: "EngineId"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_ImplementerId", + table: "Orders", + column: "ImplementerId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "EngineComponents"); + + migrationBuilder.DropTable( + name: "Messages"); + + migrationBuilder.DropTable( + name: "Orders"); + + migrationBuilder.DropTable( + name: "Components"); + + migrationBuilder.DropTable( + name: "Clients"); + + migrationBuilder.DropTable( + name: "Engines"); + + migrationBuilder.DropTable( + name: "Implementers"); + } + } +} diff --git a/MotorPlant/MotorPlantFileImplement/BackUpInfo.cs b/MotorPlant/MotorPlantFileImplement/BackUpInfo.cs new file mode 100644 index 0000000..53ecfd7 --- /dev/null +++ b/MotorPlant/MotorPlantFileImplement/BackUpInfo.cs @@ -0,0 +1,41 @@ +using MotorPlantContracts.StoragesContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantFileImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + private readonly DataFileSingleton source; + private readonly PropertyInfo[] sourceProperties; + public BackUpInfo() + { + source = DataFileSingleton.GetInstance(); + sourceProperties = source.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); + } + public List? GetList() where T : class, new() + { + var requredType = typeof(T); + return (List?)sourceProperties.FirstOrDefault(x => x.PropertyType.IsGenericType && x.PropertyType.GetGenericArguments()[0] == requredType) + ?.GetValue(source); + + } + public Type? GetTypeByModelInterface(string modelInterfaceName) + { + var assembly = typeof(BackUpInfo).Assembly; + var types = assembly.GetTypes(); + foreach (var type in types) + { + if (type.IsClass && type.GetInterface(modelInterfaceName) != null) + { + return type; + } + } + return null; + } + } +} diff --git a/MotorPlant/MotorPlantFileImplement/ImplementationExtension.cs b/MotorPlant/MotorPlantFileImplement/ImplementationExtension.cs new file mode 100644 index 0000000..a028733 --- /dev/null +++ b/MotorPlant/MotorPlantFileImplement/ImplementationExtension.cs @@ -0,0 +1,21 @@ +using MotorPlantContracts.DI; +using MotorPlantContracts.StoragesContracts; +using MotorPlantFileImplement.Implements; + +namespace MotorPlantFileImplement +{ + public class ImplementationExtension : IImplementationExtension + { + public int Priority => 1; + public void RegisterServices() + { + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + } + } +} diff --git a/MotorPlant/MotorPlantListImplement/BackUpInfo.cs b/MotorPlant/MotorPlantListImplement/BackUpInfo.cs new file mode 100644 index 0000000..3a224b1 --- /dev/null +++ b/MotorPlant/MotorPlantListImplement/BackUpInfo.cs @@ -0,0 +1,21 @@ +using MotorPlantContracts.StoragesContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MotorPlantListImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + throw new NotImplementedException(); + } + public Type? GetTypeByModelInterface(string modelInterfaceName) + { + throw new NotImplementedException(); + } + } +} diff --git a/MotorPlant/MotorPlantListImplement/ImplementationExtension.cs b/MotorPlant/MotorPlantListImplement/ImplementationExtension.cs new file mode 100644 index 0000000..670794e --- /dev/null +++ b/MotorPlant/MotorPlantListImplement/ImplementationExtension.cs @@ -0,0 +1,21 @@ +using MotorPlantContracts.DI; +using MotorPlantContracts.StoragesContracts; +using MotorPlantListImplement.Implements; + +namespace MotorPlantListImplement +{ + internal class ImplementationExtension : IImplementationExtension + { + public int Priority => 0; + public void RegisterServices() + { + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + } + } +} diff --git a/MotorPlant/MotorPlantView/DataGridViewExtension.cs b/MotorPlant/MotorPlantView/DataGridViewExtension.cs new file mode 100644 index 0000000..20a88f3 --- /dev/null +++ b/MotorPlant/MotorPlantView/DataGridViewExtension.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MotorPlantContracts.Attributes; + +namespace MotorPlantView.Forms +{ + internal static class DataGridViewExtension + { + public static void FillAndConfigGrid(this DataGridView grid, List? data) + { + if (data == null) + { + return; + } + grid.DataSource = data; + + var type = typeof(T); + var properties = type.GetProperties(); + foreach (DataGridViewColumn column in grid.Columns) + { + var property = properties.FirstOrDefault(x => x.Name == column.Name); + if (property == null) + { + throw new InvalidOperationException($"В типе {type.Name} не найдено свойство с именем {column.Name}"); + } + var attribute = property.GetCustomAttributes(typeof(ColumnAttribute), true)?.SingleOrDefault(); + if (attribute == null) + { + throw new InvalidOperationException($"Не найден атрибут типа ColumnAttribute для свойства {property.Name}"); + } + + if (attribute is ColumnAttribute columnAttr) + { + column.HeaderText = columnAttr.Title; + column.Visible = columnAttr.Visible; + if (columnAttr.IsUseAutoSize) + { + column.AutoSizeMode = (DataGridViewAutoSizeColumnMode)Enum.Parse(typeof(DataGridViewAutoSizeColumnMode), columnAttr.GridViewAutoSize.ToString()); + } + else + { + column.Width = columnAttr.Width; + } + } + } + } + } +}