mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-23 11:51:09 +08:00
Compare commits
776 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a64ab7df4e | ||
![]() |
82cd64cb50 | ||
![]() |
065bfb8694 | ||
![]() |
6db335cf87 | ||
![]() |
155f4670e9 | ||
![]() |
50522b571a | ||
![]() |
8e138863ce | ||
![]() |
7d8dfe628d | ||
![]() |
8baed5b306 | ||
![]() |
41a5ffd214 | ||
![]() |
c6aec3a1af | ||
![]() |
22e30f7a62 | ||
![]() |
57711b8ab5 | ||
![]() |
90ff1259ea | ||
![]() |
d88fc5ccd7 | ||
![]() |
5aaca2aa9c | ||
![]() |
8b9ca56e17 | ||
![]() |
e4f3772e6d | ||
![]() |
d58ec81d20 | ||
![]() |
415aae44b6 | ||
![]() |
a533286658 | ||
![]() |
e59f91cd82 | ||
![]() |
5f8b85d8a4 | ||
![]() |
47c7b88436 | ||
![]() |
90006782f2 | ||
![]() |
c3d49cbe70 | ||
![]() |
112323a360 | ||
![]() |
9d08c90fda | ||
![]() |
602d24deec | ||
![]() |
a2b9f66785 | ||
![]() |
7cbf289b50 | ||
![]() |
4097da79a5 | ||
![]() |
91b7ae554f | ||
![]() |
3121aa2542 | ||
![]() |
4bf895e6e1 | ||
![]() |
0c5489e920 | ||
![]() |
d63c3aaa80 | ||
![]() |
4f188ea6cc | ||
![]() |
acb17018ae | ||
![]() |
2affe2988d | ||
![]() |
4174dd2206 | ||
![]() |
e1c492f238 | ||
![]() |
fb08e34fa3 | ||
![]() |
a1793a0afe | ||
![]() |
4da9763b49 | ||
![]() |
81e0918bd0 | ||
![]() |
c1e064f06d | ||
![]() |
1c52be8b47 | ||
![]() |
bcd82055ca | ||
![]() |
c47d95d170 | ||
![]() |
3e62f1ad51 | ||
![]() |
8dcae973ef | ||
![]() |
4cf35f7294 | ||
![]() |
94c77d151b | ||
![]() |
7f600e2b4b | ||
![]() |
c809d0ba87 | ||
![]() |
50f038ec89 | ||
![]() |
9199a255a2 | ||
![]() |
d324537b47 | ||
![]() |
d0c05685f7 | ||
![]() |
1063c930b5 | ||
![]() |
79cbd44366 | ||
![]() |
7fdac1c5cb | ||
![]() |
0c0cf72ebb | ||
![]() |
8e2fe175ed | ||
![]() |
d1cff037c9 | ||
![]() |
fc88a2fafa | ||
![]() |
45fcceb056 | ||
![]() |
7043477038 | ||
![]() |
7dd685cf54 | ||
![]() |
5f5e4969c0 | ||
![]() |
8a53fd19e9 | ||
![]() |
baf4714c36 | ||
![]() |
7ba9ac7a5b | ||
![]() |
85b8f26e8e | ||
![]() |
594a0f1410 | ||
![]() |
d317d757d7 | ||
![]() |
fdf0ba6318 | ||
![]() |
15bf7de5fa | ||
![]() |
d3402b058e | ||
![]() |
e7dfdd4031 | ||
![]() |
b2dd7b6364 | ||
![]() |
9bd6d9abbf | ||
![]() |
cd14428fea | ||
![]() |
19d9f03c2b | ||
![]() |
0d57e72bbf | ||
![]() |
329516a61b | ||
![]() |
d566869589 | ||
![]() |
9cb8d8e6c7 | ||
![]() |
9de3c57e5d | ||
![]() |
f32ff92b0b | ||
![]() |
88d71e271e | ||
![]() |
fd9c14612a | ||
![]() |
e26e5a160f | ||
![]() |
b836bfed22 | ||
![]() |
a4b598c6d0 | ||
![]() |
c9ab755839 | ||
![]() |
9920edba53 | ||
![]() |
12bd7280d1 | ||
![]() |
d30ea7f63b | ||
![]() |
ebd3390db6 | ||
![]() |
9a374a9ebc | ||
![]() |
b1bc22cb08 | ||
![]() |
4930d53890 | ||
![]() |
c31327b5bc | ||
![]() |
3f2aa1f1e1 | ||
![]() |
6e78c00a96 | ||
![]() |
c27dde085e | ||
![]() |
d26cc308c0 | ||
![]() |
fb1efdf290 | ||
![]() |
3c99f2a472 | ||
![]() |
affe9a44e0 | ||
![]() |
43730fa519 | ||
![]() |
d39aa22b09 | ||
![]() |
e232a6b6ea | ||
![]() |
71ebb36fe9 | ||
![]() |
78a0b86327 | ||
![]() |
2636c16a97 | ||
![]() |
fd77c0242d | ||
![]() |
e74819a900 | ||
![]() |
9b7f696c9b | ||
![]() |
0230d614e7 | ||
![]() |
252d99ad78 | ||
![]() |
1ffc200350 | ||
![]() |
807d89b2b2 | ||
![]() |
4013afa1f1 | ||
![]() |
a580927ceb | ||
![]() |
bf2cf52034 | ||
![]() |
81bb8b7c31 | ||
![]() |
a825007fb5 | ||
![]() |
988124d96a | ||
![]() |
f0de815296 | ||
![]() |
0e2d58c887 | ||
![]() |
b155382626 | ||
![]() |
f362d740af | ||
![]() |
4a85e31a4f | ||
![]() |
302c270ad5 | ||
![]() |
3c1517d0f3 | ||
![]() |
f9fb222044 | ||
![]() |
e8edc02ba3 | ||
![]() |
95a44e3053 | ||
![]() |
74a9fe9a87 | ||
![]() |
4d03f9ea1a | ||
![]() |
67c96ca991 | ||
![]() |
88fb793c68 | ||
![]() |
d6d02d8cc5 | ||
![]() |
c5a3f8e2e3 | ||
![]() |
27e8653a1a | ||
![]() |
863beda82c | ||
![]() |
bac84c3ecd | ||
![]() |
2fca2ad9f8 | ||
![]() |
dd75286fe0 | ||
![]() |
7f91792cf1 | ||
![]() |
0e0ccad311 | ||
![]() |
0691f72e67 | ||
![]() |
7e38a51720 | ||
![]() |
34ca8243a3 | ||
![]() |
112fea7632 | ||
![]() |
378763e4ee | ||
![]() |
517bd0394d | ||
![]() |
70adb97fb5 | ||
![]() |
623d44cabe | ||
![]() |
0d479ca00b | ||
![]() |
8bc49ef437 | ||
![]() |
f83fcec786 | ||
![]() |
93690ce40d | ||
![]() |
f82c5f2f27 | ||
![]() |
a83c1c3899 | ||
![]() |
91d6aed109 | ||
![]() |
db8f8fe51d | ||
![]() |
4596004b17 | ||
![]() |
d5540906cb | ||
![]() |
90796a979d | ||
![]() |
2190a87772 | ||
![]() |
c5953b83f8 | ||
![]() |
24bc60abf0 | ||
![]() |
31eee6b009 | ||
![]() |
c5da565a8f | ||
![]() |
947cd712e1 | ||
![]() |
edc208f96b | ||
![]() |
1fb0296ee7 | ||
![]() |
6488d3df87 | ||
![]() |
56189d78e0 | ||
![]() |
bff18127b8 | ||
![]() |
363206e0ba | ||
![]() |
fd3e378501 | ||
![]() |
4ba2fe4c9d | ||
![]() |
2c499626ad | ||
![]() |
2b581a03c3 | ||
![]() |
450c15210a | ||
![]() |
65fed8cc93 | ||
![]() |
4b64771ea2 | ||
![]() |
f39977a6ff | ||
![]() |
933b535caa | ||
![]() |
8abc5d2f20 | ||
![]() |
d8783cd994 | ||
![]() |
d5d087feb5 | ||
![]() |
6ba3399df7 | ||
![]() |
65124b3aa8 | ||
![]() |
98597f4726 | ||
![]() |
e7981f0d8e | ||
![]() |
cf654427c3 | ||
![]() |
ff2f628282 | ||
![]() |
ae818ca265 | ||
![]() |
0f2aed458e | ||
![]() |
d486c44ff6 | ||
![]() |
ca7b9980bf | ||
![]() |
3c71e6a8e3 | ||
![]() |
542442864c | ||
![]() |
5edb64fa85 | ||
![]() |
8dc1c898a3 | ||
![]() |
1ed35726b0 | ||
![]() |
27fae9ebaa | ||
![]() |
b103f25c94 | ||
![]() |
abff450274 | ||
![]() |
c260736a11 | ||
![]() |
166ac2307a | ||
![]() |
b21a4e1a4d | ||
![]() |
f7dc943fa3 | ||
![]() |
bfbd2693ec | ||
![]() |
819e71c993 | ||
![]() |
9fd0b489a2 | ||
![]() |
f5fe9f8dae | ||
![]() |
f9ffc18145 | ||
![]() |
08db5b983a | ||
![]() |
5b3b4c8c50 | ||
![]() |
73f914ffc4 | ||
![]() |
d6bdd73ed6 | ||
![]() |
7370ee7349 | ||
![]() |
4574596bac | ||
![]() |
4d16855e36 | ||
![]() |
13a0d4d282 | ||
![]() |
b9cd06b829 | ||
![]() |
5b460e8fa2 | ||
![]() |
41087edf17 | ||
![]() |
2afcc38e38 | ||
![]() |
e59ccce25f | ||
![]() |
d7425890e8 | ||
![]() |
a989a837fb | ||
![]() |
db1221da50 | ||
![]() |
cf794569ed | ||
![]() |
51e5bbab0d | ||
![]() |
2c197ed2b2 | ||
![]() |
d8fc6665b3 | ||
![]() |
c671a79822 | ||
![]() |
9d93ce4c41 | ||
![]() |
a6d99fe227 | ||
![]() |
923b8bca31 | ||
![]() |
e2c30d1c88 | ||
![]() |
b6d9f2a04e | ||
![]() |
57306ea664 | ||
![]() |
cd7f3fd02f | ||
![]() |
0482e077a8 | ||
![]() |
5f986a45ca | ||
![]() |
ca7b49c0d5 | ||
![]() |
52dd555e6c | ||
![]() |
579b1a59f9 | ||
![]() |
5299c5c4be | ||
![]() |
f7756bccef | ||
![]() |
a6b874d160 | ||
![]() |
3e5fb3ddcf | ||
![]() |
5e6bcb12d3 | ||
![]() |
14303f1429 | ||
![]() |
96711ba022 | ||
![]() |
cbfc0fdbdc | ||
![]() |
6e81886c0e | ||
![]() |
2d976bc132 | ||
![]() |
57f6a476af | ||
![]() |
8491ed296e | ||
![]() |
cd1288afdc | ||
![]() |
ec6c830cb0 | ||
![]() |
2f86ccc4bf | ||
![]() |
8ca445aec0 | ||
![]() |
1e1f27c8a5 | ||
![]() |
2b84bde367 | ||
![]() |
b52e58551d | ||
![]() |
9aceed00bf | ||
![]() |
58814f7f74 | ||
![]() |
6a70ef9f31 | ||
![]() |
82cc4ca500 | ||
![]() |
4567fa04ed | ||
![]() |
8b98b5d818 | ||
![]() |
176d0351af | ||
![]() |
d63dc3384b | ||
![]() |
1ccd704e30 | ||
![]() |
f5d23dbe79 | ||
![]() |
75bfe53ac3 | ||
![]() |
3308f916dd | ||
![]() |
e7140279ca | ||
![]() |
1034719f5e | ||
![]() |
2c00043a7f | ||
![]() |
65c695d9ce | ||
![]() |
57253fe46a | ||
![]() |
4e5c443440 | ||
![]() |
0b3b73d8ec | ||
![]() |
921eabc134 | ||
![]() |
0faa428751 | ||
![]() |
f71a2fdd63 | ||
![]() |
4eb9ed8aba | ||
![]() |
d7b549abb8 | ||
![]() |
95d723c578 | ||
![]() |
2fcd853e86 | ||
![]() |
07eef7c812 | ||
![]() |
b01e0757fa | ||
![]() |
32844a20c6 | ||
![]() |
5b6532c601 | ||
![]() |
2c5b4b4027 | ||
![]() |
72d7ecf195 | ||
![]() |
2cfa6b4306 | ||
![]() |
6f6ffde0ab | ||
![]() |
1694739a16 | ||
![]() |
95d1e8bfca | ||
![]() |
60dec08e3c | ||
![]() |
a99d71be93 | ||
![]() |
f1331b6a0c | ||
![]() |
10d66b642b | ||
![]() |
cd2310e4a8 | ||
![]() |
1b399cf6b0 | ||
![]() |
877445bc0a | ||
![]() |
9a5b345bde | ||
![]() |
fc9e8ea7b3 | ||
![]() |
32be6fcfc1 | ||
![]() |
49847236c2 | ||
![]() |
d8424443e6 | ||
![]() |
f3b571ec3f | ||
![]() |
99318bb5d7 | ||
![]() |
1aa154c9aa | ||
![]() |
c65d8a445b | ||
![]() |
80f4f85570 | ||
![]() |
5beee43a6b | ||
![]() |
8d6ae203a0 | ||
![]() |
4353479a5c | ||
![]() |
34d7687f9e | ||
![]() |
b1dc3cf4af | ||
![]() |
6a58b95933 | ||
![]() |
d3badfd02b | ||
![]() |
0098be057b | ||
![]() |
6f972aa515 | ||
![]() |
7407ba6313 | ||
![]() |
1c79de207b | ||
![]() |
257c79db92 | ||
![]() |
9d1934a308 | ||
![]() |
d70f959902 | ||
![]() |
e4d810222f | ||
![]() |
bc1af4ae07 | ||
![]() |
6e688ef43f | ||
![]() |
f0fe1b23dc | ||
![]() |
aaf2006401 | ||
![]() |
b821e26935 | ||
![]() |
7ae4287157 | ||
![]() |
c6fcc38a65 | ||
![]() |
ab2d5c8853 | ||
![]() |
5e557ff0bc | ||
![]() |
918ca449a1 | ||
![]() |
8e73368008 | ||
![]() |
f3c1faf672 | ||
![]() |
d6df04dd6a | ||
![]() |
b1b9e51ab6 | ||
![]() |
e49d4770ac | ||
![]() |
8fa1075511 | ||
![]() |
9a70169b94 | ||
![]() |
fefb928237 | ||
![]() |
ad7e700d0d | ||
![]() |
1699c69147 | ||
![]() |
1695f7cece | ||
![]() |
052c27f907 | ||
![]() |
dc46c32b30 | ||
![]() |
fa63349bb2 | ||
![]() |
ffe26448a6 | ||
![]() |
4af51e8a84 | ||
![]() |
1e453cf5a5 | ||
![]() |
591282b87d | ||
![]() |
e87528d520 | ||
![]() |
d79eb0411d | ||
![]() |
ac1e0a4cf7 | ||
![]() |
9525eab130 | ||
![]() |
89b317496c | ||
![]() |
13be91e78b | ||
![]() |
f68c1437f3 | ||
![]() |
4c64c969bb | ||
![]() |
b4bf3b5138 | ||
![]() |
083bc4b400 | ||
![]() |
e8683c5bcc | ||
![]() |
80e0d1de91 | ||
![]() |
dbe841037e | ||
![]() |
bdd537c33c | ||
![]() |
c0c3846094 | ||
![]() |
9e8710e7d2 | ||
![]() |
475553fdf6 | ||
![]() |
9d570f5b45 | ||
![]() |
af7fafd34f | ||
![]() |
d43130f4fc | ||
![]() |
7500194620 | ||
![]() |
eb27c29144 | ||
![]() |
43260b3e24 | ||
![]() |
f80713f0aa | ||
![]() |
0c4bdc7ad1 | ||
![]() |
811cff7bd0 | ||
![]() |
30269aa75c | ||
![]() |
e345ef7083 | ||
![]() |
f559c9b8f7 | ||
![]() |
f4af0916b2 | ||
![]() |
f15f14f28d | ||
![]() |
834f44f58d | ||
![]() |
b36f45dcf4 | ||
![]() |
11ba21c9a8 | ||
![]() |
b045557ce1 | ||
![]() |
0dd251a3f6 | ||
![]() |
793acb1725 | ||
![]() |
921243e8bd | ||
![]() |
bd9d7a90d9 | ||
![]() |
cc444a4cea | ||
![]() |
38ca1fa168 | ||
![]() |
7a552b87ec | ||
![]() |
36923d3190 | ||
![]() |
a9d3017123 | ||
![]() |
313acd4976 | ||
![]() |
a4c91bb268 | ||
![]() |
f9b566984b | ||
![]() |
8dd261854d | ||
![]() |
7351e62d87 | ||
![]() |
0593ae720b | ||
![]() |
a0a7b08e08 | ||
![]() |
9a3bc6b8b3 | ||
![]() |
5acae17f71 | ||
![]() |
f1e5b76ef2 | ||
![]() |
53c628fde9 | ||
![]() |
baca0a70c0 | ||
![]() |
3e8d0af404 | ||
![]() |
cf9a91d9d5 | ||
![]() |
02b9e282c6 | ||
![]() |
9ce87f235f | ||
![]() |
e329bea1b2 | ||
![]() |
8086e7b54d | ||
![]() |
f7a875606e | ||
![]() |
196eaf85f4 | ||
![]() |
876a55668e | ||
![]() |
05bd21bdd5 | ||
![]() |
fb51a08cc6 | ||
![]() |
dd83d7f4d3 | ||
![]() |
842a56f7ce | ||
![]() |
9246a6e797 | ||
![]() |
8ad693f717 | ||
![]() |
f4c2ee7cc4 | ||
![]() |
6043441faa | ||
![]() |
4a065c3710 | ||
![]() |
0ef800bdd7 | ||
![]() |
56eaa1910d | ||
![]() |
201788e286 | ||
![]() |
506e0f144f | ||
![]() |
72f68bfdd9 | ||
![]() |
2f9869b11d | ||
![]() |
8ffcf6498c | ||
![]() |
d224ae1923 | ||
![]() |
fed2063a19 | ||
![]() |
db2810cdd7 | ||
![]() |
4f1a6781ef | ||
![]() |
beffa5d5a4 | ||
![]() |
7a20f1de07 | ||
![]() |
cd25cf726b | ||
![]() |
d6b1bc3842 | ||
![]() |
a4385fb9bb | ||
![]() |
7045f2b8ea | ||
![]() |
07ca1a4de8 | ||
![]() |
24f289e692 | ||
![]() |
01bcdaae2d | ||
![]() |
55890008d1 | ||
![]() |
5ab9b01879 | ||
![]() |
e4abb333b3 | ||
![]() |
09f476c745 | ||
![]() |
8806e68dce | ||
![]() |
2ef1e25cd8 | ||
![]() |
10e7f202aa | ||
![]() |
ccd7000c09 | ||
![]() |
8ee7b798cf | ||
![]() |
7733cf5bf0 | ||
![]() |
a05ce86dd7 | ||
![]() |
91f51c32e8 | ||
![]() |
f910202bba | ||
![]() |
6d77194a8f | ||
![]() |
9deb89c15f | ||
![]() |
4b62a092b4 | ||
![]() |
81c8f626f9 | ||
![]() |
3e846c42fb | ||
![]() |
63ad7fd766 | ||
![]() |
9ff1e9aa34 | ||
![]() |
8d162b6f3d | ||
![]() |
9844d10bef | ||
![]() |
b908fa8489 | ||
![]() |
15a10643a7 | ||
![]() |
299617aca1 | ||
![]() |
45647d697a | ||
![]() |
48f5105d38 | ||
![]() |
fe1c741d68 | ||
![]() |
fa42cc1f00 | ||
![]() |
42cf5e7a81 | ||
![]() |
47905e1aa1 | ||
![]() |
9a8e907df3 | ||
![]() |
106fe85582 | ||
![]() |
4b3571bd57 | ||
![]() |
96b537401a | ||
![]() |
721c9eb057 | ||
![]() |
51701bf6d6 | ||
![]() |
dbde68bd56 | ||
![]() |
ad2c9f585a | ||
![]() |
562093c468 | ||
![]() |
b0295584a3 | ||
![]() |
208c54de98 | ||
![]() |
63e2d941a1 | ||
![]() |
3956838e9c | ||
![]() |
abeee58bb0 | ||
![]() |
d5b1b49722 | ||
![]() |
564ed03ff8 | ||
![]() |
70db4c76b4 | ||
![]() |
d059f7975b | ||
![]() |
4e74e6dc2d | ||
![]() |
b6deb96658 | ||
![]() |
3839e966be | ||
![]() |
3dd035849c | ||
![]() |
3d6532b5d6 | ||
![]() |
bf7c175ee7 | ||
![]() |
f84af35ed6 | ||
![]() |
99063b3eb1 | ||
![]() |
3bec18f28d | ||
![]() |
15de7a7894 | ||
![]() |
e20e04e677 | ||
![]() |
5fc6ae2835 | ||
![]() |
7d281b8c96 | ||
![]() |
4880b801a7 | ||
![]() |
74e354456a | ||
![]() |
af2e03aa36 | ||
![]() |
d8fa660ab6 | ||
![]() |
1a62d48297 | ||
![]() |
7ba01be13d | ||
![]() |
1a83d64db7 | ||
![]() |
5b53014c40 | ||
![]() |
83685340af | ||
![]() |
31e0cc4dec | ||
![]() |
56b87fc1f5 | ||
![]() |
6b956a2dd7 | ||
![]() |
1937623d7d | ||
![]() |
3b60b10945 | ||
![]() |
7173acd350 | ||
![]() |
6310d87338 | ||
![]() |
49a1ed7c18 | ||
![]() |
d426e280d9 | ||
![]() |
6154fb29f1 | ||
![]() |
97d48ef9d6 | ||
![]() |
88992625c4 | ||
![]() |
bc6eb44218 | ||
![]() |
cf9ccd799d | ||
![]() |
ffa0e4e771 | ||
![]() |
60fa9c196c | ||
![]() |
df860d22fb | ||
![]() |
cb46ff326c | ||
![]() |
f277a853ef | ||
![]() |
9ae34f67c3 | ||
![]() |
c9223218cc | ||
![]() |
c0dd645aba | ||
![]() |
2e948eb5b6 | ||
![]() |
c3276889cf | ||
![]() |
a76ca8282d | ||
![]() |
8ce6b8362f | ||
![]() |
842fb12f05 | ||
![]() |
d63e1511af | ||
![]() |
278783b8e0 | ||
![]() |
d24e3c922d | ||
![]() |
1d02cd2283 | ||
![]() |
8edeb82a87 | ||
![]() |
146e9279de | ||
![]() |
47105f50a9 | ||
![]() |
16c9c80f37 | ||
![]() |
8e7e4bc95a | ||
![]() |
0aa3d2f930 | ||
![]() |
ce77755a1e | ||
![]() |
0f31f20c87 | ||
![]() |
ee6da2aaa5 | ||
![]() |
a35f087cd9 | ||
![]() |
6e029b44dd | ||
![]() |
973c0cff34 | ||
![]() |
2027eea6ac | ||
![]() |
2f43692f33 | ||
![]() |
6d24992f88 | ||
![]() |
b4388a58d6 | ||
![]() |
158aa05fac | ||
![]() |
f2731bf55e | ||
![]() |
7304e99fce | ||
![]() |
02700b83eb | ||
![]() |
676b25acf9 | ||
![]() |
556359ea2d | ||
![]() |
b72923e0f5 | ||
![]() |
115ac9f75e | ||
![]() |
32e36f6708 | ||
![]() |
d949b7a4f9 | ||
![]() |
eae1171ff5 | ||
![]() |
76a1b75a51 | ||
![]() |
8882c0daea | ||
![]() |
07ebc16d59 | ||
![]() |
0ceb109964 | ||
![]() |
118b0d0038 | ||
![]() |
5e87067792 | ||
![]() |
c946a252e8 | ||
![]() |
f9ad2ba1dd | ||
![]() |
0d0ecd33bd | ||
![]() |
e4b98fd05b | ||
![]() |
95a5933303 | ||
![]() |
da3b55fa64 | ||
![]() |
fbbabfb90e | ||
![]() |
f13da6830d | ||
![]() |
f560a8e2f8 | ||
![]() |
56f1139c2f | ||
![]() |
773bdfc1e2 | ||
![]() |
f449666628 | ||
![]() |
3f282de0ab | ||
![]() |
440dd8d22f | ||
![]() |
dcff9de2f7 | ||
![]() |
a192866543 | ||
![]() |
10081416de | ||
![]() |
e2bed618f9 | ||
![]() |
03ab1f3823 | ||
![]() |
ac8aeb63d9 | ||
![]() |
2e16d822fa | ||
![]() |
e407d873fa | ||
![]() |
fd712a1dbe | ||
![]() |
e9028b40ce | ||
![]() |
c9da3dee7c | ||
![]() |
c8c224e202 | ||
![]() |
f34559daaf | ||
![]() |
9fefbf4c27 | ||
![]() |
1af9fd73ea | ||
![]() |
75ef394eff | ||
![]() |
ec6cc2c63e | ||
![]() |
06bc2e192b | ||
![]() |
78701ec7c1 | ||
![]() |
c925fab7e4 | ||
![]() |
42fd72c164 | ||
![]() |
7fd160e1a2 | ||
![]() |
97a0d940eb | ||
![]() |
efaa099d81 | ||
![]() |
47864a804b | ||
![]() |
91136c0e43 | ||
![]() |
28c3b1bd61 | ||
![]() |
551352bc40 | ||
![]() |
e73c24c925 | ||
![]() |
7ec4c286cc | ||
![]() |
6705e2ec4b | ||
![]() |
6f0373063b | ||
![]() |
f64eef60b5 | ||
![]() |
89546bf86b | ||
![]() |
793678feca | ||
![]() |
923cc3019a | ||
![]() |
10eb98a5f6 | ||
![]() |
bd9e89d8dd | ||
![]() |
1926b4ce73 | ||
![]() |
4ef3062d74 | ||
![]() |
abb6e0f60f | ||
![]() |
f204d8d84e | ||
![]() |
fa301656f1 | ||
![]() |
7e1221028f | ||
![]() |
41308cb2dd | ||
![]() |
130600521c | ||
![]() |
cd57548a48 | ||
![]() |
efacc99f76 | ||
![]() |
f0d236e172 | ||
![]() |
a8118bd8c6 | ||
![]() |
0e58f2ef53 | ||
![]() |
f4b22b3a0c | ||
![]() |
df5bd281c7 | ||
![]() |
a3f23837ce | ||
![]() |
612d989b97 | ||
![]() |
42c01ee9a2 | ||
![]() |
14074db591 | ||
![]() |
43dfdd7942 | ||
![]() |
f397b97ccf | ||
![]() |
95f8716144 | ||
![]() |
17ba472b2e | ||
![]() |
42d82571ab | ||
![]() |
9119a28141 | ||
![]() |
a32263d838 | ||
![]() |
208ae2bb88 | ||
![]() |
4d85462a85 | ||
![]() |
f601aa9ca0 | ||
![]() |
8aee3ad455 | ||
![]() |
6a2a1e9561 | ||
![]() |
5f8786c9dc | ||
![]() |
73f1d3eead | ||
![]() |
2bf21bb3c3 | ||
![]() |
f80f0dbb11 | ||
![]() |
37518c70c4 | ||
![]() |
e5951b5bef | ||
![]() |
ab320bd90b | ||
![]() |
7bd36b5371 | ||
![]() |
b882b0f2bc | ||
![]() |
38d7ae73cc | ||
![]() |
4527c6ee5d | ||
![]() |
85829e70c1 | ||
![]() |
256c08d82a | ||
![]() |
c2ce03c047 | ||
![]() |
f2af19e198 | ||
![]() |
930b7c092d | ||
![]() |
00757c69c6 | ||
![]() |
55f267d0fc | ||
![]() |
6b96aff6e8 | ||
![]() |
32b773a8fa | ||
![]() |
03089adad6 | ||
![]() |
4a1fe746ab | ||
![]() |
aa52c05d2c | ||
![]() |
26407a43e7 | ||
![]() |
a02934bf19 | ||
![]() |
09c65fba09 | ||
![]() |
4305c727d0 | ||
![]() |
188339897f | ||
![]() |
4ecff9a707 | ||
![]() |
355aed49c6 | ||
![]() |
4717b6b0f0 | ||
![]() |
45ebe9048d | ||
![]() |
b2170c49a3 | ||
![]() |
dc2f4d6115 | ||
![]() |
1eb132440f | ||
![]() |
a464bbc37a | ||
![]() |
ed995697c2 | ||
![]() |
163cd84c7b | ||
![]() |
293d7cc292 | ||
![]() |
5de1b4e74c | ||
![]() |
7b474975da | ||
![]() |
beab51516b | ||
![]() |
fe8685a50c | ||
![]() |
f9af5d0885 | ||
![]() |
e8136a9720 | ||
![]() |
531e5d4556 | ||
![]() |
e66255963a | ||
![]() |
246aac8ee4 | ||
![]() |
23cfeff685 | ||
![]() |
a5e7e0d126 | ||
![]() |
5bebc30ba0 | ||
![]() |
0e7057f5b9 | ||
![]() |
7c6c365ba4 | ||
![]() |
424c9bb0c5 | ||
![]() |
9d0f26594c | ||
![]() |
99c17de079 | ||
![]() |
b1e3dd0af6 | ||
![]() |
261cb89530 | ||
![]() |
ff6773ba37 | ||
![]() |
bdfbbfcbbd | ||
![]() |
0c4cd56758 | ||
![]() |
4a36658321 | ||
![]() |
7aae938685 | ||
![]() |
3723401e7a | ||
![]() |
70631366a9 | ||
![]() |
0e40bbda3e | ||
![]() |
e9aa475398 | ||
![]() |
8d2a811184 | ||
![]() |
dd7f5b6700 | ||
![]() |
a4f6277737 | ||
![]() |
c2bfaacbb7 | ||
![]() |
a17cbfa2d4 | ||
![]() |
fb9a101555 | ||
![]() |
e319cf0200 | ||
![]() |
0a8395ef6a | ||
![]() |
38df5e01be | ||
![]() |
ebd891a868 | ||
![]() |
4ab2395cbe | ||
![]() |
5f1f989fc9 | ||
![]() |
44b709eee3 | ||
![]() |
d0d7726597 | ||
![]() |
054c342aeb | ||
![]() |
c79c33baf7 | ||
![]() |
23b00e35b2 | ||
![]() |
fe51079266 | ||
![]() |
0791b0bbee | ||
![]() |
dbf04c8eeb | ||
![]() |
6204256df8 | ||
![]() |
93cc8c2327 | ||
![]() |
68a2e5bbbc | ||
![]() |
72792153f2 | ||
![]() |
88b6ef1897 |
@@ -1,20 +0,0 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TargetFrameworks>net6.0;net8.0;</TargetFrameworks>
|
||||
<Version>4.0.0.8</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
<Copyright>© 2023-present Diego</Copyright>
|
||||
<RepositoryUrl>https://gitee.com/diego2098/ThingsGateway</RepositoryUrl>
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<DelaySign>False</DelaySign>
|
||||
<SatelliteResourceLanguages>zh-Hans</SatelliteResourceLanguages>
|
||||
<GenerateDocumentationFile>False</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
|
||||
</Project>
|
@@ -82,7 +82,6 @@ EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "解决方案项", "解决方案项", "{97B23D8B-C6C0-4746-A21F-C7B49354B284}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\.gitignore = ..\.gitignore
|
||||
Directory.Build.props = Directory.Build.props
|
||||
..\README.md = ..\README.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
@@ -1,7 +1,17 @@
|
||||
<Project>
|
||||
<Import Project="$(SolutionDir)\Directory.Build.props" />
|
||||
<PropertyGroup>
|
||||
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TargetFrameworks>net6.0;net8.0;</TargetFrameworks>
|
||||
<Version>4.0.0.5</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
<Copyright>© 2023-present Diego</Copyright>
|
||||
<RepositoryUrl>https://gitee.com/diego2098/ThingsGateway</RepositoryUrl>
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<DelaySign>False</DelaySign>
|
||||
<SatelliteResourceLanguages>zh-Hans</SatelliteResourceLanguages>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
|
@@ -27,12 +27,12 @@ namespace ThingsGateway.Admin.ApiController;
|
||||
[Route("Swagger")]
|
||||
public class SwaggerController : IDynamicApiController, IScoped
|
||||
{
|
||||
private readonly IConfigService _configService;
|
||||
private readonly ConfigService _configService;
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="SwaggerController"/>
|
||||
/// </summary>
|
||||
/// <param name="sysConfigService"></param>
|
||||
public SwaggerController(IConfigService sysConfigService)
|
||||
public SwaggerController(ConfigService sysConfigService)
|
||||
{
|
||||
_configService = sysConfigService;
|
||||
}
|
||||
|
@@ -79,7 +79,7 @@
|
||||
Swagger登录授权服务
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Admin.ApiController.SwaggerController.#ctor(ThingsGateway.Admin.Application.IConfigService)">
|
||||
<member name="M:ThingsGateway.Admin.ApiController.SwaggerController.#ctor(ThingsGateway.Admin.Application.ConfigService)">
|
||||
<summary>
|
||||
<inheritdoc cref="T:ThingsGateway.Admin.ApiController.SwaggerController"/>
|
||||
</summary>
|
||||
|
@@ -96,7 +96,7 @@ public class OperDispatchProxy : AspectDispatchProxy, IDispatchProxy
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public override async Task InvokeAsync(MethodInfo method, object[] args)
|
||||
{
|
||||
var desc = method.GetActualCustomAttribute<OperDescAttribute>(Target, true);
|
||||
var desc = method.GetActualCustomAttribute<OperDescAttribute>(Target);
|
||||
if (desc == null)
|
||||
{
|
||||
var task = method.Invoke(Target, args) as Task;
|
||||
@@ -134,7 +134,7 @@ public class OperDispatchProxy : AspectDispatchProxy, IDispatchProxy
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public override async Task<T> InvokeAsyncT<T>(MethodInfo method, object[] args)
|
||||
{
|
||||
var desc = method.GetActualCustomAttribute<OperDescAttribute>(Target, true);
|
||||
var desc = method.GetActualCustomAttribute<OperDescAttribute>(Target);
|
||||
if (desc == null)
|
||||
{
|
||||
var taskT = method.Invoke(Target, args) as Task<T>;
|
||||
|
@@ -83,7 +83,7 @@ public class OpenApiSessionService : DbRepository<OpenApiUser>, IOpenApiSessionS
|
||||
var verificatInfos = await _verificatService.GetVerificatIdAsync(it.Id);
|
||||
if (verificatInfos != null)
|
||||
{
|
||||
GetVerificatInfos(ref verificatInfos);//获取剩余时间
|
||||
OpenApiSessionService.GetVerificatInfos(ref verificatInfos);//获取剩余时间
|
||||
it.VerificatCount = verificatInfos.Count;//令牌数量
|
||||
it.VerificatSignList = verificatInfos;//令牌列表
|
||||
}
|
||||
|
@@ -73,7 +73,7 @@ public class SessionService : DbRepository<SysUser>, ISessionService
|
||||
var verificatInfos = await _verificatService.GetVerificatIdAsync(it.Id);
|
||||
if (verificatInfos != null)
|
||||
{
|
||||
GetVerificatInfos(ref verificatInfos);//获取剩余时间
|
||||
SessionService.GetVerificatInfos(ref verificatInfos);//获取剩余时间
|
||||
it.VerificatCount = verificatInfos.Count;//令牌数量
|
||||
it.VerificatSignList = verificatInfos;//令牌列表
|
||||
|
||||
|
@@ -10,8 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.String;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
@@ -36,8 +34,7 @@ public class SeedDataUtil
|
||||
if (!string.IsNullOrEmpty(dataString))//如果有内容
|
||||
{
|
||||
//字段没有数据的替换成null
|
||||
dataString = Regex.Replace(dataString, "\\\"[^\"]+?\\\": \\\"\\\"", match => match.Value.Replace("\"\"", "null"));
|
||||
//dataString = dataString.Replace("\"\"", "null");
|
||||
dataString = dataString.Replace("\"\"", "null");
|
||||
//将json字符串转为实体,这里extjson可以正常转换为字符串
|
||||
var seedDataRecord = Newtonsoft.Json.JsonConvert.DeserializeObject<SeedDataRecords<T>>(dataString);
|
||||
|
||||
|
@@ -37,7 +37,7 @@ namespace ThingsGateway.Admin.Blazor
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await _serviceScope.ServiceProvider.GetService<IUserCenterService>().GetLoginDefaultRazorAsync(UserManager.UserId);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<UserCenterService>().GetLoginDefaultRazorAsync(UserManager.UserId);
|
||||
var sameLevelMenus = await _serviceScope.ServiceProvider.GetService<IResourceService>().GetaMenuAndSpaListAsync();
|
||||
if (NavigationManager.ToAbsoluteUri(NavigationManager.Uri).AbsolutePath == "/Login" || NavigationManager.ToAbsoluteUri(NavigationManager.Uri).AbsolutePath == "/")
|
||||
NavigationManager.NavigateTo(sameLevelMenus.FirstOrDefault(a => a.Id == data)?.Component ?? "index", true);
|
||||
|
@@ -39,26 +39,26 @@ public partial class Config
|
||||
}
|
||||
private async Task AddCallAsync(ConfigAddInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IConfigService>().AddAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<ConfigService>().AddAsync(input);
|
||||
}
|
||||
|
||||
private async Task DeleteCallAsync(IEnumerable<SysConfig> sysConfigs)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IConfigService>().DeleteAsync(sysConfigs.Select(a => a.Id).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<ConfigService>().DeleteAsync(sysConfigs.Select(a => a.Id).ToArray());
|
||||
}
|
||||
private async Task EditCallAsync(ConfigEditInput sysConfigs)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IConfigService>().EditAsync(sysConfigs);
|
||||
await _serviceScope.ServiceProvider.GetService<ConfigService>().EditAsync(sysConfigs);
|
||||
}
|
||||
|
||||
private async Task OnSaveAsync()
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IConfigService>().EditBatchAsync(_sysConfig);
|
||||
await _serviceScope.ServiceProvider.GetService<ConfigService>().EditBatchAsync(_sysConfig);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
private async Task<ISqlSugarPagedList<SysConfig>> QueryCallAsync(ConfigPageInput input)
|
||||
{
|
||||
return await _serviceScope.ServiceProvider.GetService<IConfigService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<ConfigService>().PageAsync(input);
|
||||
}
|
||||
}
|
@@ -45,23 +45,23 @@ public partial class Menu
|
||||
private async Task AddCallAsync(MenuAddInput input)
|
||||
{
|
||||
input.ParentId = _search.ParentId;
|
||||
await _serviceScope.ServiceProvider.GetService<IMenuService>().AddAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<MenuService>().AddAsync(input);
|
||||
await NavChangeAsync();
|
||||
}
|
||||
private async Task ButtonAddCallAsync(ButtonAddInput input)
|
||||
{
|
||||
input.ParentId = _buttonParentId;
|
||||
await _serviceScope.ServiceProvider.GetService<IButtonService>().AddAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<ButtonService>().AddAsync(input);
|
||||
}
|
||||
|
||||
private async Task ButtonDeleteCallAsync(IEnumerable<SysResource> input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IButtonService>().DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<ButtonService>().DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
}
|
||||
|
||||
private async Task ButtonEditCallAsync(ButtonEditInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IButtonService>().EditAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<ButtonService>().EditAsync(input);
|
||||
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public partial class Menu
|
||||
private async Task<ISqlSugarPagedList<SysResource>> ButtonQueryCallAsync(ButtonPageInput input)
|
||||
{
|
||||
input.ParentId = _buttonParentId;
|
||||
var data = await _serviceScope.ServiceProvider.GetService<IButtonService>().PageAsync(input);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<ButtonService>().PageAsync(input);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -96,13 +96,13 @@ public partial class Menu
|
||||
|
||||
private async Task DeleteCallAsync(IEnumerable<SysResource> input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IMenuService>().DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<MenuService>().DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
await NavChangeAsync();
|
||||
|
||||
}
|
||||
private async Task EditCallAsync(MenuEditInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IMenuService>().EditAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<MenuService>().EditAsync(input);
|
||||
await NavChangeAsync();
|
||||
|
||||
}
|
||||
@@ -123,7 +123,7 @@ public partial class Menu
|
||||
}
|
||||
private async Task<ISqlSugarPagedList<SysResource>> QueryCallAsync(MenuPageInput input)
|
||||
{
|
||||
var data = await _serviceScope.ServiceProvider.GetService<IMenuService>().TreeAsync(input);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<MenuService>().TreeAsync(input);
|
||||
return data.ToPagedList(input);
|
||||
}
|
||||
|
||||
|
@@ -32,13 +32,13 @@ public partial class OpenApiSession
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("警告", "确定 ?");
|
||||
if (confirm)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiSessionService>().ExitSessionAsync(id);
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiSessionService>().ExitSessionAsync(id);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<ISqlSugarPagedList<OpenApiSessionOutput>> SessionQueryCallAsync(OpenApiSessionPageInput input)
|
||||
{
|
||||
return await _serviceScope.ServiceProvider.GetService<IOpenApiSessionService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<OpenApiSessionService>().PageAsync(input);
|
||||
}
|
||||
|
||||
private async Task ShowVerificatListAsync(List<VerificatInfo> verificatInfos)
|
||||
@@ -56,7 +56,7 @@ public partial class OpenApiSession
|
||||
VerificatIds = verificats.Select(it => it.Id).ToList(),
|
||||
Id = verificats.First().UserId
|
||||
};
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiSessionService>().ExitVerificatAsync(send);
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiSessionService>().ExitVerificatAsync(send);
|
||||
_verificatInfos.RemoveWhere(it => send.VerificatIds.Contains(it.Id));
|
||||
}
|
||||
|
||||
|
@@ -32,17 +32,17 @@ public partial class OpenApiUserR
|
||||
|
||||
private async Task AddCallAsync(OpenApiUserAddInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiUserService>().AddAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiUserService>().AddAsync(input);
|
||||
}
|
||||
|
||||
private async Task DeleteCallAsync(IEnumerable<OpenApiUser> users)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiUserService>().DeleteAsync(users.Select(a => a.Id).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiUserService>().DeleteAsync(users.Select(a => a.Id).ToArray());
|
||||
}
|
||||
|
||||
private async Task EditCallAsync(OpenApiUserEditInput users)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiUserService>().EditAsync(users);
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiUserService>().EditAsync(users);
|
||||
}
|
||||
|
||||
private List<OpenApiPermissionTreeSelector> GetRouters()
|
||||
@@ -58,7 +58,7 @@ public partial class OpenApiUserR
|
||||
OpenApiUserGrantPermissionInput userGrantRoleInput = new();
|
||||
userGrantRoleInput.Id = _choiceUserId;
|
||||
userGrantRoleInput.PermissionList = _rolesChoice.Select(it => it.ApiRoute).ToList();
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiUserService>().GrantRoleAsync(userGrantRoleInput);
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiUserService>().GrantRoleAsync(userGrantRoleInput);
|
||||
_isShowRoles = false;
|
||||
await _datatable?.QueryClickAsync();
|
||||
}
|
||||
@@ -70,7 +70,7 @@ public partial class OpenApiUserR
|
||||
}
|
||||
private async Task<ISqlSugarPagedList<OpenApiUser>> QueryCallAsync(OpenApiUserPageInput input)
|
||||
{
|
||||
return await _serviceScope.ServiceProvider.GetService<IOpenApiUserService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<OpenApiUserService>().PageAsync(input);
|
||||
}
|
||||
|
||||
private async Task UserStatusChangeAsync(OpenApiUser context, bool enable)
|
||||
@@ -78,9 +78,9 @@ public partial class OpenApiUserR
|
||||
try
|
||||
{
|
||||
if (enable)
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiUserService>().EnableUserAsync(context.Id);
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiUserService>().EnableUserAsync(context.Id);
|
||||
else
|
||||
await _serviceScope.ServiceProvider.GetService<IOpenApiUserService>().DisableUserAsync(context.Id);
|
||||
await _serviceScope.ServiceProvider.GetService<OpenApiUserService>().DisableUserAsync(context.Id);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@@ -47,7 +47,7 @@ public partial class Oplog
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("删除", "确定 ?");
|
||||
if (confirm)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IOperateLogService>().DeleteAsync(_categoryFilters.Select(it => it.Value).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<OperateLogService>().DeleteAsync(_categoryFilters.Select(it => it.Value).ToArray());
|
||||
await _datatable?.QueryClickAsync();
|
||||
}
|
||||
}
|
||||
@@ -68,6 +68,6 @@ public partial class Oplog
|
||||
input.Account = _search.Account;
|
||||
input.Category = _search.Category;
|
||||
input.ExeStatus = _search.ExeStatus;
|
||||
return await _serviceScope.ServiceProvider.GetService<IOperateLogService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<OperateLogService>().PageAsync(input);
|
||||
}
|
||||
}
|
@@ -41,17 +41,17 @@ public partial class Role
|
||||
|
||||
private async Task AddCallAsync(RoleAddInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IRoleService>().AddAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<RoleService>().AddAsync(input);
|
||||
}
|
||||
private async Task DeleteCallAsync(IEnumerable<SysRole> sysRoles)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IRoleService>().DeleteAsync(sysRoles.Select(a => a.Id).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<RoleService>().DeleteAsync(sysRoles.Select(a => a.Id).ToArray());
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
private async Task EditCallAsync(RoleEditInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IRoleService>().EditAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<RoleService>().EditAsync(input);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
private async Task OnRoleHasResuorcesSaveAsync(ModalActionEventArgs args)
|
||||
@@ -62,7 +62,7 @@ public partial class Role
|
||||
var data = new List<SysResource>();
|
||||
userGrantRoleInput.Id = _choiceRoleId;
|
||||
userGrantRoleInput.GrantInfoList = _roleHasResuorces;
|
||||
await _serviceScope.ServiceProvider.GetService<IRoleService>().GrantResourceAsync(userGrantRoleInput);
|
||||
await _serviceScope.ServiceProvider.GetService<RoleService>().GrantResourceAsync(userGrantRoleInput);
|
||||
_isShowResuorces = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -79,7 +79,7 @@ public partial class Role
|
||||
GrantUserInput userGrantRoleInput = new();
|
||||
userGrantRoleInput.Id = _choiceRoleId;
|
||||
userGrantRoleInput.GrantInfoList = _usersChoice.Select(it => it.Id).ToList();
|
||||
await _serviceScope.ServiceProvider.GetService<IRoleService>().GrantUserAsync(userGrantRoleInput);
|
||||
await _serviceScope.ServiceProvider.GetService<RoleService>().GrantUserAsync(userGrantRoleInput);
|
||||
_isShowUsers = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -92,19 +92,19 @@ public partial class Role
|
||||
|
||||
private async Task<ISqlSugarPagedList<SysRole>> QueryCallAsync(RolePageInput input)
|
||||
{
|
||||
return await _serviceScope.ServiceProvider.GetService<IRoleService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<RoleService>().PageAsync(input);
|
||||
}
|
||||
|
||||
private async Task ResuorceInitAsync()
|
||||
{
|
||||
_resTreeSelectors = (await _serviceScope.ServiceProvider.GetService<ResourceService>().GetRoleGrantResourceMenusAsync());
|
||||
_roleHasResuorces = (await _serviceScope.ServiceProvider.GetService<IRoleService>().OwnResourceAsync(_choiceRoleId))?.GrantInfoList;
|
||||
_roleHasResuorces = (await _serviceScope.ServiceProvider.GetService<RoleService>().OwnResourceAsync(_choiceRoleId))?.GrantInfoList;
|
||||
}
|
||||
|
||||
private async Task<List<UserSelectorOutput>> UserInitAsync()
|
||||
{
|
||||
_allUsers = await _serviceScope.ServiceProvider.GetService<ISysUserService>().UserSelectorAsync(_searchKey);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<IRoleService>().OwnUserAsync(_choiceRoleId);
|
||||
_allUsers = await _serviceScope.ServiceProvider.GetService<SysUserService>().UserSelectorAsync(_searchKey);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<RoleService>().OwnUserAsync(_choiceRoleId);
|
||||
_usersChoice = _allUsers.Where(a => data.Contains(a.Id)).ToList();
|
||||
return _allUsers;
|
||||
}
|
||||
|
@@ -37,14 +37,14 @@ public partial class Session
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("警告", "确定 ?");
|
||||
if (confirm)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<ISessionService>().ExitSessionAsync(id);
|
||||
await _serviceScope.ServiceProvider.GetService<SessionService>().ExitSessionAsync(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task<ISqlSugarPagedList<SessionOutput>> SessionQueryCallAsync(SessionPageInput input)
|
||||
{
|
||||
return await _serviceScope.ServiceProvider.GetService<ISessionService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<SessionService>().PageAsync(input);
|
||||
}
|
||||
|
||||
private async Task ShowVerificatListAsync(List<VerificatInfo> verificatInfos)
|
||||
@@ -62,7 +62,7 @@ public partial class Session
|
||||
VerificatIds = verificats.Select(it => it.Id).ToList(),
|
||||
Id = verificats.First().UserId
|
||||
};
|
||||
await _serviceScope.ServiceProvider.GetService<ISessionService>().ExitVerificatAsync(send);
|
||||
await _serviceScope.ServiceProvider.GetService<SessionService>().ExitVerificatAsync(send);
|
||||
_verificatInfos.RemoveWhere(it => send.VerificatIds.Contains(it.Id));
|
||||
}
|
||||
|
||||
|
@@ -28,23 +28,23 @@ public partial class Spa
|
||||
|
||||
private async Task AddCallAsync(SpaAddInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<ISpaService>().AddAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<SpaService>().AddAsync(input);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
private async Task DeleteCallAsync(IEnumerable<SysResource> input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<ISpaService>().DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<SpaService>().DeleteAsync(input.Select(a => a.Id).ToArray());
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
private async Task EditCallAsync(SpaEditInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<ISpaService>().EditAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<SpaService>().EditAsync(input);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
private async Task<ISqlSugarPagedList<SysResource>> QueryCallAsync(SpaPageInput input)
|
||||
{
|
||||
return await _serviceScope.ServiceProvider.GetService<ISpaService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<SpaService>().PageAsync(input);
|
||||
}
|
||||
}
|
@@ -35,17 +35,17 @@ public partial class User
|
||||
|
||||
private async Task AddCallAsync(UserAddInput input)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<ISysUserService>().AddAsync(input);
|
||||
await _serviceScope.ServiceProvider.GetService<SysUserService>().AddAsync(input);
|
||||
}
|
||||
private async Task DeleteCallAsync(IEnumerable<SysUser> users)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<ISysUserService>().DeleteAsync(users.Select(a => a.Id).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<SysUserService>().DeleteAsync(users.Select(a => a.Id).ToArray());
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
private async Task EditCallAsync(UserEditInput users)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<ISysUserService>().EditAsync(users);
|
||||
await _serviceScope.ServiceProvider.GetService<SysUserService>().EditAsync(users);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public partial class User
|
||||
UserGrantRoleInput userGrantRoleInput = new();
|
||||
userGrantRoleInput.Id = _choiceUserId;
|
||||
userGrantRoleInput.RoleIdList = _rolesChoice.Select(it => it.Id).ToList();
|
||||
await _serviceScope.ServiceProvider.GetService<ISysUserService>().GrantRoleAsync(userGrantRoleInput);
|
||||
await _serviceScope.ServiceProvider.GetService<SysUserService>().GrantRoleAsync(userGrantRoleInput);
|
||||
_isShowRoles = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -68,20 +68,20 @@ public partial class User
|
||||
}
|
||||
private async Task<ISqlSugarPagedList<SysUser>> QueryCallAsync(UserPageInput input)
|
||||
{
|
||||
return await _serviceScope.ServiceProvider.GetService<ISysUserService>().PageAsync(input);
|
||||
return await _serviceScope.ServiceProvider.GetService<SysUserService>().PageAsync(input);
|
||||
}
|
||||
|
||||
private async Task ResetPasswordAsync(SysUser sysUser)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<ISysUserService>().ResetPasswordAsync(sysUser.Id);
|
||||
await _serviceScope.ServiceProvider.GetService<SysUserService>().ResetPasswordAsync(sysUser.Id);
|
||||
await PopupService.EnqueueSnackbarAsync(new("成功", AlertTypes.Success));
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
}
|
||||
|
||||
private async Task RoleInitAsync()
|
||||
{
|
||||
_allRoles = await _serviceScope.ServiceProvider.GetService<IRoleService>().RoleSelectorAsync();
|
||||
var data = await _serviceScope.ServiceProvider.GetService<IRoleService>().GetRoleIdListByUserIdAsync(_choiceUserId);
|
||||
_allRoles = await _serviceScope.ServiceProvider.GetService<RoleService>().RoleSelectorAsync();
|
||||
var data = await _serviceScope.ServiceProvider.GetService<RoleService>().GetRoleIdListByUserIdAsync(_choiceUserId);
|
||||
_rolesChoice = _allRoles.Where(a => data.Contains(a.Id)).ToList();
|
||||
}
|
||||
private async Task UserStatusChangeAsync(SysUser context, bool enable)
|
||||
@@ -89,9 +89,9 @@ public partial class User
|
||||
try
|
||||
{
|
||||
if (enable)
|
||||
await _serviceScope.ServiceProvider.GetService<ISysUserService>().EnableUserAsync(context.Id);
|
||||
await _serviceScope.ServiceProvider.GetService<SysUserService>().EnableUserAsync(context.Id);
|
||||
else
|
||||
await _serviceScope.ServiceProvider.GetService<ISysUserService>().DisableUserAsync(context.Id);
|
||||
await _serviceScope.ServiceProvider.GetService<SysUserService>().DisableUserAsync(context.Id);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@@ -44,14 +44,14 @@ public partial class UserCenter
|
||||
|
||||
async Task OnDefaultRazorSaveAsync()
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IUserCenterService>().UpdateUserDefaultRazorAsync(UserManager.UserId, _defaultMenuId);
|
||||
await _serviceScope.ServiceProvider.GetService<UserCenterService>().UpdateUserDefaultRazorAsync(UserManager.UserId, _defaultMenuId);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
|
||||
async Task OnShortcutSaveAsync()
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IUserCenterService>().UpdateWorkbenchAsync(_menusChoice);
|
||||
await _serviceScope.ServiceProvider.GetService<UserCenterService>().UpdateWorkbenchAsync(_menusChoice);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
@@ -62,7 +62,7 @@ public partial class UserCenter
|
||||
{
|
||||
//验证成功,操作业务
|
||||
_passwordInfoInput.Id = UserResoures.CurrentUser.Id;
|
||||
await _serviceScope.ServiceProvider.GetService<IUserCenterService>().EditPasswordAsync(_passwordInfoInput);
|
||||
await _serviceScope.ServiceProvider.GetService<UserCenterService>().EditPasswordAsync(_passwordInfoInput);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("成功,将重新登录", AlertTypes.Success);
|
||||
await Task.Delay(2000);
|
||||
@@ -72,7 +72,7 @@ public partial class UserCenter
|
||||
|
||||
async Task OnUpdateUserInfoAsync()
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IUserCenterService>().UpdateUserInfoAsync(_updateInfoInput);
|
||||
await _serviceScope.ServiceProvider.GetService<UserCenterService>().UpdateUserInfoAsync(_updateInfoInput);
|
||||
await _mainLayout.StateHasChangedAsync();
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
|
@@ -56,7 +56,7 @@ public partial class Vislog
|
||||
var confirm = await PopupService.OpenConfirmDialogAsync("删除", "确定 ?");
|
||||
if (confirm)
|
||||
{
|
||||
await _serviceScope.ServiceProvider.GetService<IVisitLogService>().DeleteAsync(_categoryFilters.Select(it => it.Value).ToArray());
|
||||
await _serviceScope.ServiceProvider.GetService<VisitLogService>().DeleteAsync(_categoryFilters.Select(it => it.Value).ToArray());
|
||||
await _datatable?.QueryClickAsync();
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,7 @@ public partial class Vislog
|
||||
|
||||
private async Task<ISqlSugarPagedList<SysVisitLog>> QueryCallAsync(VisitLogPageInput input)
|
||||
{
|
||||
var data = await _serviceScope.ServiceProvider.GetService<IVisitLogService>().PageAsync(input);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<VisitLogService>().PageAsync(input);
|
||||
return data;
|
||||
}
|
||||
}
|
@@ -107,8 +107,8 @@ public partial class Login
|
||||
{
|
||||
await PopupService.EnqueueSnackbarAsync(new("登录成功", AlertTypes.Success));
|
||||
await Task.Delay(500);
|
||||
var userId = await _serviceScope.ServiceProvider.GetService<ISysUserService>().GetIdByAccountAsync(_loginModel.Account);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<IUserCenterService>().GetLoginDefaultRazorAsync(userId);
|
||||
var userId = await _serviceScope.ServiceProvider.GetService<SysUserService>().GetIdByAccountAsync(_loginModel.Account);
|
||||
var data = await _serviceScope.ServiceProvider.GetService<UserCenterService>().GetLoginDefaultRazorAsync(userId);
|
||||
var sameLevelMenus = await _serviceScope.ServiceProvider.GetService<ResourceService>().GetaMenuAndSpaListAsync();
|
||||
if (_NavigationManager.ToAbsoluteUri(_NavigationManager.Uri).AbsolutePath == "/Login" || _NavigationManager.ToAbsoluteUri(_NavigationManager.Uri).AbsolutePath == "/")
|
||||
await _ajaxService.GotoAsync(sameLevelMenus.FirstOrDefault(a => a.Id == data)?.Component ?? "index");
|
||||
|
@@ -16,7 +16,7 @@ using ThingsGateway.Foundation.Extension.String;
|
||||
|
||||
namespace ThingsGateway.Admin.Blazor;
|
||||
|
||||
public partial class MainLayout : IDisposable
|
||||
public partial class MainLayout
|
||||
{
|
||||
private List<SysResource> _breadcrumbSysResources = new();
|
||||
private string _configCopyRight = "";
|
||||
@@ -43,23 +43,16 @@ public partial class MainLayout : IDisposable
|
||||
private IServiceScopeFactory _serviceScopeFactory { get; set; }
|
||||
[Inject]
|
||||
private UserResoures _userResoures { get; set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_serviceScope.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 页面刷新
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task StateHasChangedAsync()
|
||||
{
|
||||
var configService = _serviceScope.ServiceProvider.GetService<IConfigService>();
|
||||
_configCopyRight = (await configService.GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_COPYRIGHT)).ConfigValue;
|
||||
_configTitle = (await configService.GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_TITLE)).ConfigValue;
|
||||
_configCopyRightUrl = (await configService.GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_COPYRIGHT_URL)).ConfigValue;
|
||||
_configPageTab = (await configService.GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_PAGETAB)).ConfigValue.ToBool(true);
|
||||
_configCopyRight = (await _serviceScope.ServiceProvider.GetService<IConfigService>().GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_COPYRIGHT)).ConfigValue;
|
||||
_configTitle = (await _serviceScope.ServiceProvider.GetService<IConfigService>().GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_TITLE)).ConfigValue;
|
||||
_configCopyRightUrl = (await _serviceScope.ServiceProvider.GetService<IConfigService>().GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_COPYRIGHT_URL)).ConfigValue;
|
||||
_configPageTab = (await _serviceScope.ServiceProvider.GetService<IConfigService>().GetByConfigKeyAsync(ConfigConst.SYS_CONFIGBASEDEFAULT, ConfigConst.CONFIG_PAGETAB)).ConfigValue.ToBool(true);
|
||||
|
||||
await _userResoures.InitUserAsync();
|
||||
await _userResoures.InitMenuAsync();
|
||||
|
@@ -24,6 +24,7 @@ public class Startup : AppStartup
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.ThingsGatewayComponentsConfigureServices();
|
||||
|
||||
services.AddScoped<UserResoures>();
|
||||
|
||||
}
|
||||
|
@@ -3,7 +3,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.0" />
|
||||
<PackageReference Include="Masa.Blazor.SomethingSkia" Version="1.2.2" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
@@ -35,7 +35,6 @@ public class Startup : AppStartup
|
||||
{
|
||||
WorkerId = 4// 取值范围0~63
|
||||
});
|
||||
services.ThingsGatewayCoreConfigureServices();
|
||||
|
||||
services.AddComponent<LoggingConsoleComponent>();//启动控制台日志格式化组件
|
||||
ThingsGateway.Core.TypeExtensions.DefaultFuncs.Add(a => a.GetCustomAttribute<SqlSugar.SugarColumn>()?.ColumnDescription);
|
||||
|
@@ -5,10 +5,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Furion.Pure" Version="4.9.1.11" />
|
||||
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.1.11" />
|
||||
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.1.11" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.126" />
|
||||
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.1.5" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.123" />
|
||||
<PackageReference Include="UAParser" Version="3.1.47" />
|
||||
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
|
||||
</ItemGroup>
|
||||
|
@@ -56,7 +56,6 @@ public abstract class BaseComponentBase : ComponentBase, IDisposable
|
||||
/// </summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
_serviceScope.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -19,7 +19,7 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ThingsGateway.Components;
|
||||
|
||||
public static class ServiceExtensions
|
||||
public static class ConfigureService
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public static void ThingsGatewayComponentsConfigureServices(this IServiceCollection services)
|
||||
@@ -65,7 +65,9 @@ public static class ServiceExtensions
|
||||
{ nameof(MTimeline), new Dictionary<string, object>() { { nameof(MTimeline.Dense), true } } },
|
||||
{ nameof(MToolbar), new Dictionary<string, object>() { { nameof(MToolbar.Dense), true } } },
|
||||
{ "MTreeview", new Dictionary<string, object>() { { "Dense", true } } },
|
||||
{ "PImageCaptcha", new Dictionary<string, object>() { { "Dense", true } } }
|
||||
{ nameof(PImageCaptcha), new Dictionary<string, object>() { { nameof(PImageCaptcha.Dense), true } } }
|
||||
|
||||
|
||||
|
||||
};
|
||||
options.ConfigureTheme(theme =>
|
||||
@@ -96,7 +98,6 @@ public static class ServiceExtensions
|
||||
services.AddScoped<InitTimezone>();
|
||||
services.AddScoped<AjaxService>();
|
||||
services.AddScoped<CookieStorage>();
|
||||
services.AddScoped<IDefaultTimezoneOffsetAccessor, DefaultTimezoneOffsetAccessor>();
|
||||
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
|
||||
namespace ThingsGateway.Components
|
||||
{
|
||||
public interface IDefaultTimezoneOffsetAccessor
|
||||
{
|
||||
TimeSpan GetTimezoneOffsetResult();
|
||||
}
|
||||
}
|
@@ -10,6 +10,9 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ThingsGateway.Components;
|
||||
|
||||
/// <summary>
|
||||
@@ -40,11 +43,17 @@ public class InitTimezone : IDisposable
|
||||
/// <param name="jsRuntime"></param>
|
||||
/// <param name="storage"></param>
|
||||
/// <param name="serviceProvider"></param>
|
||||
public InitTimezone(IJSRuntime jsRuntime, CookieStorage storage, IDefaultTimezoneOffsetAccessor defaultTimezoneOffsetAccessor)
|
||||
public InitTimezone(IJSRuntime jsRuntime, CookieStorage storage, IServiceProvider serviceProvider)
|
||||
{
|
||||
IHttpContextAccessor httpContextAccessor = serviceProvider.GetService<IHttpContextAccessor>();
|
||||
_jsRuntime = jsRuntime;
|
||||
_storage = storage;
|
||||
_timezoneOffset = defaultTimezoneOffsetAccessor.GetTimezoneOffsetResult();
|
||||
var httpContext = httpContextAccessor?.HttpContext;
|
||||
if (httpContext is not null)
|
||||
{
|
||||
var timezoneOffsetResult = httpContext.Request.Cookies[_timezoneOffsetKey];
|
||||
_timezoneOffset = TimeSpan.FromMinutes(Convert.ToDouble(timezoneOffsetResult));
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取Web客户端时差
|
||||
|
@@ -3,6 +3,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Masa.Blazor" Version="1.2.2" />
|
||||
<PackageReference Include="Masa.Blazor.SomethingSkia" Version="1.2.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -10,6 +10,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion.DependencyInjection;
|
||||
|
||||
using Mapster;
|
||||
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
@@ -21,9 +23,8 @@ namespace ThingsGateway.Core;
|
||||
/// <summary>
|
||||
/// 系统内存缓存
|
||||
/// </summary>
|
||||
public class MemoryCache
|
||||
public class MemoryCache : ISingleton
|
||||
{
|
||||
public static MemoryCache Instance { get; private set; } = new();
|
||||
private const string intervalStr = "---___---";
|
||||
private readonly Microsoft.Extensions.Caching.Memory.MemoryCache _memoryCache = new(new MemoryCacheOptions());
|
||||
private readonly Microsoft.Extensions.Caching.Memory.MemoryCache _prefixmemoryCache = new(new MemoryCacheOptions());
|
||||
|
@@ -10,6 +10,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion;
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Globalization;
|
||||
@@ -88,7 +90,7 @@ public static class TypeExtensions
|
||||
public static string GetDescription(this Type modelType, string name, Func<MemberInfo, string> func = null)
|
||||
{
|
||||
var cacheKey = $"{nameof(GetDescription)}-{CultureInfo.CurrentUICulture.Name}-{modelType.FullName}-{name}-{modelType.TypeHandle.Value}";
|
||||
var str = MemoryCache.Instance.GetOrCreate(cacheKey, entry =>
|
||||
var str = App.GetService<MemoryCache>().GetOrCreate(cacheKey, entry =>
|
||||
{
|
||||
string dn = default;
|
||||
{
|
||||
|
@@ -10,15 +10,20 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Furion;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ThingsGateway.Core;
|
||||
|
||||
public static class ServiceExtensions
|
||||
/// <summary>
|
||||
/// Startup
|
||||
/// </summary>
|
||||
[AppStartup(9999)]
|
||||
public class Startup : AppStartup
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public static void ThingsGatewayCoreConfigureServices(this IServiceCollection services)
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton(a => MemoryCache.Instance);
|
||||
|
||||
}
|
||||
}
|
@@ -1,11 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
|
||||
|
||||
<PackageReference Include="Furion.Pure" Version="4.9.1.5" />
|
||||
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.1.5" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@@ -1,7 +1,14 @@
|
||||
<Project>
|
||||
<Import Project="$(SolutionDir)\Directory.Build.props" />
|
||||
<PropertyGroup>
|
||||
|
||||
<TargetFrameworks>net6.0;net8.0;</TargetFrameworks>
|
||||
<Version>4.0.0.5</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
<Copyright>© 2023-present Diego</Copyright>
|
||||
<RepositoryUrl>https://gitee.com/diego2098/ThingsGateway</RepositoryUrl>
|
||||
<SatelliteResourceLanguages>zh-Hans</SatelliteResourceLanguages>
|
||||
<GenerateDocumentationFile>False</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
|
@@ -12,8 +12,6 @@
|
||||
|
||||
using Photino.Blazor;
|
||||
|
||||
using ThingsGateway.Core;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
|
||||
internal class Program
|
||||
@@ -25,10 +23,11 @@ internal class Program
|
||||
|
||||
var appBuilder = PhotinoBlazorAppBuilder.CreateDefault(args);
|
||||
|
||||
Serve.RunNative();
|
||||
|
||||
appBuilder.RootComponents.Add<App>("#app");
|
||||
|
||||
appBuilder.Services.ThingsGatewayComponentsConfigureServices();
|
||||
appBuilder.Services.ThingsGatewayCoreConfigureServices();
|
||||
var app = appBuilder.Build();
|
||||
app.MainWindow.SetTitle("ThingsGateway.Foundation.Demo");
|
||||
app.MainWindow.SetIconFile("wwwroot/favicon.ico");
|
||||
|
@@ -12,9 +12,6 @@
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
using ThingsGateway.Components;
|
||||
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
|
||||
/// <summary>
|
||||
|
@@ -18,10 +18,10 @@
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">通道配置</div>
|
||||
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialPortOption.Description(x => x.PortName)) Dense HideDetails="@("auto")" @bind-Value=@_serialPortOption.PortName />
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialPortOption.Description(x => x.BaudRate)) Dense HideDetails="@("auto")" @bind-Value=@_serialPortOption.BaudRate />
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialPortOption.Description(x => x.DataBits)) Dense HideDetails="@("auto")" @bind-Value=@_serialPortOption.DataBits />
|
||||
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialPortOption.Parity" Label="@(_serialPortOption.Description(x => x.Parity))"
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialProperty.Description(x => x.PortName)) Dense HideDetails="@("auto")" @bind-Value=@_serialProperty.PortName />
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialProperty.Description(x => x.BaudRate)) Dense HideDetails="@("auto")" @bind-Value=@_serialProperty.BaudRate />
|
||||
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialProperty.Description(x => x.DataBits)) Dense HideDetails="@("auto")" @bind-Value=@_serialProperty.DataBits />
|
||||
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialProperty.Parity" Label="@(_serialProperty.Description(x => x.Parity))"
|
||||
Items=@(typeof(Parity).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
||||
@@ -29,7 +29,7 @@
|
||||
HideDetails=@("auto") Height="30"
|
||||
Dense>
|
||||
</MSelect>
|
||||
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialPortOption.StopBits" Label="@(_serialPortOption.Description(x => x.StopBits))"
|
||||
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialProperty.StopBits" Label="@(_serialProperty.Description(x => x.StopBits))"
|
||||
Items=@(typeof(StopBits).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.Description)
|
@@ -13,39 +13,39 @@
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public partial class SerialPortClientPage : IDisposable
|
||||
public partial class SerialSessionPage : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 日志输出
|
||||
/// </summary>
|
||||
public Action<LogLevel, object, string, Exception> LogAction;
|
||||
|
||||
private readonly SerialPortOption _serialPortOption = new();
|
||||
private readonly SerialProperty _serialProperty = new();
|
||||
private TouchSocketConfig _config;
|
||||
private SerialPortClient _serialPortClient { get; set; } = new();
|
||||
private SerialSession _serialSession { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_serialPortClient.SafeDispose();
|
||||
_serialSession.SafeDispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SerialPortClient GetSerialPortClient()
|
||||
public SerialSession GetSerialSession()
|
||||
{
|
||||
_config ??= new TouchSocketConfig();
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
_config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
_config.SetSerialPortOption(_serialPortOption);
|
||||
_config.SetSerialProperty(_serialProperty);
|
||||
//载入配置
|
||||
_serialPortClient.Setup(_config);
|
||||
return _serialPortClient;
|
||||
_serialSession.Setup(_config);
|
||||
return _serialSession;
|
||||
}
|
||||
internal void StateHasChangedAsync()
|
||||
{
|
||||
@@ -63,7 +63,7 @@ public partial class SerialPortClientPage : IDisposable
|
||||
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
|
||||
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
|
||||
_config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
|
||||
_serialPortClient.Setup(_config);
|
||||
_serialSession.Setup(_config);
|
||||
}
|
||||
base.OnAfterRender(firstRender);
|
||||
}
|
||||
@@ -80,8 +80,8 @@ public partial class SerialPortClientPage : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
_serialPortClient.Close();
|
||||
await GetSerialPortClient().ConnectAsync();
|
||||
_serialSession.Close();
|
||||
await GetSerialSession().ConnectAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -93,7 +93,7 @@ public partial class SerialPortClientPage : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
_serialPortClient.Close();
|
||||
_serialSession.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
@@ -16,6 +16,6 @@ global using System.Threading.Tasks;
|
||||
|
||||
global using ThingsGateway.Components;
|
||||
global using ThingsGateway.Foundation.Core;
|
||||
global using ThingsGateway.Foundation.SerialPorts;
|
||||
global using ThingsGateway.Foundation.Serial;
|
||||
global using ThingsGateway.Foundation.Sockets;
|
||||
|
||||
|
@@ -19,7 +19,7 @@
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<SerialPortClientPage @ref=_serialPortClientPage></SerialPortClientPage>
|
||||
<SerialSessionPage @ref=_serialSessionPage></SerialSessionPage>
|
||||
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
|
@@ -17,9 +17,9 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class DLT645_2007DebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialPortClientPage
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
private SerialPortClientPage _serialPortClientPage;
|
||||
private SerialSessionPage _serialSessionPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
private ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007 _plc;
|
||||
/// <summary>
|
||||
@@ -37,15 +37,15 @@ public partial class DLT645_2007DebugPage
|
||||
//链路基础配置项
|
||||
var config = new TouchSocketConfig();
|
||||
config
|
||||
.SetSerialPortOption(new SerialPortOption() //串口链路才需要
|
||||
.SetSerialProperty(new SerialProperty() //串口链路才需要
|
||||
{
|
||||
PortName = "COM1"
|
||||
});
|
||||
var serialPortClient = new SerialPortClient();//链路对象
|
||||
serialPortClient.Setup(config);
|
||||
var serialSession = new SerialSession();//链路对象
|
||||
serialSession.Setup(config);
|
||||
|
||||
//创建协议对象,构造函数需要传入对应链路对象
|
||||
DLT645_2007 plc = new(serialPortClient)//传入链路
|
||||
DLT645_2007 plc = new(serialSession)//传入链路
|
||||
{
|
||||
//协议配置
|
||||
DataFormat = DataFormat.ABCD,
|
||||
@@ -69,9 +69,9 @@ public partial class DLT645_2007DebugPage
|
||||
""", "csharp"));
|
||||
|
||||
|
||||
if (_serialPortClientPage != null)
|
||||
_serialPortClientPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007(_serialPortClientPage.GetSerialPortClient());
|
||||
if (_serialSessionPage != null)
|
||||
_serialSessionPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007(_serialSessionPage.GetSerialSession());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
|
||||
//初始化
|
||||
|
@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class DLT645_2007OverTcpDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialPortClientPage
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
private TcpClientPage _tcpClientPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
@@ -19,7 +19,7 @@
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<SerialPortClientPage @ref=_serialPortClientPage></SerialPortClientPage>
|
||||
<SerialSessionPage @ref=_serialSessionPage></SerialSessionPage>
|
||||
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
|
@@ -19,9 +19,9 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class ModbusRtuDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialPortClientPage
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
private SerialPortClientPage _serialPortClientPage;
|
||||
private SerialSessionPage _serialSessionPage;
|
||||
private readonly List<(string Code, string Language)> _sections = new();
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
@@ -41,15 +41,15 @@ public partial class ModbusRtuDebugPage
|
||||
//链路基础配置项
|
||||
var config = new TouchSocketConfig();
|
||||
config
|
||||
.SetSerialPortOption(new SerialPortOption() //串口链路才需要
|
||||
.SetSerialProperty(new SerialProperty() //串口链路才需要
|
||||
{
|
||||
PortName = "COM1"
|
||||
});
|
||||
var serialPortClient = new SerialPortClient();//链路对象
|
||||
serialPortClient.Setup(config);
|
||||
var serialSession = new SerialSession();//链路对象
|
||||
serialSession.Setup(config);
|
||||
|
||||
//创建协议对象,构造函数需要传入对应链路对象
|
||||
ModbusRtu plc = new(serialPortClient)//传入链路
|
||||
ModbusRtu plc = new(serialSession)//传入链路
|
||||
{
|
||||
//协议配置
|
||||
DataFormat = DataFormat.ABCD,
|
||||
@@ -72,9 +72,9 @@ public partial class ModbusRtuDebugPage
|
||||
""", "csharp"));
|
||||
|
||||
|
||||
if (_serialPortClientPage != null)
|
||||
_serialPortClientPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu(_serialPortClientPage.GetSerialPortClient());
|
||||
if (_serialSessionPage != null)
|
||||
_serialSessionPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu(_serialSessionPage.GetSerialSession());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
|
@@ -19,7 +19,7 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class ModbusRtuOverTcpDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialPortClientPage
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
private TcpClientPage _tcpClientPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class ModbusRtuOverUdpDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialPortClientPage
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
private UdpSessionPage _udpSessionPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
@@ -19,7 +19,7 @@
|
||||
@using Masa.Blazor;
|
||||
@namespace ThingsGateway.Foundation.Demo
|
||||
|
||||
<SerialPortClientPage @ref=_serialPortClientPage></SerialPortClientPage>
|
||||
<SerialSessionPage @ref=_serialSessionPage></SerialSessionPage>
|
||||
|
||||
<MCard Flat Class="pa-2 my-1" Style="width:100%">
|
||||
<div class="mb-4">驱动配置</div>
|
||||
|
@@ -17,9 +17,9 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class ModbusSerialServerDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialPortClientPage
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
private SerialPortClientPage _serialPortClientPage;
|
||||
private SerialSessionPage _serialSessionPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusSerialServer _plc;
|
||||
@@ -39,15 +39,15 @@ public partial class ModbusSerialServerDebugPage
|
||||
//链路基础配置项
|
||||
var config = new TouchSocketConfig();
|
||||
config
|
||||
.SetSerialPortOption(new SerialPortOption() //串口链路才需要
|
||||
.SetSerialProperty(new SerialProperty() //串口链路才需要
|
||||
{
|
||||
PortName = "COM1"
|
||||
});
|
||||
var serialPortClient = new SerialPortClient();//链路对象
|
||||
serialPortClient.Setup(config);
|
||||
var serialSession = new SerialSession();//链路对象
|
||||
serialSession.Setup(config);
|
||||
|
||||
//创建协议对象,构造函数需要传入对应链路对象
|
||||
ModbusSerialServer plc = new(serialPortClient)//传入链路
|
||||
ModbusSerialServer plc = new(serialSession)//传入链路
|
||||
{
|
||||
//协议配置
|
||||
DataFormat = DataFormat.ABCD,
|
||||
@@ -70,9 +70,9 @@ public partial class ModbusSerialServerDebugPage
|
||||
""", "csharp"));
|
||||
|
||||
|
||||
if (_serialPortClientPage != null)
|
||||
_serialPortClientPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusSerialServer(_serialPortClientPage.GetSerialPortClient());
|
||||
if (_serialSessionPage != null)
|
||||
_serialSessionPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusSerialServer(_serialSessionPage.GetSerialSession());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
//载入配置
|
||||
StateHasChanged();
|
||||
|
@@ -21,7 +21,7 @@ public partial class ModbusTcpDebugPage
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp _plc;
|
||||
|
||||
/// <summary>
|
||||
/// SerialPortClientPage
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
private TcpClientPage _tcpClientPage;
|
||||
/// <summary>
|
||||
|
@@ -40,9 +40,7 @@
|
||||
Dense>
|
||||
</MSelect>
|
||||
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.IsRtu)) Dense HideDetails="@("auto")" @bind-Value=@_plc.IsRtu></MCheckbox>
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.IsCheckMessageId)) Dense HideDetails="@("auto")" @bind-Value=@_plc.IsCheckMessageId></MCheckbox>
|
||||
<MCheckbox Class="ma-1" Style="max-width:200px" Label=@(_plc.Description(x => x.Crc16CheckEnable)) Dense HideDetails="@("auto")" @bind-Value=@_plc.Crc16CheckEnable></MCheckbox>
|
||||
|
||||
}
|
||||
</MRow>
|
@@ -13,9 +13,9 @@
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
|
||||
/// <summary>
|
||||
/// ModbusDtuDebugPage
|
||||
/// ModbusTcpDtuDebugPage
|
||||
/// </summary>
|
||||
public partial class ModbusDtuDebugPage
|
||||
public partial class ModbusTcpDtuDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// TcpServerPage
|
||||
@@ -23,7 +23,7 @@ public partial class ModbusDtuDebugPage
|
||||
private TcpServerPage _tcpServerPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusDtu _plc;
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpDtu _plc;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
@@ -70,7 +70,7 @@ public partial class ModbusDtuDebugPage
|
||||
|
||||
if (_tcpServerPage != null)
|
||||
_tcpServerPage.LogAction = _driverDebugUIPage.LogOut;
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusDtu(_tcpServerPage.GetTcpServer());
|
||||
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpDtu(_tcpServerPage.GetTcpServer());
|
||||
_driverDebugUIPage.Plc = _plc;
|
||||
//载入配置
|
||||
StateHasChanged();
|
@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class ModbusUdpDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialPortClientPage
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
private UdpSessionPage _udpSessionPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
@@ -23,7 +23,7 @@
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using ThingsGateway.Foundation.Adapter.OPCDA.Da;
|
||||
@using ThingsGateway.Foundation.Extension;
|
||||
@using ThingsGateway.Foundation.SerialPorts;
|
||||
@using ThingsGateway.Foundation.Serial;
|
||||
@using Masa.Blazor
|
||||
|
||||
|
||||
|
@@ -20,6 +20,8 @@ using Microsoft.JSInterop;
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
using ThingsGateway.Foundation.Adapter.OPCDA;
|
||||
using ThingsGateway.Foundation.Adapter.OPCDA.Da;
|
||||
|
||||
@@ -43,7 +45,6 @@ public partial class OPCDAClientDebugPage : IDisposable
|
||||
{
|
||||
_plc.SafeDispose();
|
||||
opcDAClientPage.SafeDispose();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -104,7 +105,7 @@ public partial class OPCDAClientDebugPage : IDisposable
|
||||
await PopupService.EnqueueSnackbarAsync("无可用变量", AlertTypes.Warning);
|
||||
return;
|
||||
}
|
||||
await _serviceScope.ServiceProvider.GetService<ICollectDeviceService>().AddAsync(data?.Item1);
|
||||
await _serviceScope.ServiceProvider.GetService<CollectDeviceService>().AddAsync(data?.Item1);
|
||||
await _serviceScope.ServiceProvider.GetService<VariableService>().AddBatchAsync(data?.Item2);
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
@@ -150,7 +151,7 @@ public partial class OPCDAClientDebugPage : IDisposable
|
||||
/// <returns></returns>
|
||||
public async Task DownDeviceExportAsync(CollectDevice data)
|
||||
{
|
||||
using var memoryStream = await _serviceScope.ServiceProvider.GetService<ICollectDeviceService>().ExportFileAsync(new List<CollectDevice>() { data });
|
||||
using var memoryStream = await _serviceScope.ServiceProvider.GetService<CollectDeviceService>().ExportFileAsync(new List<CollectDevice>() { data });
|
||||
using var streamRef = new DotNetStreamReference(stream: memoryStream);
|
||||
JSObjectReference ??= await JSRuntime.LoadModuleAsync("js/downloadFileFromStream");
|
||||
await JSObjectReference.InvokeVoidAsync("downloadFileFromStream", $"设备导出{DateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx", streamRef);
|
||||
|
@@ -25,7 +25,7 @@
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using ThingsGateway.Foundation.Adapter.OPCUA;
|
||||
@using ThingsGateway.Foundation.Extension;
|
||||
@using ThingsGateway.Foundation.SerialPorts;
|
||||
@using ThingsGateway.Foundation.Serial;
|
||||
@using Masa.Blazor
|
||||
|
||||
|
||||
|
@@ -96,7 +96,7 @@ public partial class OPCUAClientDebugPage
|
||||
await PopupService.EnqueueSnackbarAsync("无可用变量", AlertTypes.Warning);
|
||||
return;
|
||||
}
|
||||
await _serviceScope.ServiceProvider.GetService<ICollectDeviceService>().AddAsync(data.Item1);
|
||||
await _serviceScope.ServiceProvider.GetService<CollectDeviceService>().AddAsync(data.Item1);
|
||||
await _serviceScope.ServiceProvider.GetService<VariableService>().AddBatchAsync(data.Item2);
|
||||
await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success);
|
||||
}
|
||||
@@ -141,7 +141,7 @@ public partial class OPCUAClientDebugPage
|
||||
/// <returns></returns>
|
||||
public async Task DownDeviceExportAsync(CollectDevice data)
|
||||
{
|
||||
using var memoryStream = await _serviceScope.ServiceProvider.GetService<ICollectDeviceService>().ExportFileAsync(new List<CollectDevice>() { data });
|
||||
using var memoryStream = await _serviceScope.ServiceProvider.GetService<CollectDeviceService>().ExportFileAsync(new List<CollectDevice>() { data });
|
||||
using var streamRef = new DotNetStreamReference(stream: memoryStream);
|
||||
JSObjectReference ??= await JSRuntime.LoadModuleAsync("js/downloadFileFromStream");
|
||||
await JSObjectReference.InvokeVoidAsync("downloadFileFromStream", $"设备导出{DateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx", streamRef);
|
||||
|
@@ -20,7 +20,7 @@
|
||||
@using ThingsGateway.Foundation.Adapter.Siemens;
|
||||
@using ThingsGateway.Foundation.Core;
|
||||
@using ThingsGateway.Foundation.Extension;
|
||||
@using ThingsGateway.Foundation.SerialPorts;
|
||||
@using ThingsGateway.Foundation.Serial;
|
||||
|
||||
@using Masa.Blazor
|
||||
|
||||
|
@@ -21,7 +21,7 @@ public partial class SiemensDebugPage
|
||||
private ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC _plc;
|
||||
|
||||
/// <summary>
|
||||
/// SerialPortClientPage
|
||||
/// SerialSessionPage
|
||||
/// </summary>
|
||||
private TcpClientPage _tcpClientPage;
|
||||
/// <summary>
|
||||
|
@@ -10,6 +10,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
|
||||
public partial class MainLayout
|
||||
@@ -103,16 +105,16 @@ public partial class MainLayout
|
||||
"Title": "OPCUAClient"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Mqtt",
|
||||
"Children": [
|
||||
{
|
||||
"Href": "/MqttClient",
|
||||
"Title": "MqttClient"
|
||||
}
|
||||
]
|
||||
}
|
||||
//{
|
||||
// "Title": "Mqtt",
|
||||
// "Children": [
|
||||
// {
|
||||
// "Href": "/MqttClient",
|
||||
// "Title": "MqttClient"
|
||||
// }
|
||||
// ]
|
||||
//}
|
||||
]
|
||||
|
||||
|
||||
|
@@ -25,5 +25,5 @@
|
||||
@using System.Net.Http.Json
|
||||
@using System.IO;
|
||||
@using System.Text.Json;
|
||||
@using ThingsGateway.Foundation.SerialPorts;
|
||||
@using ThingsGateway.Foundation.Serial;
|
||||
@using ThingsGateway.Foundation.Sockets;
|
@@ -14,9 +14,9 @@ using Microsoft.AspNetCore.Components.WebView.WindowsForms;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ThingsGateway.Components;
|
||||
using ThingsGateway.Core;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo.Winform
|
||||
{
|
||||
@@ -26,12 +26,14 @@ namespace ThingsGateway.Foundation.Demo.Winform
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
IServiceCollection services = new ServiceCollection();
|
||||
IServiceCollection services = null;
|
||||
|
||||
|
||||
services.AddWindowsFormsBlazorWebView();
|
||||
services.ThingsGatewayComponentsConfigureServices();
|
||||
services.ThingsGatewayCoreConfigureServices();
|
||||
Serve.RunNative(a =>
|
||||
{
|
||||
services = a;
|
||||
services.AddWindowsFormsBlazorWebView();
|
||||
services.ThingsGatewayComponentsConfigureServices();
|
||||
});
|
||||
|
||||
blazorWebView1.HostPage = "wwwroot/index.html";
|
||||
blazorWebView1.Services = services.BuildServiceProvider();
|
||||
|
@@ -7,7 +7,6 @@
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="favicon.ico" />
|
||||
</ItemGroup>
|
||||
|
@@ -1,14 +1,20 @@
|
||||
<Project>
|
||||
<Import Project="$(SolutionDir)\Directory.Build.props" />
|
||||
<!--如果编译net45报错无支持,用一下方法添加net45包-->
|
||||
<!--VS顶部菜单栏 -> 视图 -> 其他 -> 程序包控制台
|
||||
Install-Package Microsoft.NETFramework.ReferenceAssemblies.net45
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<Version>4.0.0.5</Version>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<TargetFrameworks>net45;netstandard2.0;net6.0;net8.0;</TargetFrameworks>
|
||||
<Description>
|
||||
ThingsGateway.Foundation是工业设备通讯类库,归属于ThingsGateway边缘网关项目,说明文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
</Description>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
<Copyright>© 2023-present Diego</Copyright>
|
||||
<RepositoryUrl>https://gitee.com/diego2098/ThingsGateway</RepositoryUrl>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<EmbedUntrackedSource>true</EmbedUntrackedSource>
|
||||
<EmbedAllSources>true</EmbedAllSources>
|
||||
@@ -20,11 +26,17 @@
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://diego2098.gitee.io/thingsgateway-docs/</PackageProjectUrl>
|
||||
<PackageTags>ThingsGateway;Diego;dotNET China;Blazor;设备采集;边缘网关</PackageTags>
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<DelaySign>False</DelaySign>
|
||||
<SatelliteResourceLanguages>zh-Hans</SatelliteResourceLanguages>
|
||||
<PackageOutputPath>..\..\nupkgs</PackageOutputPath>
|
||||
<AssemblyOriginatorKeyFile>..\..\..\snks/ThingsGateway.snk</AssemblyOriginatorKeyFile>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\..\..\README.md" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
@@ -16,13 +16,13 @@ namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
/// <summary>
|
||||
/// DLT645_2007
|
||||
/// </summary>
|
||||
public class DLT645_2007 : ReadWriteDevicesSerialPortClientBase, IDLT645_2007
|
||||
public class DLT645_2007 : ReadWriteDevicesSerialSessionBase, IDLT645_2007
|
||||
{
|
||||
/// <summary>
|
||||
/// DLT645_2007
|
||||
/// </summary>
|
||||
/// <param name="serialPortClient"></param>
|
||||
public DLT645_2007(SerialPortClient serialPortClient) : base(serialPortClient)
|
||||
/// <param name="serialSession"></param>
|
||||
public DLT645_2007(SerialSession serialSession) : base(serialSession)
|
||||
{
|
||||
ThingsGatewayBitConverter = new DLT645_2007BitConverter(EndianType.Big);
|
||||
RegisterByteLength = 2;
|
||||
@@ -62,7 +62,7 @@ public class DLT645_2007 : ReadWriteDevicesSerialPortClientBase, IDLT645_2007
|
||||
{
|
||||
EnableFEHead = EnableFEHead
|
||||
};
|
||||
SerialPortClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
SerialSession.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ public class DLT645_2007 : ReadWriteDevicesSerialPortClientBase, IDLT645_2007
|
||||
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default) => Write(address, value.ToString(), cancellationToken);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) => Task.FromResult(new OperResult());
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, uint value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
/// <inheritdoc/>
|
||||
@@ -125,7 +125,7 @@ public class DLT645_2007 : ReadWriteDevicesSerialPortClientBase, IDLT645_2007
|
||||
public override Task<OperResult> WriteAsync(string address, int value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) => Task.FromResult(new OperResult());
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||
|
||||
|
||||
#region 其他方法
|
||||
|
@@ -106,7 +106,7 @@ public class DLT645_2007OverTcp : ReadWriteDevicesTcpClientBase, IDLT645_2007
|
||||
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default) => Write(address, value.ToString(), cancellationToken);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) => Task.FromResult(new OperResult());
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, uint value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
/// <inheritdoc/>
|
||||
@@ -125,7 +125,7 @@ public class DLT645_2007OverTcp : ReadWriteDevicesTcpClientBase, IDLT645_2007
|
||||
public override Task<OperResult> WriteAsync(string address, int value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) => Task.FromResult(new OperResult());
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||
|
||||
|
||||
#region 其他方法
|
||||
|
@@ -17,5 +17,5 @@ global using System.Threading;
|
||||
global using System.Threading.Tasks;
|
||||
|
||||
global using ThingsGateway.Foundation.Core;
|
||||
global using ThingsGateway.Foundation.SerialPorts;
|
||||
global using ThingsGateway.Foundation.Serial;
|
||||
global using ThingsGateway.Foundation.Sockets;
|
||||
|
@@ -17,5 +17,5 @@ global using System.Threading;
|
||||
global using System.Threading.Tasks;
|
||||
|
||||
global using ThingsGateway.Foundation.Core;
|
||||
global using ThingsGateway.Foundation.SerialPorts;
|
||||
global using ThingsGateway.Foundation.Serial;
|
||||
global using ThingsGateway.Foundation.Sockets;
|
||||
|
@@ -14,14 +14,14 @@ using System.ComponentModel;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <inheritdoc/>
|
||||
public class ModbusDtu : ReadWriteDevicesTcpServerBase
|
||||
public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public ModbusDtu(TcpService tcpService) : base(tcpService)
|
||||
public ModbusTcpDtu(TcpService tcpService) : base(tcpService)
|
||||
{
|
||||
ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big);
|
||||
RegisterByteLength = 2;
|
||||
ModbusDtuPlugin modbusTcpSalvePlugin = new ModbusDtuPlugin();
|
||||
ModbusTcpDtuPlugin modbusTcpSalvePlugin = new ModbusTcpDtuPlugin();
|
||||
tcpService.Config.ConfigurePlugins(a =>
|
||||
{
|
||||
a.Add(modbusTcpSalvePlugin);
|
||||
@@ -35,18 +35,6 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase
|
||||
[Description("检测事务标识符")]
|
||||
public bool IsCheckMessageId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否Rtu格式
|
||||
/// </summary>
|
||||
[Description("是否Rtu格式")]
|
||||
public bool IsRtu { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Crc校验
|
||||
/// </summary>
|
||||
[Description("Crc校验")]
|
||||
public bool Crc16CheckEnable { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 站号
|
||||
/// </summary>
|
||||
@@ -104,49 +92,23 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase
|
||||
{
|
||||
if (socketClient != default)
|
||||
{
|
||||
if (!IsRtu)
|
||||
ModbusTcpDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
IsCheckMessageId = IsCheckMessageId,
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
};
|
||||
socketClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var item in TcpService.GetClients())
|
||||
{
|
||||
ModbusTcpDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
IsCheckMessageId = IsCheckMessageId,
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
};
|
||||
socketClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
else
|
||||
{
|
||||
ModbusRtuDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
Crc16CheckEnable = Crc16CheckEnable,
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
};
|
||||
socketClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//只适配第一个
|
||||
var item = TcpService.GetClients().FirstOrDefault();
|
||||
if (item != null)
|
||||
{
|
||||
if (!IsRtu)
|
||||
{
|
||||
ModbusTcpDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
IsCheckMessageId = IsCheckMessageId,
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
};
|
||||
item.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
else
|
||||
{
|
||||
ModbusRtuDataHandleAdapter dataHandleAdapter = new()
|
||||
{
|
||||
Crc16CheckEnable = Crc16CheckEnable,
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
};
|
||||
item.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
item.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -225,7 +187,7 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase
|
||||
if (TcpService.TryGetSocketClient($"ID={id}", out var client))
|
||||
{
|
||||
SetDataAdapter(client);
|
||||
return SendThenReturn<MessageBase>(command, cancellationToken, client);
|
||||
return SendThenReturn<ModbusTcpMessage>(command, cancellationToken, client);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -238,7 +200,7 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase
|
||||
if (TcpService.TryGetSocketClient($"ID={id}", out var client))
|
||||
{
|
||||
SetDataAdapter(client);
|
||||
return await SendThenReturnAsync<MessageBase>(command, cancellationToken, client);
|
||||
return await SendThenReturnAsync<ModbusTcpMessage>(command, cancellationToken, client);
|
||||
}
|
||||
else if (TcpService.SocketClients.Count == 1)
|
||||
{
|
||||
@@ -246,13 +208,13 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase
|
||||
if (client1 != null)
|
||||
{
|
||||
SetDataAdapter(client1);
|
||||
return await SendThenReturnAsync<MessageBase>(command, cancellationToken, client1);
|
||||
return await SendThenReturnAsync<ModbusTcpMessage>(command, cancellationToken, client1);
|
||||
}
|
||||
}
|
||||
return new OperResult<byte[]>("客户端未连接");
|
||||
}
|
||||
|
||||
internal class ModbusDtuPlugin : PluginBase, ITcpReceivingPlugin
|
||||
internal class ModbusTcpDtuPlugin : PluginBase, ITcpReceivingPlugin
|
||||
{
|
||||
public async Task OnTcpReceiving(ITcpClientBase client, ByteBlockEventArgs e)
|
||||
{
|
@@ -16,13 +16,13 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// ModbusRtu
|
||||
/// </summary>
|
||||
public class ModbusRtu : ReadWriteDevicesSerialPortClientBase
|
||||
public class ModbusRtu : ReadWriteDevicesSerialSessionBase
|
||||
{
|
||||
/// <summary>
|
||||
/// ModbusRtu
|
||||
/// </summary>
|
||||
/// <param name="serialPortClient"></param>
|
||||
public ModbusRtu(SerialPortClient serialPortClient) : base(serialPortClient)
|
||||
/// <param name="serialSession"></param>
|
||||
public ModbusRtu(SerialSession serialSession) : base(serialSession)
|
||||
{
|
||||
ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big);
|
||||
RegisterByteLength = 2;
|
||||
@@ -93,7 +93,7 @@ public class ModbusRtu : ReadWriteDevicesSerialPortClientBase
|
||||
Crc16CheckEnable = Crc16CheckEnable,
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
};
|
||||
SerialPortClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
SerialSession.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -19,7 +19,7 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// </summary>
|
||||
internal class ModbusTcpDataHandleAdapter : ReadWriteDevicesSingleStreamDataHandleAdapter<ModbusTcpMessage>
|
||||
{
|
||||
private readonly IncrementCount _incrementCount = new(ushort.MaxValue);
|
||||
private readonly IncrementCount easyIncrementCount = new(ushort.MaxValue);
|
||||
|
||||
/// <summary>
|
||||
/// 检测事务标识符
|
||||
@@ -39,7 +39,7 @@ internal class ModbusTcpDataHandleAdapter : ReadWriteDevicesSingleStreamDataHand
|
||||
/// <inheritdoc/>
|
||||
public override byte[] PackCommand(byte[] command)
|
||||
{
|
||||
return ModbusHelper.AddModbusTcpHead(command, (ushort)_incrementCount.GetCurrentValue());
|
||||
return ModbusHelper.AddModbusTcpHead(command, (ushort)easyIncrementCount.GetCurrentValue());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -18,7 +18,7 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// </summary>
|
||||
internal class ModbusUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter<ModbusTcpMessage>
|
||||
{
|
||||
private readonly IncrementCount _incrementCount = new(ushort.MaxValue);
|
||||
private readonly IncrementCount easyIncrementCount = new(ushort.MaxValue);
|
||||
|
||||
/// <summary>
|
||||
/// 检测事务标识符
|
||||
@@ -38,7 +38,7 @@ internal class ModbusUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter
|
||||
/// <inheritdoc/>
|
||||
public override byte[] PackCommand(byte[] command)
|
||||
{
|
||||
return ModbusHelper.AddModbusTcpHead(command, (ushort)_incrementCount.GetCurrentValue());
|
||||
return ModbusHelper.AddModbusTcpHead(command, (ushort)easyIncrementCount.GetCurrentValue());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -16,10 +16,10 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class ModbusSerialServer : ReadWriteDevicesSerialPortClientBase, IModbusServer
|
||||
public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase, IModbusServer
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public ModbusSerialServer(SerialPortClient serialPortClient) : base(serialPortClient)
|
||||
public ModbusSerialServer(SerialSession serialSession) : base(serialSession)
|
||||
{
|
||||
ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big);
|
||||
RegisterByteLength = 2;
|
||||
@@ -130,7 +130,7 @@ public class ModbusSerialServer : ReadWriteDevicesSerialPortClientBase, IModbusS
|
||||
{
|
||||
ModbusSerialServerDataHandleAdapter dataHandleAdapter = new();
|
||||
dataHandleAdapter.CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout);
|
||||
SerialPortClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
SerialSession.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ public class ModbusSerialServer : ReadWriteDevicesSerialPortClientBase, IModbusS
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task Received(SerialPortClient client, ReceivedDataEventArgs e)
|
||||
protected override async Task Received(SerialSession client, ReceivedDataEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@@ -253,11 +253,11 @@
|
||||
ModbusRtu
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.#ctor(ThingsGateway.Foundation.SerialPorts.SerialPortClient)">
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.#ctor(ThingsGateway.Foundation.Serial.SerialSession)">
|
||||
<summary>
|
||||
ModbusRtu
|
||||
</summary>
|
||||
<param name="serialPortClient"></param>
|
||||
<param name="serialSession"></param>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.Crc16CheckEnable">
|
||||
<summary>
|
||||
|
@@ -143,7 +143,7 @@ public interface IReadWrite : IDisposable
|
||||
/// <param name="cancellationToken">取消令箭</param>
|
||||
/// <param name="senderClient">传入改参数时,将新建等待线程</param>
|
||||
/// <returns></returns>
|
||||
T SendThenReturn<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>;
|
||||
T SendThenReturn<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>, new();
|
||||
|
||||
/// <summary>
|
||||
/// 异步发送并返回结果
|
||||
@@ -153,7 +153,7 @@ public interface IReadWrite : IDisposable
|
||||
/// <param name="cancellationToken">取消令箭</param>
|
||||
/// <param name="senderClient">传入改参数时,将新建等待线程</param>
|
||||
/// <returns></returns>
|
||||
Task<T> SendThenReturnAsync<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>;
|
||||
Task<T> SendThenReturnAsync<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>, new();
|
||||
|
||||
/// <summary>
|
||||
/// 发送获取数据
|
||||
|
@@ -148,7 +148,7 @@ public abstract class ReadWriteDevicesBase : IReadWrite
|
||||
public abstract void Send(byte[] command, string id = default);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual T SendThenReturn<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>
|
||||
public virtual T SendThenReturn<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>, new()
|
||||
{
|
||||
var item = command;
|
||||
if (FrameTime != 0)
|
||||
@@ -157,7 +157,7 @@ public abstract class ReadWriteDevicesBase : IReadWrite
|
||||
return (T)result.RequestInfo;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public virtual async Task<T> SendThenReturnAsync<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>
|
||||
public virtual async Task<T> SendThenReturnAsync<T>(byte[] command, CancellationToken cancellationToken, ISenderClient senderClient = default) where T : OperResult<byte[]>, new()
|
||||
{
|
||||
var item = command;
|
||||
await Task.Delay(FrameTime, cancellationToken);
|
||||
|
@@ -10,34 +10,33 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 串口读写设备
|
||||
/// </summary>
|
||||
public abstract class ReadWriteDevicesSerialPortClientBase : ReadWriteDevicesBase
|
||||
public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
|
||||
{
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="ReadWriteDevicesSerialPortClientBase"/>
|
||||
/// <inheritdoc cref="ReadWriteDevicesSerialSessionBase"/>
|
||||
/// </summary>
|
||||
/// <param name="serialPortClient"></param>
|
||||
public ReadWriteDevicesSerialPortClientBase(SerialPortClient serialPortClient)
|
||||
/// <param name="serialSession"></param>
|
||||
public ReadWriteDevicesSerialSessionBase(SerialSession serialSession)
|
||||
{
|
||||
SerialPortClient = serialPortClient;
|
||||
WaitingClientEx = SerialPortClient.CreateWaitingClient(new() { });
|
||||
SerialPortClient.Received -= Received;
|
||||
SerialPortClient.Connecting -= Connecting;
|
||||
SerialPortClient.Connected -= Connected;
|
||||
SerialPortClient.Disconnecting -= Disconnecting;
|
||||
SerialPortClient.Disconnected -= Disconnected;
|
||||
SerialPortClient.Connecting += Connecting;
|
||||
SerialPortClient.Connected += Connected;
|
||||
SerialPortClient.Disconnecting += Disconnecting;
|
||||
SerialPortClient.Disconnected += Disconnected;
|
||||
SerialPortClient.Received += Received;
|
||||
SerialSession = serialSession;
|
||||
WaitingClientEx = SerialSession.CreateWaitingClient(new() { });
|
||||
SerialSession.Received -= Received;
|
||||
SerialSession.Connecting -= Connecting;
|
||||
SerialSession.Connected -= Connected;
|
||||
SerialSession.Disconnecting -= Disconnecting;
|
||||
SerialSession.Disconnected -= Disconnected;
|
||||
SerialSession.Connecting += Connecting;
|
||||
SerialSession.Connected += Connected;
|
||||
SerialSession.Disconnecting += Disconnecting;
|
||||
SerialSession.Disconnected += Disconnected;
|
||||
SerialSession.Received += Received;
|
||||
|
||||
Logger = SerialPortClient.Logger;
|
||||
Logger = SerialSession.Logger;
|
||||
}
|
||||
/// <summary>
|
||||
/// 接收解析
|
||||
@@ -45,88 +44,88 @@ public abstract class ReadWriteDevicesSerialPortClientBase : ReadWriteDevicesBas
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Task Received(SerialPortClient client, ReceivedDataEventArgs e)
|
||||
protected virtual Task Received(SerialSession client, ReceivedDataEventArgs e)
|
||||
{
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override ChannelEnum ChannelEnum => ChannelEnum.SerialPortClient;
|
||||
public override ChannelEnum ChannelEnum => ChannelEnum.SerialSession;
|
||||
|
||||
/// <summary>
|
||||
/// 串口管理对象
|
||||
/// </summary>
|
||||
public SerialPortClient SerialPortClient { get; }
|
||||
public SerialSession SerialSession { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认WaitingClientEx
|
||||
/// </summary>
|
||||
public virtual IWaitingClient<SerialPortClient> WaitingClientEx { get; }
|
||||
public virtual IWaitingClient<SerialSession> WaitingClientEx { get; }
|
||||
/// <inheritdoc/>
|
||||
public override bool IsConnected()
|
||||
{
|
||||
return SerialPortClient?.CanSend == true;
|
||||
return SerialSession?.CanSend == true;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override void Connect(CancellationToken cancellationToken)
|
||||
{
|
||||
SerialPortClient.Connect();
|
||||
SerialSession.Connect();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task ConnectAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return SerialPortClient.ConnectAsync();
|
||||
return SerialSession.ConnectAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Disconnect()
|
||||
{
|
||||
if (CascadeDisposal && IsConnected())
|
||||
SerialPortClient.Close();
|
||||
SerialSession.Close();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Dispose()
|
||||
{
|
||||
Disconnect();
|
||||
SerialPortClient.Received -= Received;
|
||||
SerialPortClient.Connecting -= Connecting;
|
||||
SerialPortClient.Connected -= Connected;
|
||||
SerialPortClient.Disconnecting -= Disconnecting;
|
||||
SerialPortClient.Disconnected -= Disconnected;
|
||||
if (CascadeDisposal && !SerialPortClient.DisposedValue)
|
||||
SerialPortClient.SafeDispose();
|
||||
SerialSession.Received -= Received;
|
||||
SerialSession.Connecting -= Connecting;
|
||||
SerialSession.Connected -= Connected;
|
||||
SerialSession.Disconnecting -= Disconnecting;
|
||||
SerialSession.Disconnected -= Disconnected;
|
||||
if (CascadeDisposal && !SerialSession.DisposedValue)
|
||||
SerialSession.SafeDispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return SerialPortClient.ToString();
|
||||
return SerialSession.SerialProperty.ToString();
|
||||
}
|
||||
|
||||
private async Task Connected(ISerialPortClient client, ConnectedEventArgs e)
|
||||
private async Task Connected(ISerialSession client, ConnectedEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.ToString() + "连接成功");
|
||||
Logger?.Debug(client.SerialProperty.ToString() + "连接成功");
|
||||
SetDataAdapter();
|
||||
await EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task Connecting(ISerialPortClient client, SerialConnectingEventArgs e)
|
||||
private async Task Connecting(ISerialSession client, SerialConnectingEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.ToString() + "正在连接");
|
||||
Logger?.Debug(client.SerialProperty.ToString() + "正在连接");
|
||||
await EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task Disconnected(ISerialPortClient client, DisconnectEventArgs e)
|
||||
private async Task Disconnected(ISerialSessionBase client, DisconnectEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.ToString() + "断开连接-" + e.Message);
|
||||
Logger?.Debug(client.SerialProperty.ToString() + "断开连接-" + e.Message);
|
||||
await EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task Disconnecting(ISerialPortClient client, DisconnectEventArgs e)
|
||||
private async Task Disconnecting(ISerialSessionBase client, DisconnectEventArgs e)
|
||||
{
|
||||
Logger?.Debug(client.ToString() + "正在主动断开连接-" + e.Message);
|
||||
Logger?.Debug(client.SerialProperty.ToString() + "正在主动断开连接-" + e.Message);
|
||||
await EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
@@ -151,6 +150,6 @@ public abstract class ReadWriteDevicesSerialPortClientBase : ReadWriteDevicesBas
|
||||
/// <inheritdoc/>
|
||||
public override void Send(byte[] command, string id = default)
|
||||
{
|
||||
SerialPortClient.Send(command);
|
||||
SerialSession.Send(command);
|
||||
}
|
||||
}
|
@@ -53,7 +53,8 @@ public abstract class ReadWriteDevicesTcpServerBase : ReadWriteDevicesBase
|
||||
/// <inheritdoc/>
|
||||
public override Task ConnectAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return TcpService.StartAsync();
|
||||
Connect(cancellationToken);
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -48,7 +48,7 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase
|
||||
/// <inheritdoc/>
|
||||
public override Task ConnectAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return UdpSession.StartAsync();
|
||||
return Task.FromResult(UdpSession.Start());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -69,7 +69,7 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return UdpSession.RemoteIPHost?.ToString();
|
||||
return UdpSession.RemoteIPHost.ToString();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -29,7 +29,6 @@ public abstract class ReadWriteDevicesSingleStreamDataHandleAdapter<TRequest> :
|
||||
public ReadWriteDevicesSingleStreamDataHandleAdapter()
|
||||
{
|
||||
Request = GetInstance();
|
||||
CacheTimeoutEnable = true;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override bool CanSendRequestInfo => false;
|
||||
|
@@ -53,7 +53,7 @@ public abstract class ReadWriteDevicesUdpDataHandleAdapter<TRequest> : UdpDataHa
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return (Owner as UdpSession)?.RemoteIPHost?.ToString();
|
||||
return (Owner as UdpSession)?.RemoteIPHost.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -83,11 +83,11 @@ public abstract class ReadWriteDevicesUdpDataHandleAdapter<TRequest> : UdpDataHa
|
||||
var allBytes = byteBlock.ToArray(0, byteBlock.Len);
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 接收:{(IsHexData ? allBytes.ToHexString(' ') : Encoding.UTF8.GetString(allBytes))}");
|
||||
|
||||
//if (Request?.SendBytes == null)
|
||||
//{
|
||||
// GoReceived(remoteEndPoint, byteBlock, null);
|
||||
// return;
|
||||
//}
|
||||
if (Request?.SendBytes == null)
|
||||
{
|
||||
GoReceived(remoteEndPoint, byteBlock, null);
|
||||
return;
|
||||
}
|
||||
byte[] header = new byte[] { };
|
||||
if (Request.HeadBytesLength > 0)
|
||||
{
|
||||
|
@@ -22,7 +22,7 @@ public enum ChannelEnum
|
||||
/// <inheritdoc/>
|
||||
TcpClient = 1,
|
||||
/// <inheritdoc/>
|
||||
SerialPortClient = 2,
|
||||
SerialSession = 2,
|
||||
/// <inheritdoc/>
|
||||
UdpSession = 4,
|
||||
/// <inheritdoc/>
|
||||
|
@@ -421,74 +421,6 @@ public static class StringExtensions
|
||||
{
|
||||
return value.IsNullOrEmpty() ? defaultValue : ushort.TryParse(value, out var n) ? n : defaultValue;
|
||||
}
|
||||
/// <summary>
|
||||
/// ToDouble
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static double ToDouble(this object value, double defaultValue = 0)
|
||||
{
|
||||
if (value is Double d)
|
||||
{
|
||||
return Double.IsNaN(d) ? defaultValue : (Double)d;
|
||||
}
|
||||
var str = value?.ToString();
|
||||
if (str.IsNullOrEmpty())
|
||||
{
|
||||
return (double)defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? 1 : 0;
|
||||
}
|
||||
return (double)(double.TryParse(str, out var n) ? n : defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ToDecimal
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static decimal ToDecimal(this object value, int defaultValue = 0)
|
||||
{
|
||||
if (value is Double d)
|
||||
{
|
||||
return Double.IsNaN(d) ? defaultValue : (Decimal)d;
|
||||
}
|
||||
var str = value?.ToString();
|
||||
if (str.IsNullOrEmpty())
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? 1 : 0;
|
||||
}
|
||||
return Decimal.TryParse(str, out var n) ? n : defaultValue;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// ToInt
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static int ToInt(this object value, int defaultValue = 0)
|
||||
{
|
||||
if (value == null || value.ToString().IsNullOrEmpty())
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? 1 : 0;
|
||||
}
|
||||
return int.TryParse(value.ToString(), out int n) ? n : defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用 正则表达式 判断字符是不是汉字
|
||||
|
@@ -0,0 +1,48 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
/// <summary>
|
||||
/// Connecting
|
||||
/// </summary>
|
||||
/// <typeparam name="TClient"></typeparam>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
public delegate Task SerialConnectingEventHandler<TClient>(TClient client, SerialConnectingEventArgs e);
|
||||
|
||||
/// <summary>
|
||||
/// 客户端连接事件。
|
||||
/// </summary>
|
||||
public class SerialConnectingEventArgs : MsgPermitEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="serialPort"></param>
|
||||
public SerialConnectingEventArgs(SerialPort serialPort)
|
||||
{
|
||||
this.SerialPort = serialPort;
|
||||
this.IsPermitOperation = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户端Id。该Id的赋值,仅在服务器适用。
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 新初始化的通信器
|
||||
/// </summary>
|
||||
public SerialPort SerialPort { get; private set; }
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
@@ -10,12 +10,15 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Components;
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
|
||||
public class DefaultTimezoneOffsetAccessor : IDefaultTimezoneOffsetAccessor
|
||||
/// <summary>
|
||||
/// 字节事件
|
||||
/// </summary>
|
||||
public class SerialReceivedEventArgs : TouchSocketEventArgs
|
||||
{
|
||||
public TimeSpan GetTimezoneOffsetResult()
|
||||
{
|
||||
return TimeSpan.FromHours(8);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 数据块
|
||||
/// </summary>
|
||||
public ByteBlock UserToken { get; set; }
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
|
||||
/// <summary>
|
||||
/// 串口附加属性
|
||||
/// </summary>
|
||||
public static class SerialConfigExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 串口属性
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty<SerialProperty> SerialProperty =
|
||||
DependencyProperty<SerialProperty>.Register("SerialProperty", new());
|
||||
|
||||
/// <summary>
|
||||
/// 设置串口
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static TouchSocketConfig SetSerialProperty(this TouchSocketConfig config, SerialProperty value)
|
||||
{
|
||||
config.SetValue(SerialProperty, value);
|
||||
return config;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
|
||||
/// <summary>
|
||||
/// SocketExtension
|
||||
/// </summary>
|
||||
public static class SerialPortExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 会使用同步锁,保证所有数据上缓存区。
|
||||
/// </summary>
|
||||
/// <param name="serialPort"></param>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="length"></param>
|
||||
public static void AbsoluteSend(this SerialPort serialPort, byte[] buffer, int offset, int length)
|
||||
{
|
||||
lock (serialPort)
|
||||
{
|
||||
serialPort.Write(buffer, offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试关闭<see cref="SerialPort"/>。不会抛出异常。
|
||||
/// </summary>
|
||||
/// <param name="serialPort"></param>
|
||||
public static void TryClose(this SerialPort serialPort)
|
||||
{
|
||||
lock (serialPort)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (serialPort.IsOpen)
|
||||
{
|
||||
serialPort.Close();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="ISerialSessionBase"/>
|
||||
/// </summary>
|
||||
public interface ISerialSession : ISerialSessionBase, IClientSender, IPluginObject, ISetupConfigObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 成功打开串口
|
||||
/// </summary>
|
||||
ConnectedEventHandler<ISerialSession> Connected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 准备连接串口的时候
|
||||
/// </summary>
|
||||
SerialConnectingEventHandler<ISerialSession> Connecting { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接串口
|
||||
/// </summary>
|
||||
/// <exception cref="Exception"></exception>
|
||||
ISerialSession Connect();
|
||||
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
|
||||
/// <summary>
|
||||
/// 串口连接接口。
|
||||
/// </summary>
|
||||
public interface ISerialSessionBase : ISenderClient, IClient, ISender, IDefaultSender, IPluginObject, IRequsetInfoSender, IConfigObject, IOnlineClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否允许自由调用<see cref="SetDataHandlingAdapter"/>进行赋值。
|
||||
/// </summary>
|
||||
bool CanSetDataHandlingAdapter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据处理适配器
|
||||
/// </summary>
|
||||
SingleStreamDataHandlingAdapter DataHandlingAdapter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 断开连接
|
||||
/// </summary>
|
||||
DisconnectEventHandler<ISerialSessionBase> Disconnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 即将断开连接(仅主动断开时有效)。
|
||||
/// <para>
|
||||
/// </para>
|
||||
/// </summary>
|
||||
DisconnectEventHandler<ISerialSessionBase> Disconnecting { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主通信器
|
||||
/// </summary>
|
||||
SerialPort MainSerialPort { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 串口描述
|
||||
/// </summary>
|
||||
SerialProperty SerialProperty { get; }
|
||||
/// <summary>
|
||||
/// 关闭客户端。
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
void Close(string msg = TouchSocketCoreUtility.Empty);
|
||||
|
||||
/// <summary>
|
||||
/// 设置数据处理适配器
|
||||
/// </summary>
|
||||
/// <param name="adapter"></param>
|
||||
void SetDataHandlingAdapter(SingleStreamDataHandlingAdapter adapter);
|
||||
}
|
@@ -0,0 +1,388 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
internal sealed class InternalSerialCore : SerialCore
|
||||
{
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Serial核心
|
||||
/// </summary>
|
||||
public class SerialCore : IDisposable, ISender
|
||||
{
|
||||
/// <summary>
|
||||
/// 最小缓存尺寸
|
||||
/// </summary>
|
||||
public int MinBufferSize { get; set; } = 1024 * 10;
|
||||
|
||||
/// <summary>
|
||||
/// 最大缓存尺寸
|
||||
/// </summary>
|
||||
public int MaxBufferSize { get; set; } = 1024 * 1024 * 10;
|
||||
#region 字段
|
||||
|
||||
/// <summary>
|
||||
/// 同步根
|
||||
/// </summary>
|
||||
public readonly object SyncRoot = new object();
|
||||
|
||||
private long m_bufferRate;
|
||||
private bool m_online => m_serialPort?.IsOpen == true;
|
||||
private int m_receiveBufferSize = 1024 * 10;
|
||||
private ValueCounter m_receiveCounter;
|
||||
private int m_sendBufferSize = 1024 * 10;
|
||||
private ValueCounter m_sendCounter;
|
||||
private readonly EasyLock m_semaphoreForSend = new EasyLock();
|
||||
private SerialPort m_serialPort;
|
||||
|
||||
#endregion 字段
|
||||
|
||||
/// <summary>
|
||||
/// Tcp核心
|
||||
/// </summary>
|
||||
public SerialCore()
|
||||
{
|
||||
this.m_receiveCounter = new ValueCounter
|
||||
{
|
||||
Period = TimeSpan.FromSeconds(1),
|
||||
OnPeriod = this.OnReceivePeriod
|
||||
};
|
||||
|
||||
this.m_sendCounter = new ValueCounter
|
||||
{
|
||||
Period = TimeSpan.FromSeconds(1),
|
||||
OnPeriod = this.OnSendPeriod
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 析构函数
|
||||
/// </summary>
|
||||
~SerialCore()
|
||||
{
|
||||
this.SafeDispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool CanSend => this.m_online;
|
||||
|
||||
/// <summary>
|
||||
/// 当中断Tcp的时候。当为<see langword="true"/>时,意味着是调用<see cref="Close(string)"/>。当为<see langword="false"/>时,则是其他中断。
|
||||
/// </summary>
|
||||
public Action<SerialCore, bool, string> OnBreakOut { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当发生异常的时候
|
||||
/// </summary>
|
||||
public Action<SerialCore, Exception> OnException { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 在线状态
|
||||
/// </summary>
|
||||
public bool Online { get => this.m_online; }
|
||||
/// <summary>
|
||||
/// UserToken
|
||||
/// </summary>
|
||||
public ByteBlock UserToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当收到数据的时候
|
||||
/// </summary>
|
||||
public Action<SerialCore, ByteBlock> OnReceived { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接收缓存池,运行时的值会根据流速自动调整
|
||||
/// </summary>
|
||||
public int ReceiveBufferSize
|
||||
{
|
||||
get => this.m_receiveBufferSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 接收计数器
|
||||
/// </summary>
|
||||
public ValueCounter ReceiveCounter { get => this.m_receiveCounter; }
|
||||
|
||||
/// <summary>
|
||||
/// 发送缓存池,运行时的值会根据流速自动调整
|
||||
/// </summary>
|
||||
public int SendBufferSize
|
||||
{
|
||||
get => this.m_sendBufferSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送计数器
|
||||
/// </summary>
|
||||
public ValueCounter SendCounter { get => this.m_sendCounter; }
|
||||
|
||||
/// <summary>
|
||||
/// SerialPort
|
||||
/// </summary>
|
||||
public SerialPort MainSerialPort { get => this.m_serialPort; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 开始以Iocp方式接收
|
||||
/// </summary>
|
||||
public virtual void BeginIocpReceive()
|
||||
{
|
||||
var byteBlock = BytePool.Default.GetByteBlock(this.ReceiveBufferSize);
|
||||
this.UserToken = byteBlock;
|
||||
byteBlock.SetLength(0);
|
||||
if (this.m_serialPort.BytesToRead > 0)
|
||||
{
|
||||
this.m_bufferRate += 2;
|
||||
this.ProcessReceived();
|
||||
}
|
||||
m_serialPort.DataReceived += MainSerialPort_DataReceived;
|
||||
}
|
||||
|
||||
private void MainSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.m_bufferRate = 1;
|
||||
this.ProcessReceived();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.PrivateBreakOut(false, ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 请求关闭
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
public virtual void Close(string msg)
|
||||
{
|
||||
this.PrivateBreakOut(true, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
UserToken.SafeDispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置环境,并设置新的<see cref="m_serialPort"/>。
|
||||
/// </summary>
|
||||
/// <param name="socket"></param>
|
||||
public virtual void Reset(SerialPort socket)
|
||||
{
|
||||
if (socket is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(socket));
|
||||
}
|
||||
|
||||
if (!socket.IsOpen)
|
||||
{
|
||||
throw new Exception("新的SerialPort必须在连接状态。");
|
||||
}
|
||||
this.Reset();
|
||||
this.m_serialPort = socket;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置环境。
|
||||
/// </summary>
|
||||
public virtual void Reset()
|
||||
{
|
||||
this.m_receiveCounter.Reset();
|
||||
this.m_sendCounter.Reset();
|
||||
this.m_serialPort = null;
|
||||
this.OnReceived = null;
|
||||
this.OnBreakOut = null;
|
||||
this.UserToken = null;
|
||||
this.m_bufferRate = 1;
|
||||
this.m_receiveBufferSize = this.MinBufferSize;
|
||||
this.m_sendBufferSize = this.MinBufferSize;
|
||||
}
|
||||
/// <summary>
|
||||
/// 判断,当不在连接状态时触发异常。
|
||||
/// </summary>
|
||||
/// <exception cref="NotConnectedException"></exception>
|
||||
protected void ThrowIfNotConnected()
|
||||
{
|
||||
if (!this.m_online)
|
||||
{
|
||||
throw new NotConnectedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送数据。
|
||||
/// <para>
|
||||
/// 内部会根据是否启用Ssl,进行直接发送,还是Ssl发送。
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="length"></param>
|
||||
public virtual void Send(byte[] buffer, int offset, int length)
|
||||
{
|
||||
this.ThrowIfNotConnected();
|
||||
try
|
||||
{
|
||||
this.m_semaphoreForSend.Wait();
|
||||
this.m_serialPort.Write(buffer, offset, length);
|
||||
this.m_sendCounter.Increment(length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.m_semaphoreForSend.Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步发送数据。
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public virtual async Task SendAsync(byte[] buffer, int offset, int length)
|
||||
{
|
||||
this.ThrowIfNotConnected();
|
||||
try
|
||||
{
|
||||
await this.m_semaphoreForSend.WaitAsync();
|
||||
|
||||
this.m_serialPort.Write(buffer, offset, length);
|
||||
this.m_sendCounter.Increment(length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.m_semaphoreForSend.Release();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当中断Tcp时。
|
||||
/// </summary>
|
||||
/// <param name="manual">当为<see langword="true"/>时,意味着是调用<see cref="Close(string)"/>。当为<see langword="false"/>时,则是其他中断。</param>
|
||||
/// <param name="msg"></param>
|
||||
protected virtual void BreakOut(bool manual, string msg)
|
||||
{
|
||||
this.OnBreakOut?.Invoke(this, manual, msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 当发生异常的时候
|
||||
/// </summary>
|
||||
/// <param name="ex"></param>
|
||||
protected virtual void Exception(Exception ex)
|
||||
{
|
||||
this.OnException?.Invoke(this, ex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当收到数据的时候
|
||||
/// </summary>
|
||||
/// <param name="byteBlock"></param>
|
||||
protected virtual void Received(ByteBlock byteBlock)
|
||||
{
|
||||
this.OnReceived?.Invoke(this, byteBlock);
|
||||
}
|
||||
|
||||
private void HandleBuffer(ByteBlock byteBlock)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.m_receiveCounter.Increment(byteBlock.Length);
|
||||
this.Received(byteBlock);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Exception(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
byteBlock.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnReceivePeriod(long value)
|
||||
{
|
||||
this.m_receiveBufferSize = Math.Max(TouchSocketUtility.HitBufferLength(value), this.MinBufferSize);
|
||||
if (this.MainSerialPort != null && !MainSerialPort.IsOpen)
|
||||
{
|
||||
this.MainSerialPort.ReadBufferSize = this.m_receiveBufferSize;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSendPeriod(long value)
|
||||
{
|
||||
this.m_sendBufferSize = Math.Max(TouchSocketUtility.HitBufferLength(value), this.MinBufferSize);
|
||||
if (this.MainSerialPort != null && !MainSerialPort.IsOpen)
|
||||
{
|
||||
this.MainSerialPort.WriteBufferSize = this.m_sendBufferSize;
|
||||
}
|
||||
}
|
||||
|
||||
private void PrivateBreakOut(bool manual, string msg)
|
||||
{
|
||||
lock (this.SyncRoot)
|
||||
{
|
||||
if (this.m_online)
|
||||
{
|
||||
this.BreakOut(manual, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessReceived()
|
||||
{
|
||||
if (!this.m_online)
|
||||
{
|
||||
UserToken?.SafeDispose();
|
||||
return;
|
||||
}
|
||||
if (m_serialPort.BytesToRead > 0)
|
||||
{
|
||||
var byteBlock = UserToken;
|
||||
byte[] buffer = BytePool.Default.Rent(m_serialPort.BytesToRead);
|
||||
int num = m_serialPort.Read(buffer, 0, m_serialPort.BytesToRead);
|
||||
byteBlock.Write(buffer, 0, num);
|
||||
byteBlock.SetLength(num);
|
||||
this.HandleBuffer(byteBlock);
|
||||
try
|
||||
{
|
||||
var newByteBlock = BytePool.Default.GetByteBlock((int)Math.Min(this.ReceiveBufferSize * this.m_bufferRate, this.MaxBufferSize));
|
||||
newByteBlock.SetLength(0);
|
||||
UserToken = newByteBlock;
|
||||
|
||||
if (m_serialPort.BytesToRead > 0)
|
||||
{
|
||||
this.m_bufferRate += 2;
|
||||
this.ProcessReceived();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.PrivateBreakOut(false, ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
|
||||
/// <summary>
|
||||
/// 串口属性
|
||||
/// </summary>
|
||||
public class SerialProperty
|
||||
{
|
||||
/// <summary>
|
||||
/// COM
|
||||
/// </summary>
|
||||
[Description("COM口")]
|
||||
public string PortName { get; set; } = "COM1";
|
||||
/// <summary>
|
||||
/// 波特率
|
||||
/// </summary>
|
||||
[Description("波特率")]
|
||||
public int BaudRate { get; set; } = 9600;
|
||||
/// <summary>
|
||||
/// 数据位
|
||||
/// </summary>
|
||||
[Description("数据位")]
|
||||
public int DataBits { get; set; } = 8;
|
||||
/// <summary>
|
||||
/// 校验位
|
||||
/// </summary>
|
||||
[Description("校验位")]
|
||||
public Parity Parity { get; set; } = Parity.None;
|
||||
/// <summary>
|
||||
/// 停止位
|
||||
/// </summary>
|
||||
[Description("停止位")]
|
||||
public StopBits StopBits { get; set; } = StopBits.One;
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{PortName}[{BaudRate},{DataBits},{StopBits},{Parity}]";
|
||||
}
|
||||
}
|
@@ -0,0 +1,749 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
|
||||
|
||||
/// <inheritdoc cref="SerialSessionBase"/>
|
||||
public class SerialSession : SerialSessionBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 接收到数据
|
||||
/// </summary>
|
||||
public ReceivedEventHandler<SerialSession> Received { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Task ReceivedData(ReceivedDataEventArgs e)
|
||||
{
|
||||
if (this.Received != null)
|
||||
{
|
||||
return this.Received.Invoke(this, e);
|
||||
}
|
||||
return base.ReceivedData(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 串口管理
|
||||
/// </summary>
|
||||
public class SerialSessionBase : SetupConfigObject, ISerialSession
|
||||
{
|
||||
static readonly Protocol SerialPort = new("SerialSession");
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public SerialSessionBase()
|
||||
{
|
||||
this.Protocol = SerialPort;
|
||||
}
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return SerialProperty?.ToString();
|
||||
}
|
||||
#region 变量
|
||||
|
||||
private DelaySender m_delaySender;
|
||||
private bool m_online => MainSerialPort?.IsOpen == true;
|
||||
private readonly EasyLock m_semaphore = new();
|
||||
private readonly InternalSerialCore m_serialCore = new();
|
||||
#endregion 变量
|
||||
|
||||
#region 事件
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConnectedEventHandler<ISerialSession> Connected { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SerialConnectingEventHandler<ISerialSession> Connecting { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DisconnectEventHandler<ISerialSessionBase> Disconnected { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DisconnectEventHandler<ISerialSessionBase> Disconnecting { get; set; }
|
||||
|
||||
private async Task PrivateOnConnected(ConnectedEventArgs o)
|
||||
{
|
||||
await this.OnConnected(o);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 已经建立连接
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual async Task OnConnected(ConnectedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Connected != null)
|
||||
{
|
||||
await this.Connected.Invoke(this, e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(ITcpConnectedPlugin.OnTcpConnected), this, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Log(LogLevel.Error, this, $"在事件{nameof(this.Connected)}中发生错误。", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task PrivateOnConnecting(SerialConnectingEventArgs e)
|
||||
{
|
||||
if (this.CanSetDataHandlingAdapter)
|
||||
{
|
||||
this.SetDataHandlingAdapter(this.Config.GetValue(TouchSocketConfigExtension.TcpDataHandlingAdapterProperty).Invoke());
|
||||
}
|
||||
|
||||
await this.OnConnecting(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 准备连接的时候,此时并未建立连接
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual async Task OnConnecting(SerialConnectingEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Connecting != null)
|
||||
{
|
||||
await this.Connecting.Invoke(this, e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(ITcpConnectingPlugin.OnTcpConnecting), this, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Log(LogLevel.Error, this, $"在事件{nameof(this.OnConnecting)}中发生错误。", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task PrivateOnDisconnected(object obj)
|
||||
{
|
||||
this.m_receiver?.TryInputReceive(default, default);
|
||||
await this.OnDisconnected((DisconnectEventArgs)obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 断开连接。在客户端未设置连接状态时,不会触发
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual async Task OnDisconnected(DisconnectEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Disconnected != null)
|
||||
{
|
||||
await this.Disconnected.Invoke(this, e).ConfigureAwait(false);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await this.PluginsManager.RaiseAsync(nameof(ITcpDisconnectedPlugin.OnTcpDisconnected), this, e).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Log(LogLevel.Error, this, $"在事件{nameof(this.Disconnected)}中发生错误。", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task PrivateOnDisconnecting(object obj)
|
||||
{
|
||||
await this.OnDisconnecting((DisconnectEventArgs)obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 即将断开连接(仅主动断开时有效)。
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual async Task OnDisconnecting(DisconnectEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Disconnecting != null)
|
||||
{
|
||||
await this.Disconnecting.Invoke(this, e).ConfigureAwait(false);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await this.PluginsManager.RaiseAsync(nameof(ITcpDisconnectingPlugin.OnTcpDisconnecting), this, e).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Log(LogLevel.Error, this, $"在事件{nameof(this.Disconnecting)}中发生错误。", ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion 事件
|
||||
|
||||
#region 属性
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DateTime LastReceivedTime => this.GetSerialCore().ReceiveCounter.LastIncrement;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DateTime LastSendTime => this.GetSerialCore().SendCounter.LastIncrement;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual bool CanSetDataHandlingAdapter => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SingleStreamDataHandlingAdapter DataHandlingAdapter { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SerialProperty SerialProperty { get; private set; }
|
||||
/// <inheritdoc/>
|
||||
public SerialPort MainSerialPort { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Online { get => this.m_online; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool CanSend => this.m_online;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Protocol Protocol { get; set; }
|
||||
|
||||
|
||||
|
||||
#endregion 属性
|
||||
|
||||
#region 断开操作
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual void Close(string msg = TouchSocketCoreUtility.Empty)
|
||||
{
|
||||
lock (this.GetSerialCore())
|
||||
{
|
||||
if (this.m_online)
|
||||
{
|
||||
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, msg));
|
||||
this.MainSerialPort.TryClose();
|
||||
this.BreakOut(true, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
lock (this.GetSerialCore())
|
||||
{
|
||||
if (this.m_online)
|
||||
{
|
||||
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
|
||||
this.BreakOut(true, $"{nameof(Dispose)}主动断开");
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#endregion 断开操作
|
||||
|
||||
#region Connect
|
||||
|
||||
/// <summary>
|
||||
/// 打开串口
|
||||
/// </summary>
|
||||
protected void Open()
|
||||
{
|
||||
try
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
this.m_semaphore.Wait();
|
||||
if (this.m_online)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.DisposedValue)
|
||||
{
|
||||
throw new ObjectDisposedException(this.GetType().FullName);
|
||||
}
|
||||
if (this.Config == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(this.Config), "配置文件不能为空。");
|
||||
}
|
||||
var serialProperty = this.Config.GetValue(SerialConfigExtension.SerialProperty) ?? throw new ArgumentNullException("串口配置不能为空。");
|
||||
this.MainSerialPort.SafeDispose();
|
||||
var serialPort = CreateSerial(serialProperty);
|
||||
this.PrivateOnConnecting(new(serialPort)).ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
|
||||
serialPort.Open();
|
||||
|
||||
this.SetSerialPort(serialPort);
|
||||
this.BeginReceive();
|
||||
|
||||
this.PrivateOnConnected(new()).ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.m_semaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void BeginReceive()
|
||||
{
|
||||
this.GetSerialCore().BeginIocpReceive();
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual ISerialSession Connect()
|
||||
{
|
||||
this.Open();
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<ISerialSession> ConnectAsync()
|
||||
{
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
return this.Connect();
|
||||
});
|
||||
}
|
||||
|
||||
#endregion Connect
|
||||
|
||||
#region Receiver
|
||||
|
||||
private Receiver m_receiver;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReceiver CreateReceiver()
|
||||
{
|
||||
return this.m_receiver ??= new Receiver(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void ClearReceiver()
|
||||
{
|
||||
this.m_receiver = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void SerialCoreBreakOut(SerialCore core, bool manual, string msg)
|
||||
{
|
||||
this.BreakOut(manual, msg);
|
||||
}
|
||||
/// <summary>
|
||||
/// BreakOut。
|
||||
/// </summary>
|
||||
/// <param name="manual"></param>
|
||||
/// <param name="msg"></param>
|
||||
protected void BreakOut(bool manual, string msg)
|
||||
{
|
||||
lock (this.GetSerialCore())
|
||||
{
|
||||
if (this.m_online)
|
||||
{
|
||||
this.MainSerialPort.SafeDispose();
|
||||
this.m_delaySender.SafeDispose();
|
||||
this.DataHandlingAdapter.SafeDispose();
|
||||
Task.Factory.StartNew(this.PrivateOnDisconnected, new DisconnectEventArgs(manual, msg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private SerialCore GetSerialCore()
|
||||
{
|
||||
this.ThrowIfDisposed();
|
||||
return this.m_serialCore ?? throw new ObjectDisposedException(this.GetType().Name);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual void SetDataHandlingAdapter(SingleStreamDataHandlingAdapter adapter)
|
||||
{
|
||||
if (!this.CanSetDataHandlingAdapter)
|
||||
{
|
||||
throw new Exception($"不允许自由调用{nameof(SetDataHandlingAdapter)}进行赋值。");
|
||||
}
|
||||
|
||||
this.SetAdapter(adapter);
|
||||
}
|
||||
|
||||
|
||||
private void PrivateHandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
|
||||
{
|
||||
if (this.m_receiver != null)
|
||||
{
|
||||
if (this.m_receiver.TryInputReceive(byteBlock, requestInfo))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.ReceivedData(new ReceivedDataEventArgs(byteBlock, requestInfo)).GetFalseAwaitResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当收到适配器处理的数据时。
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
/// <returns>如果返回<see langword="true"/>则表示数据已被处理,且不会再向下传递。</returns>
|
||||
protected virtual Task ReceivedData(ReceivedDataEventArgs e)
|
||||
{
|
||||
return this.PluginsManager.RaiseAsync(nameof(ITcpReceivedPlugin.OnTcpReceived), this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当即将发送时,如果覆盖父类方法,则不会触发插件。
|
||||
/// </summary>
|
||||
/// <param name="buffer">数据缓存区</param>
|
||||
/// <param name="offset">偏移</param>
|
||||
/// <param name="length">长度</param>
|
||||
/// <returns>返回值表示是否允许发送</returns>
|
||||
protected virtual async Task<bool> SendingData(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (this.PluginsManager.GetPluginCount(nameof(ITcpSendingPlugin.OnTcpSending)) > 0)
|
||||
{
|
||||
var args = new SendingEventArgs(buffer, offset, length);
|
||||
await this.PluginsManager.RaiseAsync(nameof(ITcpSendingPlugin.OnTcpSending), this, args).ConfigureAwait(false);
|
||||
return args.IsPermitOperation;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void LoadConfig(TouchSocketConfig config)
|
||||
{
|
||||
this.SerialProperty = config.GetValue(SerialConfigExtension.SerialProperty);
|
||||
this.Logger ??= this.Container.Resolve<ILog>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置适配器,该方法不会检验<see cref="CanSetDataHandlingAdapter"/>的值。
|
||||
/// </summary>
|
||||
/// <param name="adapter"></param>
|
||||
protected void SetAdapter(SingleStreamDataHandlingAdapter adapter)
|
||||
{
|
||||
this.ThrowIfDisposed();
|
||||
if (adapter is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(adapter));
|
||||
}
|
||||
|
||||
if (this.Config != null)
|
||||
{
|
||||
adapter.Config(this.Config);
|
||||
}
|
||||
|
||||
adapter.Logger = this.Logger;
|
||||
adapter.OnLoaded(this);
|
||||
adapter.ReceivedCallBack = this.PrivateHandleReceivedData;
|
||||
adapter.SendCallBack = this.DefaultSend;
|
||||
adapter.SendAsyncCallBack = this.DefaultSendAsync;
|
||||
this.DataHandlingAdapter = adapter;
|
||||
}
|
||||
|
||||
private static SerialPort CreateSerial(SerialProperty serialProperty)
|
||||
{
|
||||
SerialPort serialPort = new(serialProperty.PortName, serialProperty.BaudRate, serialProperty.Parity, serialProperty.DataBits, serialProperty.StopBits)
|
||||
{
|
||||
DtrEnable = true,
|
||||
RtsEnable = true
|
||||
};
|
||||
return serialPort;
|
||||
}
|
||||
|
||||
#region 发送
|
||||
|
||||
#region 同步发送
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="requestInfo"></param>
|
||||
/// <exception cref="NotConnectedException"></exception>
|
||||
/// <exception cref="OverlengthException"></exception>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public void Send(IRequestInfo requestInfo)
|
||||
{
|
||||
if (this.DisposedValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.DataHandlingAdapter == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
|
||||
}
|
||||
if (!this.DataHandlingAdapter.CanSendRequestInfo)
|
||||
{
|
||||
throw new NotSupportedException($"当前适配器不支持对象发送。");
|
||||
}
|
||||
this.DataHandlingAdapter.SendInput(requestInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="buffer"><inheritdoc/></param>
|
||||
/// <param name="offset"><inheritdoc/></param>
|
||||
/// <param name="length"><inheritdoc/></param>
|
||||
/// <exception cref="NotConnectedException"><inheritdoc/></exception>
|
||||
/// <exception cref="OverlengthException"><inheritdoc/></exception>
|
||||
/// <exception cref="Exception"><inheritdoc/></exception>
|
||||
public virtual void Send(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (this.DataHandlingAdapter == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
|
||||
}
|
||||
this.DataHandlingAdapter.SendInput(buffer, offset, length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="transferBytes"><inheritdoc/></param>
|
||||
/// <exception cref="NotConnectedException"><inheritdoc/></exception>
|
||||
/// <exception cref="OverlengthException"><inheritdoc/></exception>
|
||||
/// <exception cref="Exception"><inheritdoc/></exception>
|
||||
public virtual void Send(IList<ArraySegment<byte>> transferBytes)
|
||||
{
|
||||
if (this.DataHandlingAdapter == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
|
||||
}
|
||||
|
||||
if (this.DataHandlingAdapter.CanSplicingSend)
|
||||
{
|
||||
this.DataHandlingAdapter.SendInput(transferBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
var length = 0;
|
||||
foreach (var item in transferBytes)
|
||||
{
|
||||
length += item.Count;
|
||||
}
|
||||
using (var byteBlock = new ByteBlock(length))
|
||||
{
|
||||
foreach (var item in transferBytes)
|
||||
{
|
||||
byteBlock.Write(item.Array, item.Offset, item.Count);
|
||||
}
|
||||
this.DataHandlingAdapter.SendInput(byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion 同步发送
|
||||
|
||||
#region 异步发送
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <exception cref="NotConnectedException"></exception>
|
||||
/// <exception cref="OverlengthException"></exception>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public virtual Task SendAsync(byte[] buffer, int offset, int length)
|
||||
{
|
||||
this.ThrowIfDisposed();
|
||||
if (this.DataHandlingAdapter == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
|
||||
}
|
||||
return this.DataHandlingAdapter.SendInputAsync(buffer, offset, length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="requestInfo"></param>
|
||||
/// <exception cref="NotConnectedException"></exception>
|
||||
/// <exception cref="OverlengthException"></exception>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public virtual Task SendAsync(IRequestInfo requestInfo)
|
||||
{
|
||||
this.ThrowIfDisposed();
|
||||
if (this.DataHandlingAdapter == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
|
||||
}
|
||||
if (!this.DataHandlingAdapter.CanSendRequestInfo)
|
||||
{
|
||||
throw new NotSupportedException($"当前适配器不支持对象发送。");
|
||||
}
|
||||
return this.DataHandlingAdapter.SendInputAsync(requestInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="transferBytes"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public virtual Task SendAsync(IList<ArraySegment<byte>> transferBytes)
|
||||
{
|
||||
this.ThrowIfDisposed();
|
||||
if (this.DataHandlingAdapter == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
|
||||
}
|
||||
if (this.DataHandlingAdapter.CanSplicingSend)
|
||||
{
|
||||
return this.DataHandlingAdapter.SendInputAsync(transferBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
var length = 0;
|
||||
foreach (var item in transferBytes)
|
||||
{
|
||||
length += item.Count;
|
||||
}
|
||||
using (var byteBlock = new ByteBlock(length))
|
||||
{
|
||||
foreach (var item in transferBytes)
|
||||
{
|
||||
byteBlock.Write(item.Array, item.Offset, item.Count);
|
||||
}
|
||||
return this.DataHandlingAdapter.SendInputAsync(byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion 异步发送
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void DefaultSend(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (this.SendingData(buffer, offset, length).GetFalseAwaitResult())
|
||||
{
|
||||
if (this.m_delaySender != null)
|
||||
{
|
||||
this.m_delaySender.Send(new QueueDataBytes(buffer, offset, length));
|
||||
return;
|
||||
}
|
||||
this.GetSerialCore().Send(buffer, offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task DefaultSendAsync(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (await this.SendingData(buffer, offset, length))
|
||||
{
|
||||
await this.GetSerialCore().SendAsync(buffer, offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion 发送
|
||||
|
||||
|
||||
#region 自定义
|
||||
|
||||
|
||||
private void SetSerialPort(SerialPort serialPort)
|
||||
{
|
||||
if (serialPort == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.MainSerialPort = serialPort;
|
||||
this.SerialProperty ??= new();
|
||||
this.SerialProperty.Parity = serialPort.Parity;
|
||||
this.SerialProperty.PortName = serialPort.PortName;
|
||||
this.SerialProperty.StopBits = serialPort.StopBits;
|
||||
this.SerialProperty.DataBits = serialPort.DataBits;
|
||||
this.SerialProperty.BaudRate = serialPort.BaudRate;
|
||||
|
||||
var delaySenderOption = this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty);
|
||||
if (delaySenderOption != null)
|
||||
{
|
||||
this.m_delaySender = new DelaySender(delaySenderOption, this.MainSerialPort.AbsoluteSend);
|
||||
}
|
||||
this.m_serialCore.Reset(serialPort);
|
||||
this.m_serialCore.OnReceived = this.HandleReceived;
|
||||
this.m_serialCore.OnBreakOut = this.SerialCoreBreakOut;
|
||||
if (this.Config.GetValue(TouchSocketConfigExtension.MinBufferSizeProperty) is int minValue)
|
||||
{
|
||||
this.m_serialCore.MinBufferSize = minValue;
|
||||
}
|
||||
|
||||
if (this.Config.GetValue(TouchSocketConfigExtension.MaxBufferSizeProperty) is int maxValue)
|
||||
{
|
||||
this.m_serialCore.MaxBufferSize = maxValue;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleReceived(SerialCore core, ByteBlock byteBlock)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.DisposedValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.ReceivingData(byteBlock).GetFalseAwaitResult())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.DataHandlingAdapter == null)
|
||||
{
|
||||
this.Logger.Error(this, TouchSocketResource.NullDataAdapter.GetDescription());
|
||||
return;
|
||||
}
|
||||
this.DataHandlingAdapter.ReceivedInput(byteBlock);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Log(LogLevel.Error, this, "在处理数据时发生错误", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当收到原始数据
|
||||
/// </summary>
|
||||
/// <param name="byteBlock"></param>
|
||||
/// <returns>如果返回<see langword="true"/>则表示数据已被处理,且不会再向下传递。</returns>
|
||||
protected virtual Task<bool> ReceivingData(ByteBlock byteBlock)
|
||||
{
|
||||
if (this.PluginsManager.GetPluginCount(nameof(ITcpReceivingPlugin.OnTcpReceiving)) > 0)
|
||||
{
|
||||
return this.PluginsManager.RaiseAsync(nameof(ITcpReceivingPlugin.OnTcpReceiving), this, new ByteBlockEventArgs(byteBlock));
|
||||
}
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
@@ -20,5 +20,6 @@ global using System.Threading.Tasks;
|
||||
global using ThingsGateway.Foundation.Core;
|
||||
global using ThingsGateway.Foundation.Http;
|
||||
global using ThingsGateway.Foundation.Rpc;
|
||||
global using ThingsGateway.Foundation.SerialPorts;
|
||||
global using ThingsGateway.Foundation.Serial;
|
||||
global using ThingsGateway.Foundation.Sockets;
|
||||
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net45'">
|
||||
|
@@ -15,7 +15,7 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// <summary>
|
||||
/// 具有设置配置的对象接口
|
||||
/// </summary>
|
||||
public interface ISetupConfigObject : IConfigObject, IPluginObject, IResolverObject
|
||||
public interface ISetupConfigObject : IConfigObject, IPluginObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置设置项
|
||||
@@ -23,12 +23,5 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// <param name="config"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
void Setup(TouchSocketConfig config);
|
||||
|
||||
/// <summary>
|
||||
/// 异步配置设置项
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <returns></returns>
|
||||
Task SetupAsync(TouchSocketConfig config);
|
||||
}
|
||||
}
|
||||
|
@@ -23,10 +23,10 @@ namespace ThingsGateway.Foundation.Core
|
||||
public override TouchSocketConfig Config => this.m_config;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IResolver Resolver { get; private set; }
|
||||
public IContainer Container { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IPluginManager PluginManager { get; private set; }
|
||||
public IPluginsManager PluginsManager { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Setup(TouchSocketConfig config)
|
||||
@@ -40,27 +40,11 @@ namespace ThingsGateway.Foundation.Core
|
||||
|
||||
this.BuildConfig(config);
|
||||
|
||||
this.PluginManager?.Raise(nameof(ILoadingConfigPlugin.OnLoadingConfig), this, new ConfigEventArgs(config));
|
||||
this.PluginsManager?.Raise(nameof(ILoadingConfigPlugin.OnLoadingConfig), this, new ConfigEventArgs(config));
|
||||
this.LoadConfig(this.Config);
|
||||
this.PluginManager?.Raise(nameof(ILoadedConfigPlugin.OnLoadedConfig), this, new ConfigEventArgs(config));
|
||||
this.PluginsManager?.Raise(nameof(ILoadedConfigPlugin.OnLoadedConfig), this, new ConfigEventArgs(config));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public async Task SetupAsync(TouchSocketConfig config)
|
||||
{
|
||||
if (config == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(config));
|
||||
}
|
||||
|
||||
this.ThrowIfDisposed();
|
||||
|
||||
this.BuildConfig(config);
|
||||
|
||||
await this.PluginManager.RaiseAsync(nameof(ILoadingConfigPlugin.OnLoadingConfig), this, new ConfigEventArgs(config)).ConfigureFalseAwait();
|
||||
this.LoadConfig(config);
|
||||
//return EasyTask.CompletedTask;
|
||||
await this.PluginManager.RaiseAsync(nameof(ILoadedConfigPlugin.OnLoadedConfig), this, new ConfigEventArgs(config)).ConfigureFalseAwait();
|
||||
}
|
||||
/// <summary>
|
||||
/// 加载配置
|
||||
/// </summary>
|
||||
@@ -72,48 +56,47 @@ namespace ThingsGateway.Foundation.Core
|
||||
|
||||
private void BuildConfig(TouchSocketConfig config)
|
||||
{
|
||||
this.m_config = config ?? throw new ArgumentNullException(nameof(config));
|
||||
this.m_config = config;
|
||||
|
||||
if (!config.TryGetValue(TouchSocketCoreConfigExtension.ResolverProperty, out var resolver))
|
||||
if (!config.TryGetValue(TouchSocketCoreConfigExtension.ContainerProperty, out var container))
|
||||
{
|
||||
if (!config.TryGetValue(TouchSocketCoreConfigExtension.RegistratorProperty, out var registrator))
|
||||
{
|
||||
registrator = new Container();
|
||||
}
|
||||
|
||||
if (!registrator.IsRegistered(typeof(ILog)))
|
||||
{
|
||||
registrator.RegisterSingleton<ILog>(new LoggerGroup());
|
||||
}
|
||||
|
||||
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigureContainerProperty) is Action<IRegistrator> actionContainer)
|
||||
{
|
||||
actionContainer.Invoke(registrator);
|
||||
}
|
||||
|
||||
resolver = registrator.BuildResolver();
|
||||
container = new Container();
|
||||
}
|
||||
|
||||
IPluginManager pluginManager;
|
||||
if ((!this.Config.GetValue(TouchSocketCoreConfigExtension.NewPluginManagerProperty)) && resolver.IsRegistered<IPluginManager>())
|
||||
if (!container.IsRegistered(typeof(ILog)))
|
||||
{
|
||||
pluginManager = resolver.Resolve<IPluginManager>();
|
||||
container.RegisterSingleton<ILog, LoggerGroup>();
|
||||
}
|
||||
|
||||
if (!(config.GetValue(TouchSocketCoreConfigExtension.PluginsManagerProperty) is IPluginsManager pluginsManager))
|
||||
{
|
||||
pluginsManager = new PluginsManager(container);
|
||||
}
|
||||
|
||||
if (container.IsRegistered(typeof(IPluginsManager)))
|
||||
{
|
||||
pluginsManager = container.Resolve<IPluginsManager>();
|
||||
}
|
||||
else
|
||||
{
|
||||
pluginManager = new PluginManager(resolver);
|
||||
container.RegisterSingleton<IPluginsManager>(pluginsManager);
|
||||
}
|
||||
|
||||
if (this.Config.GetValue(TouchSocketCoreConfigExtension.ConfigurePluginsProperty) is Action<IPluginManager> actionPluginManager)
|
||||
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigureContainerProperty) is Action<IContainer> actionContainer)
|
||||
{
|
||||
pluginManager.Enable = true;
|
||||
actionPluginManager.Invoke(pluginManager);
|
||||
actionContainer.Invoke(container);
|
||||
}
|
||||
|
||||
this.Logger ??= resolver.Resolve<ILog>();
|
||||
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigurePluginsProperty) is Action<IPluginsManager> actionPluginsManager)
|
||||
{
|
||||
pluginsManager.Enable = true;
|
||||
actionPluginsManager.Invoke(pluginsManager);
|
||||
}
|
||||
|
||||
this.PluginManager = pluginManager;
|
||||
this.Resolver = resolver;
|
||||
this.Logger ??= container.Resolve<ILog>();
|
||||
|
||||
this.Container = container;
|
||||
this.PluginsManager = pluginsManager;
|
||||
}
|
||||
}
|
||||
}
|
@@ -35,14 +35,14 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// <summary>
|
||||
/// 配置插件。
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty<Action<IPluginManager>> ConfigurePluginsProperty =
|
||||
DependencyProperty<Action<IPluginManager>>.Register("ConfigurePlugins", null);
|
||||
public static readonly DependencyProperty<Action<IPluginsManager>> ConfigurePluginsProperty =
|
||||
DependencyProperty<Action<IPluginsManager>>.Register("ConfigurePlugins", null);
|
||||
|
||||
/// <summary>
|
||||
/// 是否使用新插件管理器。
|
||||
/// 容器
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty<bool> NewPluginManagerProperty =
|
||||
DependencyProperty<bool>.Register("NewPluginManager", false);
|
||||
public static readonly DependencyProperty<IPluginsManager> PluginsManagerProperty =
|
||||
DependencyProperty<IPluginsManager>.Register("PluginsManager", null);
|
||||
|
||||
/// <summary>
|
||||
/// 配置插件。
|
||||
@@ -50,7 +50,7 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// <param name="config"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static TouchSocketConfig ConfigurePlugins(this TouchSocketConfig config, Action<IPluginManager> value)
|
||||
public static TouchSocketConfig ConfigurePlugins(this TouchSocketConfig config, Action<IPluginsManager> value)
|
||||
{
|
||||
if (config.TryGetValue(ConfigurePluginsProperty, out var action))
|
||||
{
|
||||
@@ -64,19 +64,15 @@ namespace ThingsGateway.Foundation.Core
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 使用新的插件管理器。
|
||||
/// <para>
|
||||
/// 一般的,当在容器<see cref="IContainer"/>中注入<see cref="IPluginManager"/>时。会使用容器中的<see cref="IPluginManager"/>。
|
||||
/// 但是有时候,我们希望个别配置能够独立使用插件管理器。所以可以使用此配置。
|
||||
/// </para>
|
||||
/// 使用插件。
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static TouchSocketConfig UseNewPluginManager(this TouchSocketConfig config)
|
||||
public static TouchSocketConfig SetPluginsManager(this TouchSocketConfig config, IPluginsManager value)
|
||||
{
|
||||
config.SetValue(NewPluginManagerProperty, true);
|
||||
config.SetValue(PluginsManagerProperty, value);
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -87,21 +83,14 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// <summary>
|
||||
/// 配置容器注入。
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty<Action<IRegistrator>> ConfigureContainerProperty =
|
||||
DependencyProperty<Action<IRegistrator>>.Register("ConfigureContainer", null);
|
||||
public static readonly DependencyProperty<Action<IContainer>> ConfigureContainerProperty =
|
||||
DependencyProperty<Action<IContainer>>.Register("ConfigureContainer", null);
|
||||
|
||||
/// <summary>
|
||||
/// 容器注册
|
||||
/// 容器
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty<IRegistrator> RegistratorProperty =
|
||||
DependencyProperty<IRegistrator>.Register("Registrator", null);
|
||||
|
||||
/// <summary>
|
||||
/// 容器提供者
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty<IResolver> ResolverProperty =
|
||||
DependencyProperty<IResolver>.Register("Resolver", null);
|
||||
|
||||
public static readonly DependencyProperty<IContainer> ContainerProperty =
|
||||
DependencyProperty<IContainer>.Register("Container", null);
|
||||
|
||||
/// <summary>
|
||||
/// 配置容器注入。
|
||||
@@ -109,7 +98,7 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// <param name="config"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static TouchSocketConfig ConfigureContainer(this TouchSocketConfig config, Action<IRegistrator> value)
|
||||
public static TouchSocketConfig ConfigureContainer(this TouchSocketConfig config, Action<IContainer> value)
|
||||
{
|
||||
if (config.TryGetValue(ConfigureContainerProperty, out var action))
|
||||
{
|
||||
@@ -123,28 +112,15 @@ namespace ThingsGateway.Foundation.Core
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置<see cref="IResolver"/>
|
||||
/// 设置容器。
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static TouchSocketConfig SetResolver(this TouchSocketConfig config, IResolver value)
|
||||
public static TouchSocketConfig SetContainer(this TouchSocketConfig config, IContainer value)
|
||||
{
|
||||
config.SetValue(ResolverProperty, value);
|
||||
return config;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置<see cref="IRegistrator"/>
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static TouchSocketConfig SetRegistrator(this TouchSocketConfig config, IRegistrator value)
|
||||
{
|
||||
config.SetValue(RegistratorProperty, value);
|
||||
config.SetValue(ContainerProperty, value);
|
||||
return config;
|
||||
}
|
||||
|
||||
|
@@ -1,735 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// API首页:http://rrqm_home.gitee.io/touchsocket/
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// API首页:http://rrqm_home.gitee.io/touchsocket/
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.Data;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ThingsGateway.Foundation.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// ContainerExtension
|
||||
/// </summary>
|
||||
public static class ContainerExtension
|
||||
{
|
||||
#region RegisterSingleton
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <typeparam name="TFrom"></typeparam>
|
||||
/// <typeparam name="TTo"></typeparam>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="instance"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton<TFrom, TTo>(this IRegistrator registrator, TTo instance)
|
||||
where TFrom : class
|
||||
where TTo : class, TFrom
|
||||
{
|
||||
RegisterSingleton(registrator, typeof(TFrom), instance);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="instance"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton(this IRegistrator registrator, object instance)
|
||||
{
|
||||
if (instance is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(instance));
|
||||
}
|
||||
|
||||
RegisterSingleton(registrator, instance.GetType(), instance);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public static IRegistrator RegisterSingleton(this IRegistrator registrator, Type fromType)
|
||||
{
|
||||
if (fromType is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(fromType));
|
||||
}
|
||||
|
||||
RegisterSingleton(registrator, fromType, fromType);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <typeparam name="TFrom"></typeparam>
|
||||
/// <typeparam name="TTo"></typeparam>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="instance"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton<TFrom, TTo>(this IRegistrator registrator, string key, TTo instance)
|
||||
where TFrom : class
|
||||
where TTo : class, TFrom
|
||||
{
|
||||
RegisterSingleton(registrator, typeof(TFrom), instance, key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <param name="instance"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton(this IRegistrator registrator, Type fromType, object instance, string key)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(fromType, instance), key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <param name="instance"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton(this IRegistrator registrator, Type fromType, object instance)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(fromType, instance));
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <typeparam name="TFrom"></typeparam>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="instance"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton<TFrom>(this IRegistrator registrator, object instance, string key)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(typeof(TFrom), instance), key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <typeparam name="TFrom"></typeparam>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="instance"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton<TFrom>(this IRegistrator registrator, object instance)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(typeof(TFrom), instance));
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="instance"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton(this IRegistrator registrator, object instance, string key)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(instance.GetType(), instance), key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <typeparam name="TFrom"></typeparam>
|
||||
/// <param name="registrator"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton<TFrom>(this IRegistrator registrator)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(typeof(TFrom), typeof(TFrom), Lifetime.Singleton));
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <typeparam name="TFrom"></typeparam>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton<TFrom>(this IRegistrator registrator, string key)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(typeof(TFrom), typeof(TFrom), Lifetime.Singleton), key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <param name="toType"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton(this IRegistrator registrator, Type fromType, Type toType)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(fromType, toType, Lifetime.Singleton));
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <param name="toType"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton(this IRegistrator registrator, Type fromType, Type toType, string key)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(fromType, toType, Lifetime.Singleton), key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="func"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton<TFrom>(this IRegistrator registrator, Func<IResolver, object> func)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(typeof(TFrom), Lifetime.Singleton)
|
||||
{
|
||||
ImplementationFactory = func
|
||||
});
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="func"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton<TFrom>(this IRegistrator registrator, Func<IResolver, object> func, string key)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(typeof(TFrom), Lifetime.Singleton)
|
||||
{
|
||||
ImplementationFactory = func
|
||||
}, key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <param name="func"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton(this IRegistrator registrator, Type fromType, Func<IResolver, object> func)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(fromType, Lifetime.Singleton)
|
||||
{
|
||||
ImplementationFactory = func
|
||||
});
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <param name="func"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton(this IRegistrator registrator, Type fromType, Func<IResolver, object> func, string key)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(fromType, Lifetime.Singleton)
|
||||
{
|
||||
ImplementationFactory = func
|
||||
}, key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <typeparam name="TFrom"></typeparam>
|
||||
/// <typeparam name="TTO"></typeparam>
|
||||
/// <param name="registrator"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton<TFrom, TTO>(this IRegistrator registrator)
|
||||
where TFrom : class
|
||||
where TTO : class, TFrom
|
||||
{
|
||||
RegisterSingleton(registrator, typeof(TFrom), typeof(TTO));
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册单例
|
||||
/// </summary>
|
||||
/// <typeparam name="TFrom"></typeparam>
|
||||
/// <typeparam name="TTO"></typeparam>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterSingleton<TFrom, TTO>(this IRegistrator registrator, string key)
|
||||
where TFrom : class
|
||||
where TTO : class, TFrom
|
||||
{
|
||||
RegisterSingleton(registrator, typeof(TFrom), typeof(TTO), key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
#endregion RegisterSingleton
|
||||
|
||||
#region Transient
|
||||
|
||||
/// <summary>
|
||||
/// 注册临时映射
|
||||
/// </summary>
|
||||
/// <typeparam name="TFrom"></typeparam>
|
||||
/// <typeparam name="TTO"></typeparam>
|
||||
/// <param name="registrator"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterTransient<TFrom, TTO>(this IRegistrator registrator)
|
||||
where TFrom : class
|
||||
where TTO : class, TFrom
|
||||
{
|
||||
RegisterTransient(registrator, typeof(TFrom), typeof(TTO));
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册临时映射
|
||||
/// </summary>
|
||||
/// <typeparam name="TFrom"></typeparam>
|
||||
/// <param name="registrator"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterTransient<TFrom>(this IRegistrator registrator)
|
||||
where TFrom : class
|
||||
{
|
||||
RegisterTransient(registrator, typeof(TFrom), typeof(TFrom));
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册临时映射
|
||||
/// </summary>
|
||||
/// <typeparam name="TFrom"></typeparam>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterTransient<TFrom>(this IRegistrator registrator, string key)
|
||||
where TFrom : class
|
||||
{
|
||||
RegisterTransient(registrator, typeof(TFrom), typeof(TFrom), key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册临时映射
|
||||
/// </summary>
|
||||
/// <typeparam name="TFrom"></typeparam>
|
||||
/// <typeparam name="TTO"></typeparam>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterTransient<TFrom, TTO>(this IRegistrator registrator, string key)
|
||||
where TFrom : class
|
||||
where TTO : class, TFrom
|
||||
{
|
||||
RegisterTransient(registrator, typeof(TFrom), typeof(TTO), key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册临时映射
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterTransient(this IRegistrator registrator, Type fromType)
|
||||
{
|
||||
RegisterTransient(registrator, fromType, fromType);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册临时映射
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterTransient(this IRegistrator registrator, Type fromType, string key)
|
||||
{
|
||||
RegisterTransient(registrator, fromType, fromType, key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册临时映射
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <param name="toType"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterTransient(this IRegistrator registrator, Type fromType, Type toType)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(fromType, toType, Lifetime.Transient));
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册临时映射
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <param name="toType"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterTransient(this IRegistrator registrator, Type fromType, Type toType, string key)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(fromType, toType, Lifetime.Transient), key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册临时映射
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="func"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterTransient<TFrom>(this IRegistrator registrator, Func<IResolver, object> func)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(typeof(TFrom), Lifetime.Transient)
|
||||
{
|
||||
ImplementationFactory = func
|
||||
});
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册临时映射
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="func"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterTransient<TFrom>(this IRegistrator registrator, Func<IResolver, object> func, string key)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(typeof(TFrom), Lifetime.Transient)
|
||||
{
|
||||
ImplementationFactory = func
|
||||
}, key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册临时映射
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <param name="func"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterTransient(this IRegistrator registrator, Type fromType, Func<IResolver, object> func)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(fromType, Lifetime.Transient)
|
||||
{
|
||||
ImplementationFactory = func
|
||||
});
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册临时映射
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <param name="func"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator RegisterTransient(this IRegistrator registrator, Type fromType, Func<IResolver, object> func, string key)
|
||||
{
|
||||
registrator.Register(new DependencyDescriptor(fromType, Lifetime.Transient)
|
||||
{
|
||||
ImplementationFactory = func
|
||||
}, key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
#endregion Transient
|
||||
|
||||
#region Unregister
|
||||
|
||||
/// <summary>
|
||||
/// 移除注册信息
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator Unregister(this IRegistrator registrator, Type fromType)
|
||||
{
|
||||
registrator.Unregister(new DependencyDescriptor(fromType));
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除注册信息
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator Unregister(this IRegistrator registrator, Type fromType, string key)
|
||||
{
|
||||
registrator.Unregister(new DependencyDescriptor(fromType), key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除注册信息
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator Unregister<TFrom>(this IRegistrator registrator)
|
||||
{
|
||||
registrator.Unregister(new DependencyDescriptor(typeof(TFrom)));
|
||||
return registrator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除注册信息
|
||||
/// </summary>
|
||||
/// <param name="registrator"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static IRegistrator Unregister<TFrom>(this IRegistrator registrator, string key)
|
||||
{
|
||||
registrator.Unregister(new DependencyDescriptor(typeof(TFrom)), key);
|
||||
return registrator;
|
||||
}
|
||||
|
||||
#endregion Unregister
|
||||
|
||||
#region Resolve
|
||||
|
||||
/// <summary>
|
||||
/// 创建类型对应的实例
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="resolver"></param>
|
||||
/// <returns></returns>
|
||||
public static T Resolve<T>(this IResolver resolver)
|
||||
{
|
||||
return (T)resolver.Resolve(typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建类型对应的实例
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="resolver"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static T Resolve<T>(this IResolver resolver, string key)
|
||||
{
|
||||
return (T)resolver.Resolve(typeof(T), key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建<see cref="Lifetime.Transient"/>生命的未注册的根类型实例。一般适用于:目标类型没有注册,但是其成员类型已经注册的情况。
|
||||
/// </summary>
|
||||
/// <param name="resolver"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public static object ResolveWithoutRoot(this IResolver resolver, Type fromType)
|
||||
{
|
||||
object[] ops = null;
|
||||
var ctor = fromType.GetConstructors().FirstOrDefault(x => x.IsDefined(typeof(DependencyInjectAttribute), true));
|
||||
if (ctor is null)
|
||||
{
|
||||
//如果没有被特性标记,那就取构造函数参数最多的作为注入目标
|
||||
if (fromType.GetConstructors().Length == 0)
|
||||
{
|
||||
throw new Exception($"没有找到类型{fromType.FullName}的公共构造函数。");
|
||||
}
|
||||
ctor = fromType.GetConstructors().OrderByDescending(x => x.GetParameters().Length).First();
|
||||
}
|
||||
DependencyTypeAttribute dependencyTypeAttribute = null;
|
||||
if (fromType.IsDefined(typeof(DependencyTypeAttribute), true))
|
||||
{
|
||||
dependencyTypeAttribute = fromType.GetCustomAttribute<DependencyTypeAttribute>();
|
||||
}
|
||||
|
||||
var parameters = ctor.GetParameters();
|
||||
var ps = new object[parameters.Length];
|
||||
|
||||
if (dependencyTypeAttribute == null || dependencyTypeAttribute.Type.HasFlag(DependencyType.Constructor))
|
||||
{
|
||||
for (var i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
if (ops != null && ops.Length - 1 >= i)
|
||||
{
|
||||
ps[i] = ops[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parameters[i].ParameterType.IsPrimitive || parameters[i].ParameterType == typeof(string))
|
||||
{
|
||||
ps[i] = parameters[i].HasDefaultValue ? parameters[i].DefaultValue : default;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parameters[i].IsDefined(typeof(DependencyInjectAttribute), true))
|
||||
{
|
||||
var attribute = parameters[i].GetCustomAttribute<DependencyInjectAttribute>();
|
||||
var type = attribute.Type ?? parameters[i].ParameterType;
|
||||
ps[i] = resolver.Resolve(type, attribute.Key);
|
||||
}
|
||||
else
|
||||
{
|
||||
ps[i] = resolver.Resolve(parameters[i].ParameterType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ps == null || ps.Length == 0)
|
||||
{
|
||||
return Activator.CreateInstance(fromType);
|
||||
}
|
||||
return Activator.CreateInstance(fromType, ps);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建<see cref="Lifetime.Transient"/>生命的未注册的根类型实例。一般适用于:目标类型没有注册,但是其成员类型已经注册的情况。
|
||||
/// </summary>
|
||||
/// <param name="resolver"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public static T ResolveWithoutRoot<T>(this IResolver resolver)
|
||||
{
|
||||
return (T)ResolveWithoutRoot(resolver, typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试创建类型对应的实例,如果类型没有注册,则会返回null或者默认值类型。
|
||||
/// </summary>
|
||||
/// <param name="resolver"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <returns></returns>
|
||||
public static object TryResolve(this IResolver resolver, Type fromType)
|
||||
{
|
||||
if (resolver.IsRegistered(fromType))
|
||||
{
|
||||
return resolver.Resolve(fromType);
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试创建类型对应的实例,如果类型没有注册,则会返回null或者默认值类型。
|
||||
/// </summary>
|
||||
/// <param name="resolver"></param>
|
||||
/// <param name="fromType"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static object TryResolve(this IResolver resolver, Type fromType, string key)
|
||||
{
|
||||
if (resolver.IsRegistered(fromType))
|
||||
{
|
||||
return resolver.Resolve(fromType, key);
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试创建类型对应的实例,如果类型没有注册,则会返回null或者默认值类型。
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="resolver"></param>
|
||||
/// <returns></returns>
|
||||
public static T TryResolve<T>(this IResolver resolver)
|
||||
{
|
||||
return (T)TryResolve(resolver, typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试创建类型对应的实例,如果类型没有注册,则会返回null或者默认值类型。
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="resolver"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static T TryResolve<T>(this IResolver resolver, string key)
|
||||
{
|
||||
return (T)TryResolve(resolver, typeof(T), key);
|
||||
}
|
||||
|
||||
#endregion Resolve
|
||||
|
||||
#region IsRegistered
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="IRegistered.IsRegistered(Type)"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="registered"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsRegistered<T>(this IRegistered registered)
|
||||
{
|
||||
return registered.IsRegistered(typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="IRegistered.IsRegistered(Type, string)"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="registered"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsRegistered<T>(this IRegistered registered, string key)
|
||||
{
|
||||
return registered.IsRegistered(typeof(T), key);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user