Compare commits
601 Commits
f170a4dd34
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0737299cf | ||
|
|
2db99edcda | ||
| 65186b4f47 | |||
| eb3a5b8991 | |||
| 908d85c648 | |||
| d0f055e066 | |||
| 7f9e6155fe | |||
| 1e3cba6fdf | |||
| daa36d767d | |||
| 3021fd36f6 | |||
| 2c704c1231 | |||
| 2bf2bb2276 | |||
|
|
d2302560f1 | ||
|
|
42c0dc7206 | ||
|
|
82686db38b | ||
|
|
ce5c59dfc2 | ||
|
|
5c3db6886a | ||
|
|
144178a504 | ||
| 6717aa37ab | |||
| bf418e986b | |||
| 9f2a13df6f | |||
| 0cf6d2690a | |||
| afbbac7b81 | |||
| d16a4b6bb4 | |||
| 5567f6731b | |||
| fc297d92fa | |||
| 50a056d110 | |||
| d87f36898b | |||
| 62e43024a6 | |||
| daa3f4d5be | |||
| 10ff9b9745 | |||
| ea2340974a | |||
| fbf9488c55 | |||
| ddbb70081e | |||
| c538a8df8c | |||
| f500d9d974 | |||
| f2808d090f | |||
| 0084e6f758 | |||
| 90ce4e487c | |||
| 1febae72c2 | |||
| 3b825d4ea3 | |||
| a06adfdcdf | |||
| 00e5f6c0e9 | |||
| 1e35692a02 | |||
| a6048238d4 | |||
| 8708f54996 | |||
| 568f5990b2 | |||
|
|
b8751379c5 | ||
|
|
a38447a36f | ||
|
|
fde0398c89 | ||
|
|
ebf79309d1 | ||
|
|
5a3cbe8ecf | ||
|
|
d5a8619b4d | ||
|
|
7689005a14 | ||
|
|
05568b1551 | ||
|
|
e0ca11ffc0 | ||
|
|
f1ab8db710 | ||
|
|
ca08709d99 | ||
|
|
28e415dee1 | ||
|
|
2cedfbe91b | ||
|
|
d4d1d2b69f | ||
|
|
74a625a863 | ||
|
|
07ab7f0c62 | ||
|
|
e74a740abd | ||
|
|
dfa3cd1a58 | ||
|
|
0dd4930f1b | ||
| c95f018413 | |||
| b99ff91841 | |||
| 1c69eb48cd | |||
| ad734f77f9 | |||
| 4c003745ff | |||
| 89de237aff | |||
| a2567791b7 | |||
| 4526ba189a | |||
| f544ea4887 | |||
| 173c4fdbc4 | |||
| babddfff83 | |||
| 56b467ddfc | |||
| 63c97b4dc7 | |||
| e2853b64d1 | |||
| db8c41368d | |||
| 8743325067 | |||
| be96bd0c07 | |||
| b181e1543f | |||
| 7c2a165479 | |||
| 90a12f52bc | |||
| 33f7ced3b2 | |||
| 84cd52cc45 | |||
| 272650d991 | |||
| 7d3d3b5ae9 | |||
| 453a0ccdf0 | |||
| 0809d1215b | |||
| 4972f05fdf | |||
| 886a107c71 | |||
| ce8e563e4e | |||
| 513f8c1ba3 | |||
| 75d0a6f1df | |||
| 003636e243 | |||
| adf2ba00c3 | |||
| e80eb6aa1f | |||
| 70e3fe5dd7 | |||
| 859c03177e | |||
| 244ed3ebe4 | |||
| 048ba35804 | |||
|
|
9aa7673484 | ||
|
|
f01db9c2d7 | ||
| 56cb3e247f | |||
| 0554cbf7bc | |||
|
|
62e36f4459 | ||
|
|
e09d40abc1 | ||
|
|
9b286b023c | ||
|
|
0441f593d4 | ||
|
|
7621d657ac | ||
|
|
e94efc8534 | ||
|
|
90db7a356a | ||
|
|
b6212fec55 | ||
|
|
63efde9e8a | ||
|
|
0a9ba9be38 | ||
|
|
e05f1347f8 | ||
|
|
a0696c5e22 | ||
|
|
01025ff36f | ||
|
|
831f91ce16 | ||
|
|
980e21f27f | ||
|
|
d49aaf61dc | ||
|
|
b95baaef5f | ||
|
|
68d78afafe | ||
|
|
dd679b79b4 | ||
|
|
cc2177e6d1 | ||
|
|
94ff231a71 | ||
|
|
5e2ebd07db | ||
|
|
43e714b061 | ||
|
|
7a7f564f82 | ||
|
|
f7e2bb2434 | ||
|
|
5995b334eb | ||
|
|
1b8dc29595 | ||
|
|
36c2c20eab | ||
|
|
a7df79629d | ||
|
|
89a77019dc | ||
|
|
21c895c22b | ||
|
|
4afeddb7f9 | ||
|
|
14d00653d1 | ||
|
|
87e4c1414e | ||
|
|
fd8e976e1e | ||
|
|
2c393701e4 | ||
|
|
1d50fd8e5b | ||
|
|
701c34a251 | ||
|
|
63f914d188 | ||
|
|
9ea2599553 | ||
|
|
b8995da5ea | ||
|
|
14013bc7b7 | ||
|
|
f586e9eb2f | ||
|
|
ce786a6d42 | ||
|
|
97695fb0b0 | ||
|
|
cb7b69a0a2 | ||
|
|
b38422256c | ||
|
|
9b29a49ad6 | ||
|
|
83ba492b37 | ||
|
|
50c19fea31 | ||
|
|
f93b197d45 | ||
|
|
eae0d9f913 | ||
|
|
55eb250d7e | ||
|
|
e0c1b856ad | ||
|
|
3a1aeb7ac3 | ||
|
|
246184165f | ||
|
|
9d36ced82f | ||
|
|
c81ff2c628 | ||
|
|
653665bb25 | ||
|
|
17edf605e7 | ||
|
|
b41373339e | ||
|
|
fb9449d701 | ||
|
|
72f735272f | ||
|
|
304f5b7b4c | ||
|
|
0238310290 | ||
|
|
3ac0501231 | ||
|
|
db8a560805 | ||
|
|
e67361bfe1 | ||
|
|
91594e80bf | ||
|
|
8d98159ba8 | ||
|
|
f1f5b9e16d | ||
|
|
3955dede16 | ||
|
|
65e834784a | ||
|
|
3c1bbc1151 | ||
|
|
5465fe5b49 | ||
|
|
85787e7054 | ||
|
|
c955220310 | ||
|
|
7d2098092a | ||
|
|
e3b9d2971b | ||
|
|
3a604ede88 | ||
|
|
476c86ff0a | ||
|
|
9376fcff86 | ||
|
|
06df97597e | ||
|
|
266d03e0a1 | ||
|
|
e752c6f6ab | ||
|
|
561a751de4 | ||
|
|
35050d65a8 | ||
|
|
cf9041980d | ||
|
|
cf2ee73ca1 | ||
|
|
52f6dc161e | ||
|
|
7670898e24 | ||
|
|
f5b202c325 | ||
|
|
fffbdf752f | ||
|
|
6916e169b1 | ||
|
|
0c529b199b | ||
|
|
5427a9722d | ||
|
|
bccfae59cd | ||
|
|
4c55ecb427 | ||
|
|
a7e4291e42 | ||
|
|
352b59dfdf | ||
|
|
1b793e2b75 | ||
|
|
72603f836c | ||
|
|
162da9a16c | ||
|
|
c0524cbca2 | ||
|
|
51c1f408d7 | ||
|
|
a034ecdb1b | ||
|
|
f4a9c5c57a | ||
|
|
e15f32ae56 | ||
|
|
44d4bb9c23 | ||
|
|
a0c5144c28 | ||
|
|
dda9b40bd3 | ||
|
|
de89185b43 | ||
|
|
a94c7249e4 | ||
|
|
3f8145e6dc | ||
|
|
f3f65415e1 | ||
|
|
192a93d153 | ||
|
|
9ec9bcd474 | ||
|
|
7dd8271f4a | ||
|
|
b8de148c52 | ||
|
|
0523308083 | ||
|
|
875692b578 | ||
|
|
973a5f1023 | ||
|
|
8498dc0456 | ||
|
|
6a12ad77ec | ||
|
|
144fe86987 | ||
|
|
528a346883 | ||
|
|
a7fb97de4a | ||
|
|
c3dbc1ec54 | ||
|
|
a86989479f | ||
|
|
53427282c5 | ||
|
|
90c85814b0 | ||
|
|
92a7b959ab | ||
|
|
63ab47a288 | ||
|
|
725b186db6 | ||
|
|
ad8d15314f | ||
|
|
f1efbae6a4 | ||
|
|
051567aa0a | ||
|
|
287871ddc6 | ||
|
|
a0ad8d732d | ||
|
|
3ad08e2a86 | ||
|
|
b90a52412c | ||
|
|
39091ff5cf | ||
|
|
22040cf1e7 | ||
|
|
af4b7d5438 | ||
|
|
211064d44e | ||
|
|
66e3c771dd | ||
|
|
97c4f7bf8f | ||
|
|
5981ba7a8d | ||
|
|
21e164ceb7 | ||
|
|
1875bf46fa | ||
|
|
7f9459f6cf | ||
|
|
079f0c69c7 | ||
|
|
d98b3f2867 | ||
|
|
3761c13dba | ||
|
|
8acbbaeb2e | ||
|
|
60e1ec78b3 | ||
|
|
e623575fe8 | ||
|
|
60ae8de550 | ||
|
|
87ad45f42a | ||
|
|
2557525f06 | ||
|
|
7a938f0379 | ||
|
|
9f0facc487 | ||
|
|
608d266d1c | ||
|
|
34e14fd2f5 | ||
|
|
dc45cf2c08 | ||
|
|
09a31b5a3d | ||
|
|
b5cecac745 | ||
|
|
0f4b5430a3 | ||
|
|
7f2d2dadfa | ||
|
|
ac0b6f739b | ||
|
|
d9d61368e3 | ||
|
|
e8c98115b6 | ||
|
|
09dae1b1ac | ||
|
|
9aafc9e467 | ||
|
|
4ce738957d | ||
|
|
5e1bf16b6d | ||
|
|
4f96d271f3 | ||
|
|
14485af448 | ||
|
|
c27e21a702 | ||
|
|
4874079b69 | ||
|
|
15e909064f | ||
|
|
d17c5ca6cd | ||
|
|
592b949f57 | ||
|
|
8850ac4ac9 | ||
|
|
8ccf6f31ae | ||
|
|
9875d023e3 | ||
|
|
62afba7c23 | ||
|
|
1d4882cfbc | ||
|
|
275b9ec858 | ||
|
|
2cf0eb3977 | ||
|
|
4ab5393deb | ||
|
|
a2dc59d5ef | ||
|
|
ed041bf7cb | ||
|
|
c70327e7f4 | ||
|
|
0a3ce89c0d | ||
|
|
389d64c25d | ||
|
|
a3931414e3 | ||
|
|
0dd897625a | ||
|
|
351a6732cf | ||
|
|
5a1808c6a6 | ||
|
|
50c42e9cdd | ||
|
|
ec126be2aa | ||
|
|
9953bbd2ef | ||
|
|
dbecfa92f4 | ||
|
|
e007f15bce | ||
|
|
79dffef528 | ||
|
|
af478e974c | ||
|
|
435c91955c | ||
|
|
4142d2d948 | ||
|
|
06260e0edb | ||
|
|
2d675a16ad | ||
|
|
5469b20e4f | ||
|
|
6f5b4efefb | ||
|
|
b6b12c7702 | ||
|
|
ce716d2bab | ||
|
|
bf672d8b8c | ||
|
|
ed29c9f990 | ||
|
|
66ed34b664 | ||
|
|
d7b4c382cd | ||
|
|
4f6ca3524a | ||
|
|
bd1ae4246d | ||
|
|
d92475c230 | ||
|
|
15705cccc4 | ||
|
|
a8403087f6 | ||
|
|
0235c83075 | ||
|
|
63aeba982f | ||
|
|
514495fc8d | ||
|
|
9752fb14ec | ||
|
|
b3629661a1 | ||
|
|
f38bad8531 | ||
|
|
154478c318 | ||
|
|
155eb563d1 | ||
|
|
4aacc3f650 | ||
|
|
f40c86ed63 | ||
|
|
b32f0df125 | ||
|
|
324a5bdb1e | ||
|
|
e0a6787a87 | ||
|
|
c6a4038eab | ||
|
|
58c8520c08 | ||
|
|
eced1a5afc | ||
|
|
7da93c6719 | ||
|
|
6a92466490 | ||
|
|
5d9d756b91 | ||
|
|
f14aaa75e1 | ||
|
|
249f5a0ae5 | ||
|
|
30177cf0c7 | ||
|
|
68ef0a7537 | ||
|
|
fe2ee78d14 | ||
|
|
53e6f37a09 | ||
|
|
7ec85b4e30 | ||
|
|
a9ebc406f3 | ||
|
|
d013d3edfa | ||
|
|
f267fe955b | ||
|
|
644283cf8f | ||
|
|
82aa8d1143 | ||
|
|
7459f05748 | ||
|
|
36f75d003a | ||
|
|
76ce64691a | ||
|
|
7c03282066 | ||
|
|
7ae95b729f | ||
|
|
9ee8a51664 | ||
|
|
b1d1a898b8 | ||
|
|
4ed3e79565 | ||
|
|
8d9de4502e | ||
|
|
7dd91c73c4 | ||
|
|
988d1e2b16 | ||
|
|
4e0e907313 | ||
|
|
0bfec426d4 | ||
|
|
08ffe821ff | ||
|
|
fa5d0f1b26 | ||
|
|
38bd23d012 | ||
|
|
50e2581727 | ||
|
|
5c09d7775b | ||
|
|
dbfee49dee | ||
|
|
0c6c84852d | ||
|
|
3f61b5064c | ||
|
|
f79d2e2352 | ||
|
|
201da81aa5 | ||
|
|
bea57a25e8 | ||
|
|
0ff89b4906 | ||
|
|
600d17ef40 | ||
|
|
16565eca4d | ||
|
|
8787c04917 | ||
|
|
b3568216a0 | ||
|
|
6f520732dd | ||
|
|
8003cffb9b | ||
|
|
b02f93b38d | ||
|
|
2f0c6a905a | ||
|
|
baf1f5e045 | ||
|
|
b8a4a1f2b5 | ||
|
|
a69f610ef4 | ||
|
|
016d8bdcf2 | ||
|
|
738005f5dc | ||
|
|
c96af25e23 | ||
|
|
35e2fef046 | ||
|
|
b8fb45d4a3 | ||
|
|
fa60147507 | ||
|
|
e9d408a717 | ||
|
|
5fd3fa2fc6 | ||
|
|
0d5bcedc01 | ||
|
|
2e68a37944 | ||
|
|
8076efb934 | ||
|
|
c38f7dcf72 | ||
|
|
6e4942c885 | ||
|
|
d0dfd834b0 | ||
|
|
aa9951f242 | ||
|
|
506685a0b5 | ||
|
|
c9548238bb | ||
|
|
3ffdd49a47 | ||
|
|
609cd29dc5 | ||
|
|
cc3d1f58d3 | ||
|
|
c03f39c1a9 | ||
|
|
750f7bc20c | ||
|
|
65989b23b3 | ||
|
|
c895d2df0e | ||
|
|
0c451cb834 | ||
|
|
9396f48f46 | ||
|
|
1a941b4728 | ||
|
|
c6942164e2 | ||
|
|
343560ed62 | ||
|
|
6873bac8a1 | ||
|
|
09406ca505 | ||
|
|
3aa5ad782f | ||
|
|
5991444efd | ||
|
|
f720ea9cd6 | ||
|
|
a4b96c2f3e | ||
|
|
65c64a3f9a | ||
|
|
1d600aa453 | ||
|
|
816d5835f1 | ||
|
|
4a64a31d47 | ||
|
|
e9b2ba788f | ||
|
|
e53813500a | ||
|
|
25e3855de2 | ||
|
|
dd3d6e70cc | ||
|
|
02a87309df | ||
|
|
0f7bdc9d0e | ||
|
|
f9df2fb29e | ||
|
|
ef7da0e52c | ||
|
|
f602a842be | ||
|
|
52a7664e57 | ||
|
|
ea3d1312b8 | ||
|
|
3b8b315fea | ||
|
|
c65eefb954 | ||
|
|
997fd533ac | ||
|
|
bcfb5a8a70 | ||
|
|
049e9977f4 | ||
|
|
0334fc4cdf | ||
|
|
0c2334cefb | ||
|
|
dd7f1c1ea0 | ||
|
|
4bb242a4cc | ||
|
|
b577067379 | ||
|
|
bd4d4856ea | ||
|
|
c3a12ba5b7 | ||
|
|
478bf13a4a | ||
|
|
d8849f48da | ||
|
|
c466c553dc | ||
|
|
48afa6b433 | ||
|
|
e44b2895c9 | ||
|
|
85e5fc4018 | ||
|
|
70ccec9fef | ||
|
|
f7193594b1 | ||
|
|
9c7319634a | ||
|
|
3becb208ec | ||
|
|
1b00f9afa2 | ||
|
|
b58d4aed2f | ||
|
|
5adc67edf2 | ||
|
|
0ff0de8159 | ||
|
|
49b49271f3 | ||
|
|
5c5a6bd181 | ||
|
|
6ab1777f7c | ||
|
|
103ddf5c2e | ||
|
|
f9c94e8464 | ||
|
|
cdb0009e7c | ||
|
|
5010224500 | ||
|
|
1ebdd7e5bb | ||
|
|
0e0513e640 | ||
|
|
683b95c205 | ||
|
|
f28b43cc06 | ||
|
|
777a8a73ac | ||
|
|
77fc06991b | ||
|
|
eeb50e837d | ||
|
|
1b210714fd | ||
|
|
806bc01c17 | ||
|
|
0169097671 | ||
|
|
90c73237eb | ||
|
|
2a9c9551b8 | ||
|
|
a39728dff5 | ||
|
|
7048f385ef | ||
|
|
cb9c5746b0 | ||
|
|
ed36015d1e | ||
|
|
6ce4a08c53 | ||
|
|
4c379c2d4d | ||
|
|
fee43c00ca | ||
|
|
ee3060158e | ||
|
|
4e615d7e39 | ||
|
|
d1fea581d7 | ||
|
|
26a68cd477 | ||
|
|
eccf2b32ce | ||
|
|
6ff0d0a876 | ||
|
|
0bb779b7b6 | ||
|
|
51ebf3fa67 | ||
|
|
8cc6fd95f7 | ||
|
|
c5b422921b | ||
|
|
7b571e4d86 | ||
|
|
c39b554165 | ||
|
|
489ca67203 | ||
|
|
0804ea1418 | ||
|
|
84dbca97d5 | ||
|
|
8c350db146 | ||
|
|
471dace359 | ||
|
|
a01e6e5b16 | ||
|
|
96d03a5f59 | ||
|
|
993d407a48 | ||
|
|
2c739fbf02 | ||
|
|
dcd54266c0 | ||
|
|
0bf8979a09 | ||
|
|
b6ac303c96 | ||
|
|
406a41b91f | ||
|
|
adfb0daf7d | ||
|
|
a6d554fbc2 | ||
|
|
c6199cc0be | ||
|
|
ed2a591317 | ||
|
|
f6d5305c22 | ||
|
|
a6230419d8 | ||
|
|
b6cd520b72 | ||
|
|
68bfe93cf2 | ||
|
|
e6849cd9c9 | ||
|
|
d59350174c | ||
|
|
5f18ccd2bd | ||
|
|
58d879aec5 | ||
|
|
c9d07ce7bf | ||
|
|
bb39b97d1e | ||
|
|
b91769d931 | ||
|
|
ee5668a5cb | ||
|
|
67a3c598b1 | ||
|
|
ceb8858dc9 | ||
|
|
ed5dd43f37 | ||
|
|
8224b733db | ||
|
|
c1782bf4c3 | ||
|
|
cff310ad59 | ||
|
|
e9c5ae1683 | ||
|
|
09ab518007 | ||
|
|
246c1123fe | ||
|
|
d937383c78 | ||
|
|
d35b638c74 | ||
|
|
605448c0da | ||
|
|
f46a0627ce | ||
|
|
249e13e6a2 | ||
|
|
97f6b6c874 | ||
|
|
deb67a99ce | ||
|
|
3c85969f5a | ||
|
|
7789605585 | ||
|
|
2cb80ec119 | ||
|
|
b0f5738390 | ||
|
|
8f09ec4255 | ||
|
|
ab4d8646d1 | ||
|
|
9f649a11f2 | ||
|
|
9bd377de80 | ||
|
|
52d350ae48 | ||
|
|
f128a719e8 | ||
|
|
c09ff44287 | ||
|
|
d84ef820f1 | ||
|
|
8d38e883df | ||
|
|
ba94f4689a | ||
|
|
5e26545036 | ||
|
|
e554197089 | ||
|
|
b6adf7ed8b | ||
|
|
0ad92e7592 | ||
|
|
b7584a1632 | ||
|
|
cf0689e349 | ||
|
|
316847a11b | ||
|
|
58e86e1405 | ||
|
|
3844f9d8d8 | ||
|
|
0697f5ff58 | ||
|
|
ee045d5bfd | ||
|
|
cb28ce39a1 | ||
|
|
63bcf8a9b9 | ||
|
|
09a2360640 | ||
|
|
4ed0bbc21f | ||
|
|
73ea081f7d | ||
|
|
a01cb0e2a8 | ||
|
|
132183e1d8 | ||
|
|
0e0f78aaa2 | ||
|
|
419974ba12 | ||
|
|
5b21f7f208 | ||
|
|
5c016be71a | ||
|
|
f21944f177 | ||
|
|
401e742ea3 | ||
|
|
5f84f6bcab | ||
|
|
c559662286 | ||
|
|
0138fb5166 | ||
|
|
b71c778a4d | ||
|
|
f7a5d4fc28 |
75
.gitignore
vendored
75
.gitignore
vendored
@@ -1,7 +1,8 @@
|
||||
# ---> VisualStudio
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
@@ -29,7 +30,6 @@ x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
@@ -91,6 +91,7 @@ StyleCopReport.xml
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.tlog
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
@@ -294,6 +295,17 @@ node_modules/
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
|
||||
*.vbp
|
||||
|
||||
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||
*.dsw
|
||||
*.dsp
|
||||
|
||||
# Visual Studio 6 technical files
|
||||
*.ncb
|
||||
*.aps
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
@@ -350,6 +362,9 @@ ASALocalRun/
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# Visual Studio History (VSHistory) files
|
||||
.vshistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
@@ -361,6 +376,42 @@ MigrationBackup/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code files for those working on multiple tools
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Windows Installer files from build outputs
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# JetBrains Rider
|
||||
*.sln.iml
|
||||
|
||||
# ---> VisualStudioCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
/.vs/DigitalData.Core/DesignTimeBuild/.dtbcache.v2
|
||||
/.vs/DigitalData.Core/v17/.suo
|
||||
/.vs/ProjectEvaluation/digitaldata.core.metadata.v6.1
|
||||
@@ -391,3 +442,23 @@ FodyWeavers.xsd
|
||||
/DigitalData.Core.Contracts/obj/Debug/net7.0/DigitalData.Core.Contracts.csproj.FileListAbsolute.txt
|
||||
/DigitalData.Core.Contracts/obj/DigitalData.Core.Contracts.csproj.nuget.dgspec.json
|
||||
/DigitalData.Core.Contracts/obj/project.assets.json
|
||||
/.vs/DigitalData.Core/v17/TestStore/0/000.testlog
|
||||
/DigitalData.Core.Tests/obj/Debug/net7.0/DigitalData.Core.Tests.assets.cache
|
||||
/DigitalData.Core.Tests/obj/DigitalData.Core.Tests.csproj.nuget.dgspec.json
|
||||
/DigitalData.Core.Tests/obj/DigitalData.Core.Tests.csproj.nuget.g.targets
|
||||
/DigitalData.Core.Tests/obj/project.assets.json
|
||||
/.vs/DigitalData.Core/v17/TestStore/0/000.testlog
|
||||
/DigitalData.Core.Tests/obj/Debug/net7.0/DigitalData.Core.Tests.assets.cache
|
||||
/DigitalData.Core.Tests/obj/DigitalData.Core.Tests.csproj.nuget.dgspec.json
|
||||
/DigitalData.Core.Tests/obj/DigitalData.Core.Tests.csproj.nuget.g.targets
|
||||
/DigitalData.Core.Tests/obj/project.assets.json
|
||||
/.vs/DigitalData.Core/v17/TestStore/0/testlog.manifest
|
||||
/DigitalData.Core.Infrastructure/obj
|
||||
/DigitalData.Core.Application/obj/Release/net7.0/DigitalData.Core.Application.AssemblyInfo.cs
|
||||
/DigitalData.Core.Application/obj/Release/net7.0/ref/DigitalData.Core.Application.dll
|
||||
/DigitalData.Core.ConsoleApp/DigitalData.Core.ConsoleApp.csproj
|
||||
/DigitalData.Core.ConsoleApp/Program.cs
|
||||
/DigitalData.Core.ConsoleApp/FooHttpOptions.cs
|
||||
/DigitalData.Core.Tests/obj/
|
||||
/DigitalData.Core.Terminal
|
||||
/DigitalData.Core.Tests.API
|
||||
|
||||
Binary file not shown.
Binary file not shown.
BIN
Assets/core_icon.png
Normal file
BIN
Assets/core_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1020 KiB |
BIN
Assets/core_legacy_icon.png
Normal file
BIN
Assets/core_legacy_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
@@ -1,14 +1,13 @@
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using DigitalData.Core.Contracts.Infrastructure;
|
||||
using DigitalData.Core.Abstraction.Application;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace DigitalData.Core.API
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class BasicCRUDControllerBase<TCRUDService, TCRUDRepository, TDto, TEntity, TId> : CRUDControllerBase<TCRUDService, TCRUDRepository, TDto, TDto, TDto, TEntity, TId>
|
||||
where TCRUDService : ICRUDService<TCRUDRepository, TDto, TDto, TDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class BasicCRUDControllerBase<TCRUDService, TDto, TEntity, TId> : CRUDControllerBase<TCRUDService, TDto, TDto, TDto, TEntity, TId>
|
||||
where TCRUDService : ICRUDService<TDto, TDto, TEntity, TId>
|
||||
where TDto : class
|
||||
where TEntity : class
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using DigitalData.Core.Contracts.Infrastructure;
|
||||
using DigitalData.Core.DTO;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DigitalData.Core.Abstraction.Application;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
|
||||
namespace DigitalData.Core.API
|
||||
{
|
||||
@@ -11,14 +10,13 @@ namespace DigitalData.Core.API
|
||||
/// <typeparam name="TCRUDService">The derived CRUD service type implementing ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId>.</typeparam>
|
||||
/// <typeparam name="TCreateDto">The Data Transfer Object type for create operations.</typeparam>
|
||||
/// <typeparam name="TReadDto">The Data Transfer Object type for read operations.</typeparam>
|
||||
/// <typeparam name="TUpdateDto">The Data Transfer Object type for update operations.</typeparam>
|
||||
/// <typeparam name="TEntity">The entity type CRUD operations will be performed on.</typeparam>
|
||||
/// <typeparam name="TId">The type of the entity's identifier.</typeparam>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class CRUDControllerBase<TCRUDService, TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : ControllerBase
|
||||
where TCRUDService : ICRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class CRUDControllerBase<TCRUDService, TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : ControllerBase
|
||||
where TCRUDService : ICRUDService<TCreateDto, TReadDto, TEntity, TId>
|
||||
where TCreateDto : class
|
||||
where TReadDto : class
|
||||
where TUpdateDto : class
|
||||
@@ -48,10 +46,10 @@ namespace DigitalData.Core.API
|
||||
[HttpPost]
|
||||
public virtual async Task<IActionResult> Create(TCreateDto createDto)
|
||||
{
|
||||
return await _service.CreateAsync(createDto).ThenAsync<TId, IActionResult>(
|
||||
Success: id =>
|
||||
return await _service.CreateAsync(createDto).ThenAsync<TReadDto, IActionResult>(
|
||||
Success: dto =>
|
||||
{
|
||||
var createdResource = new { Id = id };
|
||||
var createdResource = new { Id = dto.GetId() };
|
||||
var actionName = nameof(GetById);
|
||||
var routeValues = new { id = createdResource.Id };
|
||||
return CreatedAtAction(actionName, routeValues, createdResource);
|
||||
|
||||
172
DigitalData.Core.API/CRUDControllerBaseWithErrorHandling.cs
Normal file
172
DigitalData.Core.API/CRUDControllerBaseWithErrorHandling.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DigitalData.Core.Abstraction.Application;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
|
||||
namespace DigitalData.Core.API
|
||||
{
|
||||
/// <summary>
|
||||
/// A base controller class that provides generic CRUD (Create, Read, Update, Delete) operations for a specified entity type,
|
||||
/// with enhanced error handling to ensure robust and reliable API endpoints.
|
||||
/// </summary>
|
||||
/// <typeparam name="TCRUDService">The derived CRUD service type implementing ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId>.</typeparam>
|
||||
/// <typeparam name="TCreateDto">The Data Transfer Object type for create operations.</typeparam>
|
||||
/// <typeparam name="TReadDto">The Data Transfer Object type for read operations.</typeparam>
|
||||
/// <typeparam name="TEntity">The entity type CRUD operations will be performed on.</typeparam>
|
||||
/// <typeparam name="TId">The type of the entity's identifier.</typeparam>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
[Obsolete("Use MediatR")]
|
||||
public class CRUDControllerBaseWithErrorHandling<TCRUDService, TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : ControllerBase
|
||||
where TCRUDService : ICRUDService<TCreateDto, TReadDto, TEntity, TId>
|
||||
where TCreateDto : class
|
||||
where TReadDto : class
|
||||
where TUpdateDto : class
|
||||
where TEntity : class
|
||||
{
|
||||
protected readonly ILogger _logger;
|
||||
protected readonly TCRUDService _service;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CRUDControllerBase class with specified logger and CRUD service.
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger to be used by the controller.</param>
|
||||
/// <param name="service">The CRUD service handling business logic for the entity.</param>
|
||||
public CRUDControllerBaseWithErrorHandling(
|
||||
ILogger logger,
|
||||
TCRUDService service)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_service = service ?? throw new ArgumentNullException(nameof(service));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new entity based on the provided DTO.
|
||||
/// </summary>
|
||||
/// <param name="createDto">The DTO from which to create the entity.</param>
|
||||
/// <returns>A task that represents the asynchronous create operation. The task result contains the action result.</returns>
|
||||
[HttpPost]
|
||||
public virtual async Task<IActionResult> Create(TCreateDto createDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _service.CreateAsync(createDto).ThenAsync<TReadDto, IActionResult>(
|
||||
Success: dto =>
|
||||
{
|
||||
var createdResource = new { Id = dto.GetId() };
|
||||
var actionName = nameof(GetById);
|
||||
var routeValues = new { id = createdResource.Id };
|
||||
return CreatedAtAction(actionName, routeValues, createdResource);
|
||||
},
|
||||
Fail: (messages, notices) =>
|
||||
{
|
||||
_logger.LogNotice(notices);
|
||||
return BadRequest(messages);
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "{Message}", ex.Message);
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves an entity by its identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to retrieve.</param>
|
||||
/// <returns>A task that represents the asynchronous read operation. The task result contains the action result.</returns>
|
||||
[HttpGet("{id}")]
|
||||
public virtual async Task<IActionResult> GetById([FromRoute] TId id)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _service.ReadByIdAsync(id).ThenAsync(
|
||||
Success: Ok,
|
||||
Fail: IActionResult (messages, notices) =>
|
||||
{
|
||||
_logger.LogNotice(notices);
|
||||
return NotFound(messages);
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "{Message}", ex.Message);
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves all entities.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous read-all operation. The task result contains the action result.</returns>
|
||||
[HttpGet]
|
||||
public virtual async Task<IActionResult> GetAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _service.ReadAllAsync().ThenAsync(
|
||||
Success: Ok,
|
||||
Fail: IActionResult (messages, notices) =>
|
||||
{
|
||||
_logger.LogNotice(notices);
|
||||
return NotFound(messages);
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "{Message}", ex.Message);
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates an existing entity based on the provided DTO.
|
||||
/// </summary>
|
||||
/// <param name="updateDto">The DTO containing the updated data for the entity.</param>
|
||||
/// <returns>A task that represents the asynchronous update operation. The task result contains the action result.</returns>
|
||||
[HttpPut]
|
||||
public virtual async Task<IActionResult> Update(TUpdateDto updateDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _service.UpdateAsync(updateDto).ThenAsync(
|
||||
Success: Ok,
|
||||
Fail: IActionResult (messages, notices) =>
|
||||
{
|
||||
_logger.LogNotice(notices);
|
||||
return BadRequest(messages);
|
||||
});
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "{Message}", ex.Message);
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes an entity by its identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to delete.</param>
|
||||
/// <returns>A task that represents the asynchronous delete operation. The task result contains the action result.</returns>
|
||||
[HttpDelete("{id}")]
|
||||
public virtual async Task<IActionResult> Delete([FromRoute] TId id)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _service.DeleteAsyncById(id).ThenAsync(
|
||||
Success: Ok,
|
||||
Fail: IActionResult (messages, notices) =>
|
||||
{
|
||||
_logger.LogNotice(notices);
|
||||
return BadRequest(messages);
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "{Message}", ex.Message);
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
DigitalData.Core.API/CSPMiddleware.cs
Normal file
46
DigitalData.Core.API/CSPMiddleware.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
namespace DigitalData.Core.API;
|
||||
|
||||
/// <summary>
|
||||
/// Middleware to add Content Security Policy (CSP) headers to the HTTP response.
|
||||
/// </summary>
|
||||
public class CSPMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly string _policy;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CSPMiddleware"/> class.
|
||||
/// </summary>
|
||||
/// <param name="next">The next middleware in the request pipeline.</param>
|
||||
/// <param name="policy">The CSP policy string with placeholders for nonces.</param>
|
||||
public CSPMiddleware(RequestDelegate next, string policy)
|
||||
{
|
||||
_next = next;
|
||||
_policy = policy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the middleware to add the CSP header to the response.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP context.</param>
|
||||
/// <returns>A task that represents the completion of request processing.</returns>
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
// Generate a nonce (number used once) for inline scripts and styles
|
||||
var nonce = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
|
||||
|
||||
// Store the nonce in the context items for later use
|
||||
context.Items["csp-nonce"] = nonce;
|
||||
|
||||
// Add the CSP header to the response
|
||||
context.Response.OnStarting(() =>
|
||||
{
|
||||
context.Response.Headers.Append("Content-Security-Policy",
|
||||
string.Format(_policy, nonce));
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
|
||||
// Call the next middleware in the pipeline
|
||||
await _next(context);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using DigitalData.Core.DTO;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Text;
|
||||
|
||||
@@ -20,7 +19,7 @@ namespace DigitalData.Core.API
|
||||
/// <param name="index">The key in the ViewData dictionary where the value will be stored.</param>
|
||||
/// <param name="value">The value to be stored in the ViewData dictionary.</param>
|
||||
/// <returns>The same ViewResult object with updated ViewData, allowing for additional chained operations.</returns>
|
||||
public static ViewResult WithData(this ViewResult viewResult, string index, object value)
|
||||
public static ViewResult WithData(this ViewResult viewResult, string index, object? value)
|
||||
{
|
||||
viewResult.ViewData[index] = value;
|
||||
return viewResult;
|
||||
@@ -34,15 +33,13 @@ namespace DigitalData.Core.API
|
||||
/// <param name="message">Optional. A custom error message to include in the response.</param>
|
||||
/// /// <param name="messageKey">Optional. A custom error message key to include in the response.</param>
|
||||
/// <returns>An ObjectResult representing an internal server error (status code 500).</returns>
|
||||
public static ObjectResult InnerServiceError(this ControllerBase controllerBase, Exception? ex = null, string? message = null, Enum? messageKey = null)
|
||||
public static ObjectResult InnerServiceError(this ControllerBase controllerBase, Exception? ex = null, string? message = null)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
if (ex is not null)
|
||||
sb.AppendLine(ex.Message);
|
||||
if (message is not null)
|
||||
sb.AppendLine(message);
|
||||
if (messageKey is not null)
|
||||
sb.AppendLine(messageKey.ToString());
|
||||
|
||||
return controllerBase.StatusCode(500, sb.Length > 0 ? sb.ToString() : null);
|
||||
}
|
||||
|
||||
65
DigitalData.Core.API/DIExtensions.cs
Normal file
65
DigitalData.Core.API/DIExtensions.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
namespace DigitalData.Core.API;
|
||||
|
||||
/// <summary>
|
||||
/// Provides extension methods for adding middleware to the application's request pipeline.
|
||||
/// </summary>
|
||||
public static class DIExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <see cref="CSPMiddleware"/> to the application's request pipeline to include
|
||||
/// Content Security Policy (CSP) headers in the HTTP response.
|
||||
/// </summary>
|
||||
/// <param name="app">The application builder.</param>
|
||||
/// <param name="policy">
|
||||
/// The CSP policy string with placeholders. The first format parameter {0} will be replaced
|
||||
/// by the nonce value.
|
||||
/// </param>
|
||||
/// <returns>The application builder with the CSP middleware added.</returns>
|
||||
public static IApplicationBuilder UseCSPMiddleware(this IApplicationBuilder app, string policy)
|
||||
=> app.UseMiddleware<CSPMiddleware>(policy);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the DiP (Development in Production) mode is enabled for the WebApplicationBuilder.
|
||||
/// </summary>
|
||||
/// <param name="builder">The WebApplicationBuilder instance.</param>
|
||||
/// <returns>True if DiP mode is enabled; otherwise, false.</returns>
|
||||
public static bool IsDiP(this WebApplicationBuilder builder) => builder.Configuration.GetValue<bool>("DiPMode");
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the DiP (Development in Production) mode is enabled for the WebApplication.
|
||||
/// </summary>
|
||||
/// <param name="app">The WebApplication instance.</param>
|
||||
/// <returns>True if DiP mode is enabled; otherwise, false.</returns>
|
||||
public static bool IsDiP(this WebApplication app) => app.Configuration.GetValue<bool>("DiPMode");
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the environment is Development or DiP (Development in Production) mode is enabled for the WebApplicationBuilder.
|
||||
/// </summary>
|
||||
/// <param name="builder">The WebApplicationBuilder instance.</param>
|
||||
/// <returns>True if the environment is Development or DiP mode is enabled; otherwise, false.</returns>
|
||||
public static bool IsDevOrDiP(this WebApplicationBuilder builder) => builder.Environment.IsDevelopment() || builder.IsDiP();
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the environment is Development or DiP (Development in Production) mode is enabled for the WebApplication.
|
||||
/// </summary>
|
||||
/// <param name="app">The WebApplication instance.</param>
|
||||
/// <returns>True if the environment is Development or DiP mode is enabled; otherwise, false.</returns>
|
||||
public static bool IsDevOrDiP(this WebApplication app) => app.Environment.IsDevelopment() || app.IsDiP();
|
||||
|
||||
/// <summary>
|
||||
/// Configures the services with options from the specified section of the appsettings.json file.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The options class type. Must be a reference type.</typeparam>
|
||||
/// <param name="builder">The WebApplicationBuilder instance.</param>
|
||||
/// <returns>The WebApplicationBuilder instance for chaining.</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the section is not found in the configuration.</exception>
|
||||
public static WebApplicationBuilder ConfigureBySection<T>(this WebApplicationBuilder builder) where T : class
|
||||
{
|
||||
var section = builder.Configuration.GetSection(typeof(T).Name);
|
||||
if (!section.Exists())
|
||||
throw new InvalidOperationException($"Section '{typeof(T).Name}' not found in appsettings.");
|
||||
|
||||
builder.Services.Configure<T>(section);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,47 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<IsPackable>true</IsPackable>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<OutputType>Library</OutputType>
|
||||
<Description>This package provides a comprehensive set of API controllers and related utilities for the DigitalData.Core library. It includes generic CRUD controllers, localization extensions, middleware for security policies, and application model conventions.</Description>
|
||||
<PackageId>DigitalData.Core.API</PackageId>
|
||||
<Version>2.2.1</Version>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>DigitalData.Core.API</Product>
|
||||
<Copyright>Copyright 2024</Copyright>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
|
||||
<PackageTags>digital data core api</PackageTags>
|
||||
<PackageIcon>core_icon.png</PackageIcon>
|
||||
<AssemblyVersion>2.2.1</AssemblyVersion>
|
||||
<FileVersion>2.2.1</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\..\nuget-package-icons\core_icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DigitalData.Core.Contracts\DigitalData.Core.Contracts.csproj" />
|
||||
<ProjectReference Include="..\DigitalData.Core.DTO\DigitalData.Core.DTO.csproj" />
|
||||
<ProjectReference Include="..\DigitalData.Core.Application\DigitalData.Core.Application.csproj" />
|
||||
<ProjectReference Include="..\DigitalData.Core.Exceptions\DigitalData.Core.Exceptions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Assets\icon.png">
|
||||
<PackagePath>\</PackagePath>
|
||||
<Pack>True</Pack>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.AspNetCore.Localization;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using System.Dynamic;
|
||||
using System.Globalization;
|
||||
|
||||
namespace DigitalData.Core.API
|
||||
@@ -55,5 +56,27 @@ namespace DigitalData.Core.API
|
||||
app.UseRequestLocalization(options);
|
||||
return app;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts all localized strings to a dictionary.
|
||||
/// </summary>
|
||||
/// <param name="localizer">The <see cref="IStringLocalizer"/> instance containing the localized strings.</param>
|
||||
/// <returns>A dictionary containing all localized strings, where the key is the name of the string and the value is the localized value.</returns>
|
||||
public static Dictionary<string, string> ToDictionary(this IStringLocalizer localizer) => localizer.GetAllStrings().ToDictionary(ls => ls.Name, ls => ls.Value);
|
||||
|
||||
/// <summary>
|
||||
/// Converts the localized strings from an <see cref="IStringLocalizer"/> to a dynamic object.
|
||||
/// </summary>
|
||||
/// <param name="localizer">The string localizer to get localized strings from.</param>
|
||||
/// <returns>A dynamic object containing all localized strings.</returns>
|
||||
public static dynamic ToDynamic(this IStringLocalizer localizer)
|
||||
{
|
||||
var expando = new ExpandoObject() as IDictionary<string, object>;
|
||||
foreach (var localizedString in localizer.GetAllStrings())
|
||||
{
|
||||
expando[localizedString.Name] = localizedString.Value;
|
||||
}
|
||||
return expando;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"profiles": {
|
||||
"DigitalData.Core.API": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:59445;http://localhost:59446"
|
||||
}
|
||||
}
|
||||
{
|
||||
"profiles": {
|
||||
"DigitalData.Core.API": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:50245;http://localhost:50246"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using DigitalData.Core.Contracts.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DigitalData.Core.Abstraction.Application;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
|
||||
namespace DigitalData.Core.API
|
||||
{
|
||||
@@ -12,14 +12,14 @@ namespace DigitalData.Core.API
|
||||
/// <typeparam name="TId">The type of the entity's identifier.</typeparam>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class ReadControllerBase<TBasicCRUDService, TCRUDRepository, TReadDto, TEntity, TId> : ControllerBase
|
||||
where TBasicCRUDService : IBasicCRUDService<TCRUDRepository, TReadDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class ReadControllerBase<TReadService, TReadDto, TEntity, TId> : ControllerBase
|
||||
where TReadService : IReadService<TReadDto, TEntity, TId>
|
||||
where TReadDto : class
|
||||
where TEntity : class
|
||||
{
|
||||
protected readonly ILogger _logger;
|
||||
protected readonly TBasicCRUDService _service;
|
||||
protected readonly TReadService _service;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CRUDControllerBase class with specified logger and CRUD service.
|
||||
@@ -28,7 +28,7 @@ namespace DigitalData.Core.API
|
||||
/// <param name="service">The CRUD service handling business logic for the entity.</param>
|
||||
public ReadControllerBase(
|
||||
ILogger logger,
|
||||
TBasicCRUDService service)
|
||||
TReadService service)
|
||||
{
|
||||
_logger = logger;
|
||||
_service = service;
|
||||
@@ -42,12 +42,13 @@ namespace DigitalData.Core.API
|
||||
[HttpGet("{id}")]
|
||||
public virtual async Task<IActionResult> GetById([FromRoute] TId id)
|
||||
{
|
||||
var result = await _service.ReadByIdAsync(id);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
return Ok(result);
|
||||
}
|
||||
return NotFound(result);
|
||||
return await _service.ReadByIdAsync(id).ThenAsync(
|
||||
Success: Ok,
|
||||
Fail: IActionResult (messages, notices) =>
|
||||
{
|
||||
_logger.LogNotice(notices);
|
||||
return NotFound(messages);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -57,12 +58,13 @@ namespace DigitalData.Core.API
|
||||
[HttpGet]
|
||||
public virtual async Task<IActionResult> GetAll()
|
||||
{
|
||||
var result = await _service.ReadAllAsync();
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
return Ok(result);
|
||||
}
|
||||
return NotFound(result);
|
||||
return await _service.ReadAllAsync().ThenAsync(
|
||||
Success: Ok,
|
||||
Fail: IActionResult (messages, notices) =>
|
||||
{
|
||||
_logger.LogNotice(notices);
|
||||
return NotFound(messages);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
87
DigitalData.Core.API/ReadControllerBaseWithErrorHandling.cs
Normal file
87
DigitalData.Core.API/ReadControllerBaseWithErrorHandling.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using DigitalData.Core.Abstraction.Application;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace DigitalData.Core.API
|
||||
{
|
||||
/// <summary>
|
||||
/// A base controller class providing Read operation for a specified entity type,
|
||||
/// with enhanced error handling to ensure robust and reliable API endpoints.
|
||||
/// </summary>
|
||||
/// <typeparam name="TReadDto">The Data Transfer Object type for read operations.</typeparam>
|
||||
/// <typeparam name="TEntity">The entity type CRUD operations will be performed on.</typeparam>
|
||||
/// <typeparam name="TId">The type of the entity's identifier.</typeparam>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
[Obsolete("Use MediatR")]
|
||||
public class ReadControllerBaseWithErrorHandling<TReadService, TReadDto, TEntity, TId> : ControllerBase
|
||||
where TReadService : IReadService<TReadDto, TEntity, TId>
|
||||
where TReadDto : class
|
||||
where TEntity : class
|
||||
{
|
||||
protected readonly ILogger _logger;
|
||||
protected readonly TReadService _service;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CRUDControllerBase class with specified logger and CRUD service.
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger to be used by the controller.</param>
|
||||
/// <param name="service">The CRUD service handling business logic for the entity.</param>
|
||||
public ReadControllerBaseWithErrorHandling(
|
||||
ILogger logger,
|
||||
TReadService service)
|
||||
{
|
||||
_logger = logger;
|
||||
_service = service;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves an entity by its identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to retrieve.</param>
|
||||
/// <returns>A task that represents the asynchronous read operation. The task result contains the action result.</returns>
|
||||
[HttpGet("{id}")]
|
||||
public virtual async Task<IActionResult> GetById([FromRoute] TId id)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _service.ReadByIdAsync(id).ThenAsync(
|
||||
Success: Ok,
|
||||
Fail: IActionResult (messages, notices) =>
|
||||
{
|
||||
_logger.LogNotice(notices);
|
||||
return NotFound(messages);
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "{Message}", ex.Message);
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves all entities.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous read-all operation. The task result contains the action result.</returns>
|
||||
[HttpGet]
|
||||
public virtual async Task<IActionResult> GetAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _service.ReadAllAsync().ThenAsync(
|
||||
Success: Ok,
|
||||
Fail: IActionResult (messages, notices) =>
|
||||
{
|
||||
_logger.LogNotice(notices);
|
||||
return NotFound(messages);
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "{Message}", ex.Message);
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
DigitalData.Core.Abstraction.Application/DTO/BaseDto.cs
Normal file
19
DigitalData.Core.Abstraction.Application/DTO/BaseDto.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
#if NET
|
||||
namespace DigitalData.Core.Abstraction.Application.DTO;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a base Data Transfer Object (DTO) with an identifier.
|
||||
/// </summary>
|
||||
/// <typeparam name="TId">The type of the identifier.</typeparam>
|
||||
/// <param name="Id">The identifier of the DTO.</param>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public record BaseDTO<TId>(TId Id) where TId : notnull
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance, based on the identifier.
|
||||
/// This override ensures that the hash code is derived consistently from the identifier.
|
||||
/// </summary>
|
||||
/// <returns>A hash code for the current object, derived from the identifier.</returns>
|
||||
public override int GetHashCode() => Id.GetHashCode();
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
#if NET
|
||||
namespace DigitalData.Core.Abstraction.Application.DTO;
|
||||
|
||||
/// <summary>
|
||||
/// Represents settings related to user cookie consent dialogs. Designed to be serialized into JSON format for use with JavaScript frontend libraries,
|
||||
/// such as the bootstrap-cookie-consent-settings at the GitHub repository: https://github.com/shaack/bootstrap-cookie-consent-settings
|
||||
/// </summary>
|
||||
public class CookieConsentSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// URL to the privacy policy page.
|
||||
/// </summary>
|
||||
public string? PrivacyPolicyUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// URL to the legal notice page.
|
||||
/// </summary>
|
||||
public string? LegalNoticeUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// URL to the content of the dialog box.
|
||||
/// </summary>
|
||||
public string? ContentURL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// CSS class for the 'Agree' button.
|
||||
/// </summary>
|
||||
public string? ButtonAgreeClass { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// CSS class for the 'Don't Agree' button.
|
||||
/// </summary>
|
||||
public string? ButtonDontAgreeClass { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// CSS class for the 'Save' button.
|
||||
/// </summary>
|
||||
public string? ButtonSaveClass { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Language in which the modal is displayed.
|
||||
/// </summary>
|
||||
public string? Lang { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Default language for the modal if the user's browser language is not supported.
|
||||
/// </summary>
|
||||
public string? DefaultLang { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of the cookie used to store the consent status.
|
||||
/// </summary>
|
||||
public string? CookieName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of days the cookie will be stored.
|
||||
/// </summary>
|
||||
public int CookieStorageDays { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for the modal dialog element.
|
||||
/// </summary>
|
||||
public string? ModalId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether to also store the settings in the browser's localStorage.
|
||||
/// </summary>
|
||||
public bool AlsoUseLocalStorage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// List of categories for cookie consent.
|
||||
/// </summary>
|
||||
public List<string>? Categories { get; set; }
|
||||
}
|
||||
#endif
|
||||
36
DigitalData.Core.Abstraction.Application/DTO/DIExtensions.cs
Normal file
36
DigitalData.Core.Abstraction.Application/DTO/DIExtensions.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
#if NET
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Configuration;
|
||||
|
||||
namespace DigitalData.Core.Abstraction.Application.DTO;
|
||||
|
||||
/// <summary>
|
||||
/// Provides extension methods for dependency injection.
|
||||
/// </summary>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static class DIExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <see cref="CookieConsentSettings"/> to the service collection.
|
||||
/// </summary>
|
||||
/// <param name="services">The service collection to add the settings to.</param>
|
||||
/// <returns>The updated service collection.</returns>
|
||||
/// <exception cref="ConfigurationErrorsException">
|
||||
/// Thrown if the 'CookieConsentSettings' section is missing or improperly configured in appsettings.json.
|
||||
/// </exception>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static IServiceCollection AddCookieConsentSettings(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton(sp =>
|
||||
{
|
||||
var configuration = sp.GetRequiredService<IConfiguration>();
|
||||
var settings = configuration.GetSection("CookieConsentSettings").Get<CookieConsentSettings>();
|
||||
return settings is null
|
||||
? throw new ConfigurationErrorsException("The 'CookieConsentSettings' section is missing or improperly configured in appsettings.json.")
|
||||
: settings;
|
||||
});
|
||||
return services;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
395
DigitalData.Core.Abstraction.Application/DTO/DTOExtensions.cs
Normal file
395
DigitalData.Core.Abstraction.Application/DTO/DTOExtensions.cs
Normal file
@@ -0,0 +1,395 @@
|
||||
#if NET
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Text;
|
||||
|
||||
namespace DigitalData.Core.Abstraction.Application.DTO;
|
||||
|
||||
/// <summary>
|
||||
/// Provides extension methods for data transfer objects (DTOs).
|
||||
/// </summary>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static class DTOExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a single message to the result, if not null.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the result.</typeparam>
|
||||
/// <param name="result">The result to add the message to.</param>
|
||||
/// <param name="message">The message to add.</param>
|
||||
/// <returns>The updated result.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static T Message<T>(this T result, string? message) where T : Result
|
||||
{
|
||||
if (message is not null)
|
||||
result.Messages.Add(message);
|
||||
return result;
|
||||
}
|
||||
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
internal static IEnumerable<T> FilterNull<T>(this IEnumerable<T?> list)
|
||||
{
|
||||
foreach (var item in list)
|
||||
if (item is not null)
|
||||
yield return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds multiple messages to the result, after removing nulls.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the result.</typeparam>
|
||||
/// <param name="result">The result to add the messages to.</param>
|
||||
/// <param name="messages">The messages to add.</param>
|
||||
/// <returns>The updated result.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static T Message<T>(this T result, params string?[] messages) where T : Result
|
||||
{
|
||||
result.Messages.AddRange(messages.FilterNull());
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a collection of messages to the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the result.</typeparam>
|
||||
/// <param name="result">The result to add the messages to.</param>
|
||||
/// <param name="messages">The collection of messages to add.</param>
|
||||
/// <returns>The updated result.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static T Message<T>(this T result, IEnumerable<string?> messages) where T : Result
|
||||
{
|
||||
result.Messages.AddRange(messages.FilterNull());
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a notice to the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the result.</typeparam>
|
||||
/// <param name="result">The result to add the notice to.</param>
|
||||
/// <param name="notice">The notice to add.</param>
|
||||
/// <returns>The updated result.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static T Notice<T>(this T result, Notice notice) where T : Result
|
||||
{
|
||||
result.Notices.Add(notice);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a collection of notices to the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the result.</typeparam>
|
||||
/// <param name="result">The result to add the notices to.</param>
|
||||
/// <param name="notices">The collection of notices to add.</param>
|
||||
/// <returns>The updated result.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static T Notice<T>(this T result, IEnumerable<Notice> notices) where T : Result
|
||||
{
|
||||
result.Notices.AddRange(notices);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds notices with a specific log level and flags to the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the result.</typeparam>
|
||||
/// <param name="result">The result to add the notices to.</param>
|
||||
/// <param name="level">The log level of the notices.</param>
|
||||
/// <param name="flags">The flags associated with the notices.</param>
|
||||
/// <returns>The updated result.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static T Notice<T>(this T result, LogLevel level, params Enum[] flags) where T : Result
|
||||
{
|
||||
var notices = flags.Select(flag => new Notice()
|
||||
{
|
||||
Flag = flag,
|
||||
Level = level
|
||||
});
|
||||
result.Notices.AddRange(notices);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a notice with a specific log level, flag, and messages to the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the result.</typeparam>
|
||||
/// <param name="result">The result to add the notice to.</param>
|
||||
/// <param name="level">The log level of the notice.</param>
|
||||
/// <param name="flag">The flag associated with the notice.</param>
|
||||
/// <param name="messages">The messages to add to the notice.</param>
|
||||
/// <returns>The updated result.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static T Notice<T>(this T result, LogLevel level, Enum flag, params string?[] messages) where T : Result
|
||||
{
|
||||
result.Notices.Add(new Notice()
|
||||
{
|
||||
Flag = flag,
|
||||
Level = level,
|
||||
Messages = messages.FilterNull().ToList()
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a notice with a specific log level and messages to the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the result.</typeparam>
|
||||
/// <param name="result">The result to add the notice to.</param>
|
||||
/// <param name="level">The log level of the notice.</param>
|
||||
/// <param name="messages">The messages to add to the notice.</param>
|
||||
/// <returns>The updated result.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static T Notice<T>(this T result, LogLevel level, params string[] messages) where T : Result
|
||||
{
|
||||
result.Notices.Add(new Notice()
|
||||
{
|
||||
Flag = null,
|
||||
Level = level,
|
||||
Messages = messages.FilterNull().ToList()
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if any notice has the specified flag.
|
||||
/// </summary>
|
||||
/// <param name="notices">The collection of notices to check.</param>
|
||||
/// <param name="flag">The flag to check for.</param>
|
||||
/// <returns>True if any notice has the specified flag; otherwise, false.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static bool HasFlag(this IEnumerable<Notice> notices, Enum flag) => notices.Any(n => n.Flag?.ToString() == flag.ToString());
|
||||
|
||||
/// <summary>
|
||||
/// Checks if any notice has any of the specified flags.
|
||||
/// </summary>
|
||||
/// <param name="notices">The collection of notices to check.</param>
|
||||
/// <param name="flags">The flags to check for.</param>
|
||||
/// <returns>True if any notice has any of the specified flags; otherwise, false.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static bool HasAnyFlag(this IEnumerable<Notice> notices, params Enum[] flags) => flags.Any(f => notices.HasFlag(f));
|
||||
|
||||
/// <summary>
|
||||
/// Executes a function based on the success or failure of the task result,
|
||||
/// without using result data.
|
||||
/// </summary>
|
||||
/// <typeparam name="I">The type of the return value.</typeparam>
|
||||
/// <param name="tResult">The task returning a result to evaluate.</param>
|
||||
/// <param name="Success">The function to execute if the result is successful.</param>
|
||||
/// <param name="Fail">The function to execute if the result is a failure.</param>
|
||||
/// <returns>The result of the executed function.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static I? Then<I>(this Result result, Func<I> Success)
|
||||
{
|
||||
return result.IsSuccess ? Success() : default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a function based on the success or failure of the task result,
|
||||
/// using the data in the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data in the result.</typeparam>
|
||||
/// <typeparam name="I">The type of the return value.</typeparam>
|
||||
/// <param name="tResult">The task returning a data result to evaluate.</param>
|
||||
/// <param name="Success">The function to execute if the data result is successful.</param>
|
||||
/// <param name="Fail">The function to execute if the data result is a failure.</param>
|
||||
/// <returns>The result of the executed function.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static async Task<I?> ThenAsync<I>(this Result result, Func<Task<I>> SuccessAsync)
|
||||
{
|
||||
return result.IsSuccess ? await SuccessAsync() : default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a function based on the success or failure of the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="I">The type of the return value.</typeparam>
|
||||
/// <param name="result">The result to evaluate.</param>
|
||||
/// <param name="Success">The function to execute if the result is successful.</param>
|
||||
/// <param name="Fail">The function to execute if the result is a failure.</param>
|
||||
/// <returns>The result of the executed function.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static I Then<I>(this Result result, Func<I> Success, Func<List<string>, List<Notice>, I> Fail)
|
||||
{
|
||||
return result.IsSuccess ? Success() : Fail(result.Messages, result.Notices);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously executes a function based on the success or failure of the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="I">The type of the return value.</typeparam>
|
||||
/// <param name="result">The result to evaluate.</param>
|
||||
/// <param name="SuccessAsync">The asynchronous function to execute if the result is successful.</param>
|
||||
/// <param name="Fail">The function to execute if the result is a failure.</param>
|
||||
/// <returns>The result of the executed function.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static async Task<I> ThenAsync<I>(this Result result, Func<Task<I>> SuccessAsync, Func<List<string>, List<Notice>, I> Fail)
|
||||
{
|
||||
return result.IsSuccess ? await SuccessAsync() : Fail(result.Messages, result.Notices);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a function based on the success or failure of the data result.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data in the result.</typeparam>
|
||||
/// <typeparam name="I">The type of the return value.</typeparam>
|
||||
/// <param name="result">The data result to evaluate.</param>
|
||||
/// <param name="Success">The function to execute if the data result is successful.</param>
|
||||
/// <param name="Fail">The function to execute if the data result is a failure.</param>
|
||||
/// <returns>The result of the executed function.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static I Then<T, I>(this DataResult<T> result, Func<T, I> Success, Func<List<string>, List<Notice>, I> Fail)
|
||||
{
|
||||
return result.IsSuccess ? Success(result.Data) : Fail(result.Messages, result.Notices);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously executes a function based on the success or failure of the data result.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data in the result.</typeparam>
|
||||
/// <typeparam name="I">The type of the return value.</typeparam>
|
||||
/// <param name="result">The data result to evaluate.</param>
|
||||
/// <param name="SuccessAsync">The asynchronous function to execute if the data result is successful.</param>
|
||||
/// <param name="Fail">The function to execute if the data result is a failure.</param>
|
||||
/// <returns>The result of the executed function.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static async Task<I> ThenAsync<T, I>(this DataResult<T> result, Func<T, Task<I>> SuccessAsync, Func<List<string>, List<Notice>, I> Fail)
|
||||
{
|
||||
return result.IsSuccess ? await SuccessAsync(result.Data) : Fail(result.Messages, result.Notices);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously executes a function based on the success or failure of a task returning a result.
|
||||
/// </summary>
|
||||
/// <typeparam name="I">The type of the return value.</typeparam>
|
||||
/// <param name="tResult">The task returning a result to evaluate.</param>
|
||||
/// <param name="Success">The function to execute if the result is successful.</param>
|
||||
/// <param name="Fail">The function to execute if the result is a failure.</param>
|
||||
/// <returns>The result of the executed function.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static async Task<I> ThenAsync<I>(this Task<Result> tResult, Func<I> Success, Func<List<string>, List<Notice>, I> Fail)
|
||||
{
|
||||
Result result = await tResult;
|
||||
return result.IsSuccess ? Success() : Fail(result.Messages, result.Notices);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously executes a function based on the success or failure of a task returning a result.
|
||||
/// </summary>
|
||||
/// <typeparam name="I">The type of the return value.</typeparam>
|
||||
/// <param name="tResult">The task returning a result to evaluate.</param>
|
||||
/// <param name="SuccessAsync">The asynchronous function to execute if the result is successful.</param>
|
||||
/// <param name="Fail">The function to execute if the result is a failure.</param>
|
||||
/// <returns>The result of the executed function.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static async Task<I> ThenAsync<I>(this Task<Result> tResult, Func<Task<I>> SuccessAsync, Func<List<string>, List<Notice>, I> Fail)
|
||||
{
|
||||
Result result = await tResult;
|
||||
return result.IsSuccess ? await SuccessAsync() : Fail(result.Messages, result.Notices);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously executes a function based on the success or failure of a task returning a data result.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data in the result.</typeparam>
|
||||
/// <typeparam name="I">The type of the return value.</typeparam>
|
||||
/// <param name="tResult">The task returning a data result to evaluate.</param>
|
||||
/// <param name="Success">The function to execute if the data result is successful.</param>
|
||||
/// <param name="Fail">The function to execute if the data result is a failure.</param>
|
||||
/// <returns>The result of the executed function.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static async Task<I> ThenAsync<T, I>(this Task<DataResult<T>> tResult, Func<T, I> Success, Func<List<string>, List<Notice>, I> Fail)
|
||||
{
|
||||
DataResult<T> result = await tResult;
|
||||
return result.IsSuccess ? Success(result.Data) : Fail(result.Messages, result.Notices);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously executes a function based on the success or failure of a task returning a data result.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data in the result.</typeparam>
|
||||
/// <typeparam name="I">The type of the return value.</typeparam>
|
||||
/// <param name="tResult">The task returning a data result to evaluate.</param>
|
||||
/// <param name="SuccessAsync">The asynchronous function to execute if the data result is successful.</param>
|
||||
/// <param name="Fail">The function to execute if the data result is a failure.</param>
|
||||
/// <returns>The result of the executed function.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static async Task<I> ThenAsync<T, I>(this Task<DataResult<T>> tResult, Func<T, Task<I>> SuccessAsync, Func<List<string>, List<Notice>, I> Fail)
|
||||
{
|
||||
DataResult<T> result = await tResult;
|
||||
return result.IsSuccess ? await SuccessAsync(result.Data) : Fail(result.Messages, result.Notices);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Joins the values into a single string with optional start, separator, and end strings.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the values.</typeparam>
|
||||
/// <param name="values">The values to join.</param>
|
||||
/// <param name="start">The starting string.</param>
|
||||
/// <param name="separator">The separator string.</param>
|
||||
/// <param name="end">The ending string.</param>
|
||||
/// <returns>The joined string.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static string Join<T>(this IEnumerable<T> values, string start = "", string seperator = ". ", string end = ".")
|
||||
=> new StringBuilder(start).Append(string.Join(seperator, values)).Append(end).ToString();
|
||||
|
||||
/// <summary>
|
||||
/// Logs the notices using the specified logger.
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger to use.</param>
|
||||
/// <param name="notices">The collection of notices to log.</param>
|
||||
/// <param name="start">The starting string for each notice.</param>
|
||||
/// <param name="separator">The separator string for messages in each notice.</param>
|
||||
/// <param name="end">The ending string for each notice.</param>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static void LogNotice(this ILogger logger, IEnumerable<Notice> notices, string start = ": ", string seperator = ". ", string end = ".\n")
|
||||
{
|
||||
foreach (LogLevel level in Enum.GetValues(typeof(LogLevel)))
|
||||
{
|
||||
var logNotices = notices.Where(n => n.Level == level);
|
||||
|
||||
if (!logNotices.Any())
|
||||
continue;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (Notice notice in logNotices)
|
||||
{
|
||||
if (notice.Flag is not null)
|
||||
sb.Append(notice.Flag);
|
||||
|
||||
if (notice.Messages.Any())
|
||||
sb.Append(start).Append(string.Join(seperator, notice.Messages)).AppendLine(end);
|
||||
else sb.Append(end);
|
||||
}
|
||||
logger.Log(level, sb.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs the notices from a result using the specified logger.
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger to use.</param>
|
||||
/// <param name="result">The result containing the notices to log.</param>
|
||||
/// <param name="start">The starting string for each notice.</param>
|
||||
/// <param name="separator">The separator string for messages in each notice.</param>
|
||||
/// <param name="end">The ending string for each notice.</param>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static void LogNotice(this ILogger logger, Result result, string start = ": ", string seperator = ". ", string end = ".\n")
|
||||
=> logger.LogNotice(notices: result.Notices, start: start, seperator: seperator, end: end);
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the data result is right (true).
|
||||
/// </summary>
|
||||
/// <param name="bResult">The data result to evaluate.</param>
|
||||
/// <returns>True if the data result is true; otherwise, false.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static bool IsRight(this DataResult<bool> bResult) => bResult.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the data result is wrong (false).
|
||||
/// </summary>
|
||||
/// <param name="bResult">The data result to evaluate.</param>
|
||||
/// <returns>True if the data result is false; otherwise, false.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static bool IsWrong(this DataResult<bool> bResult) => !bResult.Data;
|
||||
}
|
||||
#endif
|
||||
30
DigitalData.Core.Abstraction.Application/DTO/DataResult.cs
Normal file
30
DigitalData.Core.Abstraction.Application/DTO/DataResult.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
#if NET
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace DigitalData.Core.Abstraction.Application.DTO;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a result of an operation that includes data, inheriting from <see cref="Result"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data included in the result.</typeparam>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public class DataResult<T> : Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the data included in the result. This property is required.
|
||||
/// It will be ignored during JSON serialization if the value is null.
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public required T Data { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Converts the current <see cref="DataResult{T}"/> to a failed <see cref="DataResult{I}"/>,
|
||||
/// preserving the messages and notices.
|
||||
/// </summary>
|
||||
/// <typeparam name="I">The type of the data in the new failed result.</typeparam>
|
||||
/// <returns>A failed <see cref="DataResult{I}"/> with the current messages and notices.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public DataResult<I> ToFail<I>() => Fail<I>().Message(Messages).Notice(Notices);
|
||||
}
|
||||
#endif
|
||||
52
DigitalData.Core.Abstraction.Application/DTO/Flag.cs
Normal file
52
DigitalData.Core.Abstraction.Application/DTO/Flag.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
#if NET
|
||||
namespace DigitalData.Core.Abstraction.Application.DTO;
|
||||
|
||||
/// <summary>
|
||||
/// Defines flags that indicate specific types of status or conditions in a service operation.
|
||||
/// These flags help in categorizing and identifying specific circumstances or issues that may arise during execution.
|
||||
/// </summary>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public enum Flag
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates a security breach or vulnerability has been detected during the service operation.
|
||||
/// </summary>
|
||||
SecurityBreach,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates a potential issue with data integrity during the service operation.
|
||||
/// This flag is used when data may have been altered, corrupted, or is otherwise unreliable,
|
||||
/// which could impact the accuracy or trustworthiness of the operation's results.
|
||||
/// </summary>
|
||||
DataIntegrityIssue,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that either a security breach, a data integrity issue, or both have been detected during the service operation.
|
||||
/// This flag is used when it is not sure whether the problem is security or data integrity. In this case, data integrity should be checked first.
|
||||
/// </summary>
|
||||
SecurityBreachOrDataIntegrity,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates a possible security breach during the service operation.
|
||||
/// </summary>
|
||||
PossibleSecurityBreach,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates a possible issue with data integrity during the service operation.
|
||||
/// This flag is used when there is a suspicion of data alteration, corruption, or unreliability.
|
||||
/// </summary>
|
||||
PossibleDataIntegrityIssue,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that either a possible security breach, a possible data integrity issue, or both have been detected during the service operation.
|
||||
/// This flag is used when it is uncertain whether the issue is related to security, data integrity, or both.
|
||||
/// </summary>
|
||||
PossibleSecurityBreachOrDataIntegrity,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the requested resource or operation could not be found.
|
||||
/// This flag is used when the specified item or condition does not exist or is unavailable.
|
||||
/// </summary>
|
||||
NotFound
|
||||
}
|
||||
#endif
|
||||
30
DigitalData.Core.Abstraction.Application/DTO/Notice.cs
Normal file
30
DigitalData.Core.Abstraction.Application/DTO/Notice.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
#if NET
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace DigitalData.Core.Abstraction.Application.DTO;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a notice for logging purposes, containing a flag, log level, and associated messages.
|
||||
/// </summary>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public class Notice
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets an optional flag associated with the notice.
|
||||
/// </summary>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public Enum? Flag { get; init; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the log level for the notice.
|
||||
/// </summary>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public LogLevel Level { get; init; } = LogLevel.None;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of messages associated with the notice.
|
||||
/// </summary>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public List<string> Messages { get; init; } = new();
|
||||
}
|
||||
#endif
|
||||
110
DigitalData.Core.Abstraction.Application/DTO/Result.cs
Normal file
110
DigitalData.Core.Abstraction.Application/DTO/Result.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
#if NET
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace DigitalData.Core.Abstraction.Application.DTO;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the result of an operation, containing information about its success or failure,
|
||||
/// messages for the client, and notices for logging.
|
||||
/// </summary>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public class Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the operation was successful.
|
||||
/// </summary>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public bool IsSuccess { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the operation failed.
|
||||
/// </summary>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public bool IsFailed => !IsSuccess;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of messages intended for the client.
|
||||
/// </summary>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public List<string> Messages { get; init; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of notices intended for logging purposes. This property is ignored during JSON serialization.
|
||||
/// </summary>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
[JsonIgnore]
|
||||
public List<Notice> Notices = new();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="DataResult{T}"/> with the specified data.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data.</typeparam>
|
||||
/// <param name="data">The data to include in the result.</param>
|
||||
/// <returns>A new <see cref="DataResult{T}"/> instance.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public DataResult<T> Data<T>(T data) => new()
|
||||
{
|
||||
IsSuccess = IsSuccess,
|
||||
Messages = Messages,
|
||||
Notices = Notices,
|
||||
Data = data
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Checks if any notice has the specified flag.
|
||||
/// </summary>
|
||||
/// <param name="flag">The flag to check.</param>
|
||||
/// <returns>True if any notice has the specified flag; otherwise, false.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public bool HasFlag(Enum flag) => Notices.Any(n => n.Flag?.ToString() == flag.ToString());
|
||||
|
||||
/// <summary>
|
||||
/// Checks if any notice has any of the specified flags.
|
||||
/// </summary>
|
||||
/// <param name="flags">The flags to check.</param>
|
||||
/// <returns>True if any notice has any of the specified flags; otherwise, false.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public bool HasAnyFlag(params Enum[] flags) => flags.Any(HasFlag);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new successful <see cref="Result"/>.
|
||||
/// </summary>
|
||||
/// <returns>A new successful <see cref="Result"/>.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static Result Success() => new() { IsSuccess = true };
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new failed <see cref="Result"/>.
|
||||
/// </summary>
|
||||
/// <returns>A new failed <see cref="Result"/>.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static Result Fail() => new() { IsSuccess = false };
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new successful <see cref="DataResult{T}"/> with the specified data.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data.</typeparam>
|
||||
/// <param name="data">The data to include in the result.</param>
|
||||
/// <returns>A new successful <see cref="DataResult{T}"/> with the specified data.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public static DataResult<T> Success<T>(T data) => new()
|
||||
{
|
||||
IsSuccess = true,
|
||||
Data = data
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new failed <see cref="DataResult{T}"/> with no data.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data.</typeparam>
|
||||
/// <returns>A new failed <see cref="DataResult{T}"/> with no data.</returns>
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
#pragma warning disable CS8601 // Possible null reference assignment.
|
||||
public static DataResult<T> Fail<T>() => new()
|
||||
{
|
||||
IsSuccess = false,
|
||||
Data = default
|
||||
};
|
||||
#pragma warning restore CS8601 // Possible null reference assignment.
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,83 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net462;net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<Description>This package defines the abstraction layer for the DigitalData.Core.Application module, providing interfaces and contracts for application services, repositories, and infrastructure components in alignment with Clean Architecture principles.</Description>
|
||||
<PackageId>DigitalData.Core.Abstraction.Application</PackageId>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>DigitalData.Core.Abstraction.Application</Product>
|
||||
<Copyright>Copyright 2025</Copyright>
|
||||
<PackageIcon>core_icon.png</PackageIcon>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
|
||||
<PackageTags>digital data core application clean architecture abstraction</PackageTags>
|
||||
<Version>1.6.0</Version>
|
||||
<AssemblyVersion>1.6.0</AssemblyVersion>
|
||||
<FileVersion>1.6.0</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\Assets\core_icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- disable for net462 -->
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'net462'">
|
||||
<Nullable>disable</Nullable>
|
||||
<ImplicitUsings>disable</ImplicitUsings>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- enable for net7 and more -->
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'net7.0' Or '$(TargetFramework)' == 'net8.0' Or '$(TargetFramework)' == 'net9.0'">
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.16" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
|
||||
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="7.0.1" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.5.1" />
|
||||
<PackageReference Include="System.Security.Cryptography.Cng" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
|
||||
<PackageReference Include="AutoMapper" Version="10.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="3.1.32" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
|
||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="7.0.20" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="8.0.15" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="9.0.5" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="9.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DigitalData.Core.Abstractions\DigitalData.Core.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
96
DigitalData.Core.Abstraction.Application/EntityExtensions.cs
Normal file
96
DigitalData.Core.Abstraction.Application/EntityExtensions.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
#if NET
|
||||
namespace DigitalData.Core.Abstraction.Application;
|
||||
|
||||
/// <summary>
|
||||
/// Provides extension methods for retrieving the value of an 'Id' property from objects.
|
||||
/// </summary>
|
||||
public static class EntityExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Attempts to retrieve the value of the 'Id' property from the specified object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TId">The expected type of the 'Id' property.</typeparam>
|
||||
/// <param name="obj">The object from which to retrieve the 'Id' property.</param>
|
||||
/// <returns>
|
||||
/// The value of the 'Id' property if it exists and is of type <typeparamref name="TId"/>; otherwise, <c>default</c>.
|
||||
/// </returns>
|
||||
public static TId? GetIdOrDefault<TId>(this object? obj)
|
||||
{
|
||||
var prop = obj?.GetType().GetProperty("Id");
|
||||
return prop is not null && prop.GetValue(obj) is TId id ? id : default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the value of the 'Id' property from the specified object, or throws an exception if not found or of the wrong type.
|
||||
/// </summary>
|
||||
/// <typeparam name="TId">The expected type of the 'Id' property.</typeparam>
|
||||
/// <param name="obj">The object from which to retrieve the 'Id' property.</param>
|
||||
/// <returns>The value of the 'Id' property.</returns>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Thrown if the object does not have a readable 'Id' property of type <typeparamref name="TId"/>.
|
||||
/// </exception>
|
||||
public static TId GetId<TId>(this object? obj)
|
||||
=> obj.GetIdOrDefault<TId>()
|
||||
?? throw new InvalidOperationException($"The object of type '{obj?.GetType().FullName ?? "null"}' does not have a readable 'Id' property of type '{typeof(TId).FullName}'.");
|
||||
|
||||
/// <summary>
|
||||
/// Tries to retrieve the value of the 'Id' property from the specified object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TId">The expected type of the 'Id' property.</typeparam>
|
||||
/// <param name="obj">The object from which to retrieve the 'Id' property.</param>
|
||||
/// <param name="id">When this method returns, contains the value of the 'Id' property if found; otherwise, the default value for the type.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the 'Id' property was found and is of type <typeparamref name="TId"/>; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public static bool TryGetId<TId>(object? obj, out TId id)
|
||||
{
|
||||
#pragma warning disable CS8601
|
||||
id = obj.GetIdOrDefault<TId>();
|
||||
#pragma warning restore CS8601
|
||||
return id is not null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to retrieve the value of the 'Id' property from the specified object.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object from which to retrieve the 'Id' property.</param>
|
||||
/// <returns>
|
||||
/// The value of the 'Id' property if it exists; otherwise, <c>null</c>.
|
||||
/// </returns>
|
||||
public static object? GetIdOrDefault(this object? obj)
|
||||
{
|
||||
var prop = obj?.GetType().GetProperty("Id");
|
||||
return prop?.GetValue(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the value of the 'Id' property from the specified object, or throws an exception if not found.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object from which to retrieve the 'Id' property.</param>
|
||||
/// <returns>The value of the 'Id' property.</returns>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Thrown if the object does not have a readable 'Id' property.
|
||||
/// </exception>
|
||||
public static object GetId(this object? obj)
|
||||
=> obj.GetIdOrDefault()
|
||||
?? throw new InvalidOperationException($"The object of type '{obj?.GetType().FullName ?? "null"}' does not have a readable 'Id' property.");
|
||||
|
||||
/// <summary>
|
||||
/// Tries to retrieve the value of the 'Id' property from the specified object.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object from which to retrieve the 'Id' property.</param>
|
||||
/// <param name="id">
|
||||
/// When this method returns, contains the value of the 'Id' property if found; otherwise, <c>null</c>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the 'Id' property was found; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public static bool TryGetId(object? obj, out object id)
|
||||
{
|
||||
#pragma warning disable CS8601
|
||||
id = obj.GetIdOrDefault();
|
||||
#pragma warning restore CS8601
|
||||
return id is not null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,6 +1,5 @@
|
||||
using DigitalData.Core.Contracts.Infrastructure;
|
||||
|
||||
namespace DigitalData.Core.Contracts.Application
|
||||
#if NET
|
||||
namespace DigitalData.Core.Abstraction.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements a simplified CRUD service interface that uses a single Data Transfer Object (DTO) type for all CRUD operations,
|
||||
@@ -8,7 +7,6 @@ namespace DigitalData.Core.Contracts.Application
|
||||
/// This interface inherits from the ICRUDService interface, applying the same DTO type for all generic type parameters,
|
||||
/// thereby simplifying the usage for cases where a single DTO is sufficient for all operations on an entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="TCRUDRepository">The repository type that provides CRUD operations for entities of type TEntity.</typeparam>
|
||||
/// <typeparam name="TDto">The type of the Data Transfer Object used for all CRUD operations.</typeparam>
|
||||
/// <typeparam name="TEntity">The type of the entity this service maps to.</typeparam>
|
||||
/// <typeparam name="TId">The type of the identifier for the entity.</typeparam>
|
||||
@@ -16,8 +14,10 @@ namespace DigitalData.Core.Contracts.Application
|
||||
/// This interface is useful for entities that do not require different DTOs for different operations,
|
||||
/// allowing for a more concise and maintainable codebase when implementing services for such entities.
|
||||
/// </remarks>
|
||||
public interface IBasicCRUDService<TCRUDRepository, TDto, TEntity, TId> : ICRUDService<TCRUDRepository, TDto, TDto, TDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TDto : class where TEntity : class
|
||||
[Obsolete("Use MediatR")]
|
||||
public interface IBasicCRUDService<TDto, TEntity, TId> : ICRUDService<TDto, TDto, TEntity, TId>
|
||||
where TDto : class where TEntity : class
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
26
DigitalData.Core.Abstraction.Application/ICRUDService.cs
Normal file
26
DigitalData.Core.Abstraction.Application/ICRUDService.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
#if NET
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
|
||||
namespace DigitalData.Core.Abstraction.Application;
|
||||
|
||||
[Obsolete("Use MediatR")]
|
||||
public interface ICRUDService<TCreateDto, TReadDto, TEntity, TId> : IReadService<TReadDto, TEntity, TId>
|
||||
where TCreateDto : class where TReadDto : class where TEntity : class
|
||||
{
|
||||
/// <summary>
|
||||
/// Asynchronously creates a new entity based on the provided <paramref name="createDto"/> and returns the identifier of the created entity wrapped in a <see cref="DataResult{TId}"/>.
|
||||
/// The <see cref="DataResult{TId}"/> contains the identifier of the newly created entity on success or an error message on failure.
|
||||
/// </summary>
|
||||
/// <param name="createDto">The data transfer object containing the information for the new entity.</param>
|
||||
/// <returns>A task representing the asynchronous operation, with a <see cref="DataResult{TId}"/> containing the identifier of the created entity or an error message.</returns>
|
||||
Task<DataResult<TReadDto>> CreateAsync(TCreateDto createDto);
|
||||
|
||||
/// <summary>
|
||||
/// Updates an existing entity based on the provided updateDTO and returns the result wrapped in an IServiceMessage,
|
||||
/// indicating the success or failure of the operation, including the error messages on failure.
|
||||
/// </summary>
|
||||
/// <param name="updateDto">The updateDTO with updated values for the entity.</param>
|
||||
/// <returns>An Result indicating the outcome of the update operation, with an appropriate message.</returns>
|
||||
Task<Result> UpdateAsync<TUpdateDto>(TUpdateDto updateDto);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,96 @@
|
||||
#if NET
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
using System.DirectoryServices;
|
||||
|
||||
namespace DigitalData.Core.Abstraction.Application;
|
||||
|
||||
[Obsolete("Use DigitalData.ActiveDirectory")]
|
||||
public interface IDirectorySearchService
|
||||
{
|
||||
public string ServerName { get; }
|
||||
|
||||
public string Root { get; }
|
||||
|
||||
string SearchRootPath { get; }
|
||||
|
||||
Dictionary<string, string> CustomSearchFilters { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates the connections to the server and returns a Boolean value that specifies
|
||||
/// whether the specified username and password are valid.
|
||||
/// </summary>
|
||||
/// <param name="userName">The username that is validated on the server. See the Remarks section
|
||||
/// for more information on the format of userName.</param>
|
||||
/// <param name="password">The password that is validated on the server.</param>
|
||||
/// <returns>True if the credentials are valid; otherwise, false.</returns>
|
||||
bool ValidateCredentials(string userName, string password);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the connections to the server asynchronously and returns a Boolean value that specifies
|
||||
/// whether the specified username and password are valid.
|
||||
/// </summary>
|
||||
/// <param name="userName">The username that is validated on the server. See the Remarks section
|
||||
/// for more information on the format of userName.</param>
|
||||
/// <param name="password">The password that is validated on the server.</param>
|
||||
/// <returns>True if the credentials are valid; otherwise, false.</returns>
|
||||
Task<bool> ValidateCredentialsAsync(string userName, string password);
|
||||
|
||||
/// <summary>
|
||||
/// Finds all directory entries matching the specified filter.
|
||||
/// </summary>
|
||||
/// <param name="searchRoot">The search root.</param>
|
||||
/// <param name="filter">The search filter.</param>
|
||||
/// <param name="searchScope">The search scope.</param>
|
||||
/// <param name="sizeLimit">The size limit.</param>
|
||||
/// <param name="properties">The properties to load.</param>
|
||||
/// <returns>A <see cref="DataResult{T}"/> containing the results.</returns>
|
||||
DataResult<IEnumerable<ResultPropertyCollection>> FindAll(DirectoryEntry searchRoot, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties);
|
||||
|
||||
/// <summary>
|
||||
/// Finds all directory entries matching the specified filter asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="searchRoot">The search root.</param>
|
||||
/// <param name="filter">The search filter.</param>
|
||||
/// <param name="searchScope">The search scope.</param>
|
||||
/// <param name="sizeLimit">The size limit.</param>
|
||||
/// <param name="properties">The properties to load.</param>
|
||||
/// <returns>A <see cref="DataResult{T}"/> containing the results.</returns>
|
||||
Task<DataResult<IEnumerable<ResultPropertyCollection>>> FindAllAsync(DirectoryEntry searchRoot, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties);
|
||||
|
||||
/// <summary>
|
||||
/// Finds all directory entries matching the specified filter, using the user cache.
|
||||
/// </summary>
|
||||
/// <param name="username">The username.</param>
|
||||
/// <param name="filter">The search filter.</param>
|
||||
/// <param name="searchScope">The search scope.</param>
|
||||
/// <param name="sizeLimit">The size limit.</param>
|
||||
/// <param name="properties">The properties to load.</param>
|
||||
/// <returns>A <see cref="DataResult{T}"/> containing the results.</returns>
|
||||
DataResult<IEnumerable<ResultPropertyCollection>> FindAllByUserCache(string username, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties);
|
||||
|
||||
/// <summary>
|
||||
/// Finds all directory entries matching the specified filter asynchronously, using the user cache.
|
||||
/// </summary>
|
||||
/// <param name="username">The username.</param>
|
||||
/// <param name="filter">The search filter.</param>
|
||||
/// <param name="searchScope">The search scope.</param>
|
||||
/// <param name="sizeLimit">The size limit.</param>
|
||||
/// <param name="properties">The properties to load.</param>
|
||||
/// <returns>A <see cref="DataResult{T}"/> containing the results.</returns>
|
||||
Task<DataResult<IEnumerable<ResultPropertyCollection>>> FindAllByUserCacheAsync(string username, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the search root in the cache.
|
||||
/// </summary>
|
||||
/// <param name="username">The directory entry username.</param>
|
||||
/// <param name="password">The directory entry password.</param>
|
||||
void SetSearchRootCache(string username, string password);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the search root from the cache.
|
||||
/// </summary>
|
||||
/// <param name="username">The directory entry username.</param>
|
||||
/// <returns>The cached <see cref="DirectoryEntry"/> if found; otherwise, null.</returns>
|
||||
DirectoryEntry? GetSearchRootCache(string username);
|
||||
}
|
||||
#endif
|
||||
42
DigitalData.Core.Abstraction.Application/IJWTService.cs
Normal file
42
DigitalData.Core.Abstraction.Application/IJWTService.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
#if NET
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Abstraction.Application;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the operations for JWT service handling claims of type <typeparamref name="TClaimValue"/>.
|
||||
/// </summary>
|
||||
public interface IJWTService<TClaimValue>
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates a symmetric security key with the specified byte size.
|
||||
/// </summary>
|
||||
/// <param name="byteSize">The size of the security key in bytes. Default is 32 bytes.</param>
|
||||
/// <returns>A new instance of <see cref="SymmetricSecurityKey"/>.</returns>
|
||||
public static SymmetricSecurityKey GenerateSecurityKey(int byteSize = 32)
|
||||
{
|
||||
using var rng = RandomNumberGenerator.Create();
|
||||
var randomBytes = new byte[byteSize];
|
||||
rng.GetBytes(randomBytes);
|
||||
var securityKey = new SymmetricSecurityKey(randomBytes);
|
||||
|
||||
return securityKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a token based on the specified claim value.
|
||||
/// </summary>
|
||||
/// <param name="claimValue">The claim value to encode in the token.</param>
|
||||
/// <returns>A JWT as a string.</returns>
|
||||
string GenerateToken(TClaimValue claimValue);
|
||||
|
||||
/// <summary>
|
||||
/// Reads and validates a security token from a string representation.
|
||||
/// </summary>
|
||||
/// <param name="token">The JWT to read.</param>
|
||||
/// <returns>A <see cref="JwtSecurityToken"/> if the token is valid; otherwise, null.</returns>
|
||||
JwtSecurityToken? ReadSecurityToken(string token);
|
||||
}
|
||||
#endif
|
||||
40
DigitalData.Core.Abstraction.Application/IReadService.cs
Normal file
40
DigitalData.Core.Abstraction.Application/IReadService.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
#if NET
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
|
||||
namespace DigitalData.Core.Abstraction.Application;
|
||||
|
||||
[Obsolete("Use MediatR")]
|
||||
public interface IReadService<TReadDto, TEntity, TId>
|
||||
where TReadDto : class where TEntity : class
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves an entity by its identifier and returns its readDTO representation wrapped in an IServiceResult,
|
||||
/// including the readDTO on success or null and an error message on failure.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to retrieve.</param>
|
||||
/// <returns>An DataResult containing the readDTO representing the found entity or null, with an appropriate message.</returns>
|
||||
Task<DataResult<TReadDto>> ReadByIdAsync(TId id);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves all entities and returns their readDTO representations wrapped in an IServiceResult,
|
||||
/// including a collection of readDTOs on success or an error message on failure.
|
||||
/// </summary>
|
||||
/// <returns>An DataResult containing a collection of readDTOs representing all entities or an error message.</returns>
|
||||
Task<DataResult<IEnumerable<TReadDto>>> ReadAllAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Deletes an entity by its identifier and returns the result wrapped in an IServiceMessage,
|
||||
/// indicating the success or failure of the operation, including the error messages on failure.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to delete.</param>
|
||||
/// <returns>An Result indicating the outcome of the delete operation, with an appropriate message.</returns>
|
||||
Task<Result> DeleteAsyncById(TId id);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously checks if an entity with the specified identifier exists within the data store.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to check.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains a boolean value indicating whether the entity exists.</returns>
|
||||
Task<bool> HasEntity(TId id);
|
||||
}
|
||||
#endif
|
||||
@@ -1,10 +1,12 @@
|
||||
namespace DigitalData.Core.Contracts.Infrastructure
|
||||
#if NET
|
||||
namespace DigitalData.Core.Abstraction.Application.Repository
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for CRUD operations on a repository for entities of type TEntity.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The type of the entity this repository works with.</typeparam>
|
||||
/// <typeparam name="TId">The type of the identifier for the entity.</typeparam>
|
||||
[Obsolete("Use IRepository")]
|
||||
public interface ICRUDRepository<TEntity, TId> where TEntity : class
|
||||
{
|
||||
/// <summary>
|
||||
@@ -40,5 +42,24 @@
|
||||
/// <param name="entity">The entity to delete.</param>
|
||||
/// <returns>If entity is deleted, return true othwerwise return false.</returns>
|
||||
Task<bool> DeleteAsync(TEntity entity);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously counts all entities in the repository.
|
||||
/// </summary>
|
||||
/// <returns>The total number of entities in the repository.</returns>
|
||||
Task<int> CountAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously counts the number of entities in the repository that match a specific identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entities to count.</param>
|
||||
/// <returns>The number of entities with the specified identifier.</returns>
|
||||
/// <remarks>
|
||||
/// This method provides a count of entities in the database that match the given identifier.
|
||||
/// If there are multiple entities with the same identifier, they will all be counted.
|
||||
/// The default implementation assumes that the identifier is unique for each entity.
|
||||
/// </remarks>
|
||||
Task<int> CountAsync(TId id);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
#if NETFRAMEWORK
|
||||
using System.Collections.Generic;
|
||||
#endif
|
||||
namespace DigitalData.Core.Abstraction.Application.Repository
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines methods for mapping between entities and Data Transfer Objects (DTOs).
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The type of the entity to be mapped.</typeparam>
|
||||
public interface IEntityMapper<TEntity>
|
||||
{
|
||||
/// <summary>
|
||||
/// Maps an entity to a DTO.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDto">The type of the DTO to map to.</typeparam>
|
||||
/// <param name="entity">The entity to be mapped.</param>
|
||||
/// <returns>The mapped DTO.</returns>
|
||||
TDto Map<TDto>(TEntity entity);
|
||||
|
||||
/// <summary>
|
||||
/// Maps an entity list to a DTO list.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDto">The type of the DTO to map to.</typeparam>
|
||||
/// <param name="entities">The entity list to be mapped.</param>
|
||||
/// <returns>The mapped DTO list.</returns>
|
||||
IEnumerable<TDto> Map<TDto>(IEnumerable<TEntity> entities);
|
||||
|
||||
/// <summary>
|
||||
/// Maps a DTO to an entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDto">The type of the DTO to be mapped.</typeparam>
|
||||
/// <param name="dto">The DTO to be mapped.</param>
|
||||
/// <returns>The mapped entity.</returns>
|
||||
TEntity Map<TDto>(TDto dto);
|
||||
|
||||
/// <summary>
|
||||
/// Maps a DTO list to an entity list.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDto">The type of the DTO to be mapped.</typeparam>
|
||||
/// <param name="dtos">The DTO list to be mapped.</param>
|
||||
/// <returns>The mapped entity list.</returns>
|
||||
IEnumerable<TEntity> Map<TDto>(IEnumerable<TDto> dtos);
|
||||
|
||||
/// <summary>
|
||||
/// Maps a DTO to an existing entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDto">The type of the DTO to be mapped.</typeparam>
|
||||
/// <param name="dto">The DTO to be mapped.</param>
|
||||
/// <param name="entity">The existing entity to be updated with the mapped values.</param>
|
||||
/// <returns>The updated entity.</returns>
|
||||
TEntity Map<TDto>(TDto dto, TEntity entity);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
using System.Linq.Expressions;
|
||||
using Microsoft.EntityFrameworkCore.Query;
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
#endif
|
||||
|
||||
namespace DigitalData.Core.Abstraction.Application.Repository
|
||||
{
|
||||
public interface IRepository
|
||||
{
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
Task<int> ExecuteQueryRawAsync([NotParameterized] string sql, IEnumerable<object> parameters, CancellationToken cancel = default);
|
||||
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
Task<int> ExecuteQueryInterpolatedAsync(FormattableString sql, CancellationToken cancel = default);
|
||||
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
int ExecuteQueryRaw([NotParameterized] string sql, params object[] parameters);
|
||||
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
int ExecuteQueryInterpolated(FormattableString sql);
|
||||
}
|
||||
|
||||
public interface IRepository<TEntity>
|
||||
{
|
||||
#region Create
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
Task<TEntity> CreateAsync(TEntity entity, CancellationToken cancel = default);
|
||||
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
Task<IEnumerable<TEntity>> CreateAsync(IEnumerable<TEntity> entities, CancellationToken cancel = default);
|
||||
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
Task<TEntity> CreateAsync<TDto>(TDto dto, CancellationToken cancel = default);
|
||||
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
Task<IEnumerable<TEntity>> CreateAsync<TDto>(IEnumerable<TDto> dtos, CancellationToken cancel = default);
|
||||
#endregion Create
|
||||
|
||||
#region Read
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
IQueryable<TEntity> Query { get; }
|
||||
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
IQueryable<TEntity> QueryRaw([NotParameterized] string sql, params object[] parameters);
|
||||
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
IQueryable<TEntity> QueryInterpolated([NotParameterized] FormattableString sql);
|
||||
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> expression);
|
||||
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
IEnumerable<TEntity> GetAll();
|
||||
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
Task<IEnumerable<TEntity>> GetAllAsync(CancellationToken cancel = default);
|
||||
#endregion Read
|
||||
|
||||
#region Update
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
Task UpdateAsync<TDto>(TDto dto, Expression<Func<TEntity, bool>> expression, CancellationToken cancel = default);
|
||||
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
Task UpdateAsync<TDto>(TDto dto, Func<IQueryable<TEntity>, IQueryable<TEntity>> query, CancellationToken cancel = default);
|
||||
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
Task UpdateAsync(Action<TEntity> modification, Func<IQueryable<TEntity>, IQueryable<TEntity>> query, CancellationToken cancel = default);
|
||||
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
Task UpdateAsync(Action<TEntity> modification, Expression<Func<TEntity, bool>> expression, CancellationToken cancel = default);
|
||||
#endregion Update
|
||||
|
||||
#region Delete
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
Task DeleteAsync(Expression<Func<TEntity, bool>> expression, CancellationToken cancel = default);
|
||||
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
Task DeleteAsync(Func<IQueryable<TEntity>, IQueryable<TEntity>> query, CancellationToken cancel = default);
|
||||
#endregion Delete
|
||||
|
||||
#region Obsolete
|
||||
[Obsolete("Use CreateAsync, UpdateAsync or DeleteAsync")]
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
IQueryable<TEntity> Read();
|
||||
|
||||
[Obsolete("Use IRepository<TEntity>.Where")]
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
IQueryable<TEntity> ReadOnly();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
#endif
|
||||
|
||||
namespace DigitalData.Core.Abstraction.Application.Repository
|
||||
{
|
||||
public static class ServiceProviderExtensions
|
||||
{
|
||||
public static IRepository<TEntity> Repository<TEntity>(this IServiceProvider serviceProvider)
|
||||
{
|
||||
return serviceProvider.GetRequiredService<IRepository<TEntity>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace DigitalData.Core.Abstractions.Security.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a unique security context that identifies an issuer and an audience.
|
||||
/// </summary>
|
||||
public interface IUniqueSecurityContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the issuer identifier for this security context.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The issuer typically represents the entity that issues a token or a cryptographic key.
|
||||
/// </remarks>
|
||||
string Issuer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the audience identifier for this security context.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The audience typically represents the intended recipient or target of a token or cryptographic operation.
|
||||
/// </remarks>
|
||||
string Audience { get; }
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageId>DigitalData.Core.Abstractions.Security</PackageId>
|
||||
<Version>1.0.1</Version>
|
||||
<AssemblyVersion>1.0.1</AssemblyVersion>
|
||||
<FileVersion>1.0.1</FileVersion>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>Digital Data GmbH</Product>
|
||||
<Copyright>Copyright 2025</Copyright>
|
||||
<PackageProjectUrl>http://git.dd:3000/AppStd/WebCoreModules.git</PackageProjectUrl>
|
||||
<PackageIcon>core_icon.png</PackageIcon>
|
||||
<Description>This package defines the foundational abstractions for implementing security functionalities within the DigitalData.Core ecosystem. It provides interfaces and base classes for encryption, decryption, and secure authentication mechanisms. Designed to ensure flexibility and consistency, it enables seamless integration with various security implementations, such as RSA-based encryption and JWT handling.</Description>
|
||||
<PackageTags>digital data core security abstractions</PackageTags>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\..\nuget-package-icons\core_icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.7.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,64 @@
|
||||
using DigitalData.Core.Abstractions.Security.Common;
|
||||
using DigitalData.Core.Abstractions.Security.Key;
|
||||
using DigitalData.Core.Abstractions.Security.Services;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.Text;
|
||||
|
||||
namespace DigitalData.Core.Abstractions.Security.Extensions;
|
||||
|
||||
public static class SecurityExtensions
|
||||
{
|
||||
#region Unique Security Context
|
||||
public static IEnumerable<TUniqueSecurityContext> GetByIssuer<TUniqueSecurityContext>(this IEnumerable<TUniqueSecurityContext> contextes, string issuer) where TUniqueSecurityContext : IUniqueSecurityContext
|
||||
=> contextes.Where(c => c.Issuer == issuer);
|
||||
|
||||
public static IEnumerable<TUniqueSecurityContext> GetByAudience<TUniqueSecurityContext>(this IEnumerable<TUniqueSecurityContext> contextes, string audience) where TUniqueSecurityContext : IUniqueSecurityContext
|
||||
=> contextes.Where(c => c.Audience == audience);
|
||||
|
||||
public static TUniqueSecurityContext Get<TUniqueSecurityContext>(this IEnumerable<TUniqueSecurityContext> contextes, string issuer, string audience) where TUniqueSecurityContext : IUniqueSecurityContext
|
||||
=> contextes.Where(c => c.Issuer == issuer && c.Audience == audience).SingleOrDefault()
|
||||
?? throw new InvalidOperationException($"Exactly one {typeof(TUniqueSecurityContext).Name} must exist with Issuer: '{issuer}' and Audience: '{audience}'.");
|
||||
|
||||
public static bool TryGet<TUniqueSecurityContext>(this IEnumerable<TUniqueSecurityContext> contextes, string issuer, string audience, out TUniqueSecurityContext context) where TUniqueSecurityContext : IUniqueSecurityContext
|
||||
{
|
||||
#pragma warning disable CS8601 // Possible null reference assignment.
|
||||
context = contextes.SingleOrDefault(c => c.Issuer == issuer && c.Audience == audience);
|
||||
#pragma warning restore CS8601 // Possible null reference assignment.
|
||||
return context is not null;
|
||||
}
|
||||
|
||||
public static TUniqueSecurityContext Match<TUniqueSecurityContext>(this IEnumerable<TUniqueSecurityContext> contextes, IUniqueSecurityContext lookupContext) where TUniqueSecurityContext : IUniqueSecurityContext
|
||||
=> contextes.Get(lookupContext.Issuer, lookupContext.Audience);
|
||||
|
||||
public static bool TryMatch<TUniqueSecurityContext>(this IEnumerable<TUniqueSecurityContext> contextes, IUniqueSecurityContext lookupContext, out TUniqueSecurityContext context) where TUniqueSecurityContext : IUniqueSecurityContext
|
||||
=> contextes.TryGet(lookupContext.Issuer, lookupContext.Audience, out context);
|
||||
#endregion Unique Security Context
|
||||
|
||||
#region De/serilization
|
||||
internal static byte[] Base64ToByte(this string base64String) => Convert.FromBase64String(base64String);
|
||||
|
||||
internal static string BytesToString(this byte[] bytes) => Encoding.UTF8.GetString(bytes);
|
||||
|
||||
internal static string ToBase64String(this byte[] bytes) => Convert.ToBase64String(bytes);
|
||||
|
||||
internal static byte[] ToBytes(this string str) => Encoding.UTF8.GetBytes(str);
|
||||
|
||||
public static string Decrypt(this IAsymmetricDecryptor decryptor, string data) => decryptor
|
||||
.Decrypt(data.Base64ToByte()).BytesToString();
|
||||
#endregion De/serilization
|
||||
|
||||
#region Asymmetric Encryptor
|
||||
public static string Encrypt(this IAsymmetricEncryptor encryptor, string data) => encryptor.Encrypt(data.ToBytes()).ToBase64String();
|
||||
#endregion Asymmetric Encryptor
|
||||
|
||||
#region Jwt Signature Handler
|
||||
public static string WriteToken<TPrincipal>(this IJwtSignatureHandler<TPrincipal> handler, SecurityTokenDescriptor descriptor)
|
||||
=> handler.WriteToken(handler.CreateToken(descriptor));
|
||||
|
||||
public static string WriteToken<TPrincipal>(this IJwtSignatureHandler<TPrincipal> handler, TPrincipal subject, IAsymmetricTokenDescriptor descriptor)
|
||||
=> handler.WriteToken(handler.CreateToken(subject: subject, descriptor: descriptor));
|
||||
|
||||
public static string WriteToken<TPrincipal>(this IJwtSignatureHandler<TPrincipal> handler, TPrincipal subject, string issuer, string audience)
|
||||
=> handler.WriteToken(handler.CreateToken(subject: subject, issuer: issuer, audience: audience));
|
||||
#endregion Jwt Signature Handler
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace DigitalData.Core.Abstractions.Security.Key;
|
||||
|
||||
public interface IAsymmetricDecryptor : IAsymmetricPrivateKey
|
||||
{
|
||||
byte[] Decrypt(byte[] data);
|
||||
|
||||
IAsymmetricEncryptor Encryptor { get; }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace DigitalData.Core.Abstractions.Security.Key;
|
||||
|
||||
public interface IAsymmetricEncryptor : IAsymmetricPublicKey
|
||||
{
|
||||
byte[] Encrypt(byte[] data);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace DigitalData.Core.Abstractions.Security.Key;
|
||||
|
||||
public interface IAsymmetricKey
|
||||
{
|
||||
string? Id { get; }
|
||||
|
||||
string Content { get; }
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace DigitalData.Core.Abstractions.Security.Key;
|
||||
|
||||
public interface IAsymmetricPrivateKey : IAsymmetricKey
|
||||
{
|
||||
bool IsEncrypted { get; }
|
||||
|
||||
IAsymmetricPublicKey PublicKey { get; }
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace DigitalData.Core.Abstractions.Security.Key;
|
||||
|
||||
public interface IAsymmetricPublicKey : IAsymmetricKey
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using DigitalData.Core.Abstractions.Security.Common;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace DigitalData.Core.Abstractions.Security.Key;
|
||||
|
||||
/// <summary>
|
||||
/// Contains some information which used to create a security token. Designed to abstract <see cref="SecurityTokenDescriptor"/>
|
||||
/// </summary>
|
||||
public interface IAsymmetricTokenDescriptor : IAsymmetricPrivateKey, IUniqueSecurityContext
|
||||
{
|
||||
IAsymmetricTokenValidator Validator { get; }
|
||||
|
||||
TimeSpan Lifetime { get; init; }
|
||||
|
||||
#region SecurityTokenDescriptor Map
|
||||
/// <summary>
|
||||
/// Defines the compression algorithm that will be used to compress the JWT token payload.
|
||||
/// </summary>
|
||||
string CompressionAlgorithm { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="EncryptingCredentials"/> used to create a encrypted security token.
|
||||
/// </summary>
|
||||
EncryptingCredentials EncryptingCredentials { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value of the 'expiration' claim. This value should be in UTC.
|
||||
/// </summary>
|
||||
DateTime? Expires { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the time the security token was issued. This value should be in UTC.
|
||||
/// </summary>
|
||||
DateTime? IssuedAt { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the notbefore time for the security token. This value should be in UTC.
|
||||
/// </summary>
|
||||
DateTime? NotBefore { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the token type.
|
||||
/// <remarks> If provided, this will be added as the value for the 'typ' header parameter. In the case of a JWE, this will be added to both the inner (JWS) and the outer token (JWE) header. By default, the value used is 'JWT'.
|
||||
/// If <see cref="AdditionalHeaderClaims"/> also contains 'typ' header claim value, it will override the TokenType provided here.
|
||||
/// This value is used only for JWT tokens and not for SAML/SAML2 tokens</remarks>
|
||||
/// </summary>
|
||||
string TokenType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="Dictionary{TKey, TValue}"/> which contains any custom header claims that need to be added to the JWT token header.
|
||||
/// The 'alg', 'kid', 'x5t', 'enc', and 'zip' claims are added by default based on the <see cref="SigningCredentials"/>,
|
||||
/// <see cref="EncryptingCredentials"/>, and/or <see cref="CompressionAlgorithm"/> provided and SHOULD NOT be included in this dictionary as this
|
||||
/// will result in an exception being thrown.
|
||||
/// <remarks> These claims are only added to the outer header (in case of a JWE).</remarks>
|
||||
/// </summary>
|
||||
IDictionary<string, object> AdditionalHeaderClaims { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="Dictionary{TKey, TValue}"/> which contains any custom header claims that need to be added to the inner JWT token header.
|
||||
/// The 'alg', 'kid', 'x5t', 'enc', and 'zip' claims are added by default based on the <see cref="SigningCredentials"/>,
|
||||
/// <see cref="EncryptingCredentials"/>, and/or <see cref="CompressionAlgorithm"/> provided and SHOULD NOT be included in this dictionary as this
|
||||
/// will result in an exception being thrown.
|
||||
/// <remarks>
|
||||
/// For JsonWebTokenHandler, these claims are merged with <see cref="AdditionalHeaderClaims"/> while adding to the inner JWT header.
|
||||
/// </remarks>
|
||||
/// </summary>
|
||||
IDictionary<string, object> AdditionalInnerHeaderClaims { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="SigningCredentials"/> used to create a security token.
|
||||
/// </summary>
|
||||
SigningCredentials SigningCredentials { get; }
|
||||
#endregion SecurityTokenDescriptor
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace DigitalData.Core.Abstractions.Security.Key;
|
||||
|
||||
public interface IAsymmetricTokenValidator : IAsymmetricPublicKey
|
||||
{
|
||||
SecurityKey SecurityKey { get; }
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Security.Cryptography;
|
||||
using DigitalData.Core.Abstractions.Security.Key;
|
||||
|
||||
namespace DigitalData.Core.Abstractions.Security.Services;
|
||||
|
||||
public interface IAsymmetricKeyFactory
|
||||
{
|
||||
string CreatePrivateKeyPem(int? keySizeInBits = null, bool encrypt = false);
|
||||
|
||||
string CreateEncryptedPrivateKeyPem(
|
||||
PbeEncryptionAlgorithm? pbeEncryptionAlgorithm = null,
|
||||
HashAlgorithmName? hashAlgorithmName = null,
|
||||
int? iterationCount = null,
|
||||
int? keySizeInBits = null,
|
||||
string? password = null);
|
||||
|
||||
string CreateEncryptedPrivateKeyPem(
|
||||
PbeParameters pbeParameters,
|
||||
int? keySizeInBits = null,
|
||||
string? password = null);
|
||||
|
||||
IAsymmetricDecryptor CreateDecryptor(string pem, string? issuer = null, string? audience = null, bool encrypt = false, RSAEncryptionPadding? padding = null);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using DigitalData.Core.Abstractions.Security.Key;
|
||||
|
||||
namespace DigitalData.Core.Abstractions.Security.Services;
|
||||
|
||||
public interface IAsymmetricKeyPool : IAsymmetricKeyFactory
|
||||
{
|
||||
IEnumerable<IAsymmetricDecryptor> Decryptors { get; }
|
||||
|
||||
IAsymmetricDecryptor VaultDecryptor { get; }
|
||||
|
||||
IEnumerable<IAsymmetricTokenDescriptor> TokenDescriptors { get; }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using DigitalData.Core.Abstractions.Security.Key;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace DigitalData.Core.Abstractions.Security.Services
|
||||
{
|
||||
public interface IJwtSignatureHandler<TPrincipal>
|
||||
{
|
||||
SecurityToken CreateToken(SecurityTokenDescriptor tokenDescriptor);
|
||||
|
||||
SecurityToken CreateToken(TPrincipal subject, IAsymmetricTokenDescriptor descriptor);
|
||||
|
||||
SecurityToken CreateToken(TPrincipal subject, string issuer, string audience);
|
||||
|
||||
string WriteToken(SecurityToken token);
|
||||
}
|
||||
}
|
||||
31
DigitalData.Core.Abstractions/ConfigurationExtension.cs
Normal file
31
DigitalData.Core.Abstractions/ConfigurationExtension.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
#if NET
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace DigitalData.Core.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for the <see cref="IConfiguration"/> interface, providing
|
||||
/// additional functionality for retrieving configuration values with default behavior.
|
||||
/// </summary>
|
||||
public static class ConfigurationExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves a configuration value for the specified key, or returns a default value
|
||||
/// of type <typeparamref name="T"/> if the configuration is not found or the key is null.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to retrieve from the configuration.</typeparam>
|
||||
/// <param name="configuration">The <see cref="IConfiguration"/> instance.</param>
|
||||
/// <param name="key">The optional key to look for in the configuration. If null, the method
|
||||
/// retrieves the root configuration.</param>
|
||||
/// <returns>
|
||||
/// An instance of <typeparamref name="T"/> populated from the configuration values, or
|
||||
/// a new instance of <typeparamref name="T"/> if no matching configuration is found.
|
||||
/// </returns>
|
||||
public static T GetOrDefault<T>(this IConfiguration configuration, string? key = null)
|
||||
where T : new()
|
||||
=> (key is null
|
||||
? configuration.Get<T>()
|
||||
: configuration.GetSection(key).Get<T>())
|
||||
?? new T();
|
||||
}
|
||||
#endif
|
||||
42
DigitalData.Core.Abstractions/DeferredServiceProvider.cs
Normal file
42
DigitalData.Core.Abstractions/DeferredServiceProvider.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
#if NET
|
||||
namespace DigitalData.Core.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// A deferred implementation of <see cref="IServiceProvider"/> that allows the <see cref="IServiceProvider"/> instance
|
||||
/// to be provided at a later time via a factory callback.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is particularly useful when service registration requires an <see cref="IServiceProvider"/> instance,
|
||||
/// but the service provider is not yet available at registration time.
|
||||
/// By using <see cref="DeferredServiceProvider"/>, a service can safely resolve dependencies once
|
||||
/// the application's service provider has been built, ensuring a single consistent scope.
|
||||
/// </remarks>
|
||||
public class DeferredServiceProvider : IServiceProvider
|
||||
{
|
||||
private Lazy<IServiceProvider>? _serviceProvider;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the factory that will be used to lazily initialize the <see cref="IServiceProvider"/> instance.
|
||||
/// </summary>
|
||||
public Func<IServiceProvider> Factory
|
||||
{
|
||||
set => _serviceProvider = new(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the requested service object from the deferred <see cref="IServiceProvider"/>.
|
||||
/// </summary>
|
||||
/// <param name="serviceType">The type of service object to retrieve.</param>
|
||||
/// <returns>The requested service object, or <c>null</c> if the service is not available.</returns>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Thrown if the service provider factory has not been set before calling <see cref="GetService"/>.
|
||||
/// </exception>
|
||||
public object? GetService(Type serviceType)
|
||||
{
|
||||
if (_serviceProvider is null)
|
||||
throw new InvalidOperationException("The service provider has not been initialized. Make sure 'Factory' is set before calling 'GetService'.");
|
||||
|
||||
return _serviceProvider.Value.GetService(serviceType);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,68 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net462;net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<!-- NuGet Package Metadata -->
|
||||
<PackageId>DigitalData.Core.Abstractions</PackageId>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>DigitalData.Core.Abstractions</Product>
|
||||
<Description>This package contains abstractions for the DigitalData.Core library.</Description>
|
||||
<PackageTags>digital data core abstractions clean architecture</PackageTags>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<Copyright>Copyright 2024</Copyright>
|
||||
<PackageProjectUrl></PackageProjectUrl>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
|
||||
<PackAsTool>False</PackAsTool>
|
||||
<PackageIcon>core_icon.png</PackageIcon>
|
||||
<Version>4.3.0</Version>
|
||||
<AssemblyVersion>4.3.0</AssemblyVersion>
|
||||
<FileVersion>4.3.0</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\Assets\core_icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- disable for net462 -->
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'net462'">
|
||||
<Nullable>disable</Nullable>
|
||||
<ImplicitUsings>disable</ImplicitUsings>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- enable for net7 and more -->
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'net7.0' Or '$(TargetFramework)' == 'net8.0' Or '$(TargetFramework)' == 'net9.0'">
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
142
DigitalData.Core.Abstractions/Factory.cs
Normal file
142
DigitalData.Core.Abstractions/Factory.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Collections;
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
#endif
|
||||
|
||||
namespace DigitalData.Core.Abstractions
|
||||
{
|
||||
public class Factory : IServiceProvider, IServiceCollection
|
||||
{
|
||||
public static readonly Factory Shared = new Factory();
|
||||
|
||||
private readonly IServiceCollection _serviceCollection = new ServiceCollection();
|
||||
private readonly Lazy<IServiceProvider> _lazyServiceProvider;
|
||||
|
||||
private bool IsBuilt => _lazyServiceProvider.IsValueCreated;
|
||||
|
||||
private PostBuildBehavior _pbBehavior = PostBuildBehavior.ThrowException;
|
||||
|
||||
public Factory BehaveOnPostBuild(PostBuildBehavior postBuildBehavior)
|
||||
{
|
||||
_pbBehavior = postBuildBehavior;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Factory()
|
||||
{
|
||||
_lazyServiceProvider = new Lazy<IServiceProvider>(() => _serviceCollection.BuildServiceProvider());
|
||||
}
|
||||
|
||||
#region Service Provider
|
||||
public object
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
GetService(Type serviceType)
|
||||
{
|
||||
return _lazyServiceProvider.Value.GetService(serviceType);
|
||||
}
|
||||
|
||||
public IServiceScopeFactory ScopeFactory => this.GetRequiredService<IServiceScopeFactory>();
|
||||
#endregion
|
||||
|
||||
#region Service Collection
|
||||
public int Count => _serviceCollection.Count;
|
||||
|
||||
public bool IsReadOnly => _serviceCollection.IsReadOnly;
|
||||
|
||||
public ServiceDescriptor this[int index]
|
||||
{
|
||||
get => _serviceCollection[index];
|
||||
set
|
||||
{
|
||||
if (EnsureBuilt())
|
||||
return;
|
||||
_serviceCollection[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int IndexOf(ServiceDescriptor item)
|
||||
{
|
||||
return _serviceCollection.IndexOf(item);
|
||||
}
|
||||
|
||||
public void Insert(int index, ServiceDescriptor item)
|
||||
{
|
||||
if (EnsureBuilt())
|
||||
return;
|
||||
_serviceCollection.Insert(index, item);
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
if (EnsureBuilt())
|
||||
return;
|
||||
_serviceCollection.RemoveAt(index);
|
||||
}
|
||||
|
||||
public void Add(ServiceDescriptor item)
|
||||
{
|
||||
if (EnsureBuilt())
|
||||
return;
|
||||
_serviceCollection.Add(item);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
if (EnsureBuilt())
|
||||
return;
|
||||
_serviceCollection.Clear();
|
||||
}
|
||||
|
||||
public bool Contains(ServiceDescriptor item)
|
||||
{
|
||||
return _serviceCollection.Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo(ServiceDescriptor[] array, int arrayIndex)
|
||||
{
|
||||
_serviceCollection.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public bool Remove(ServiceDescriptor item)
|
||||
{
|
||||
if (EnsureBuilt())
|
||||
return false;
|
||||
return _serviceCollection.Remove(item);
|
||||
}
|
||||
|
||||
public IEnumerator<ServiceDescriptor> GetEnumerator()
|
||||
{
|
||||
return _serviceCollection.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return (_serviceCollection as IEnumerable).GetEnumerator();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
private bool EnsureBuilt()
|
||||
{
|
||||
if (IsBuilt)
|
||||
{
|
||||
return _pbBehavior == PostBuildBehavior.ThrowException
|
||||
? throw new InvalidOperationException("Service provider has already been built. No further service modifications are allowed.")
|
||||
: true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public enum PostBuildBehavior
|
||||
{
|
||||
ThrowException,
|
||||
Ignore
|
||||
}
|
||||
}
|
||||
18
DigitalData.Core.Abstractions/Interfaces/IDto.cs
Normal file
18
DigitalData.Core.Abstractions/Interfaces/IDto.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace DigitalData.Core.Abstractions.Interfaces
|
||||
#if NET
|
||||
;
|
||||
#elif NETFRAMEWORK
|
||||
{
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that extension methods are handled securely
|
||||
/// </summary>
|
||||
/// <typeparam name="Entity"></typeparam>
|
||||
public interface IDto<Entity> where Entity : IEntity
|
||||
{
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
}
|
||||
#endif
|
||||
17
DigitalData.Core.Abstractions/Interfaces/IEntity.cs
Normal file
17
DigitalData.Core.Abstractions/Interfaces/IEntity.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace DigitalData.Core.Abstractions.Interfaces
|
||||
#if NET
|
||||
;
|
||||
#elif NETFRAMEWORK
|
||||
{
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that extension methods are handled securely
|
||||
/// </summary>
|
||||
public interface IEntity
|
||||
{
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
}
|
||||
#endif
|
||||
33
DigitalData.Core.Abstractions/ServiceProviderExtensions.cs
Normal file
33
DigitalData.Core.Abstractions/ServiceProviderExtensions.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
#if NET
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace DigitalData.Core.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="IServiceProvider"/> to retrieve configuration options.
|
||||
/// </summary>
|
||||
public static class ServiceProviderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves an instance of <typeparamref name="TOptions"/> from the <see cref="IServiceProvider"/>.
|
||||
/// If the options are not registered, returns null.
|
||||
/// </summary>
|
||||
/// <typeparam name="TOptions">The type of the options to retrieve.</typeparam>
|
||||
/// <param name="service">The service provider instance.</param>
|
||||
/// <returns>An instance of <typeparamref name="TOptions"/> or null if not found.</returns>
|
||||
public static TOptions? GetOptions<TOptions>(this IServiceProvider service) where TOptions : class
|
||||
=> service.GetService<IOptions<TOptions>>()?.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves an instance of <typeparamref name="TOptions"/> from the <see cref="IServiceProvider"/>.
|
||||
/// Throws an exception if the options are not registered.
|
||||
/// </summary>
|
||||
/// <typeparam name="TOptions">The type of the options to retrieve.</typeparam>
|
||||
/// <param name="service">The service provider instance.</param>
|
||||
/// <returns>An instance of <typeparamref name="TOptions"/>.</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown when the options are not registered.</exception>
|
||||
public static TOptions GetRequiredOptions<TOptions>(this IServiceProvider service) where TOptions : class
|
||||
=> service.GetRequiredService<IOptions<TOptions>>().Value;
|
||||
}
|
||||
#endif
|
||||
@@ -1,8 +1,6 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using DigitalData.Core.Contracts.Infrastructure;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
using DigitalData.Core.Abstraction.Application;
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
@@ -19,18 +17,18 @@ namespace DigitalData.Core.Application
|
||||
/// reducing the need for multiple DTOs and simplifying the data mapping process. It leverages AutoMapper for object mapping
|
||||
/// and a culture-specific translation service for any necessary text translations, ensuring a versatile and internationalized approach to CRUD operations.
|
||||
/// </remarks>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class BasicCRUDService<TCRUDRepository, TDto, TEntity, TId> :
|
||||
CRUDService<TCRUDRepository, TDto, TDto, TDto, TEntity, TId>, IBasicCRUDService<TCRUDRepository, TDto, TEntity, TId>
|
||||
CRUDService<TCRUDRepository, TDto, TDto, TEntity, TId>, IBasicCRUDService<TDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TDto : class where TEntity : class
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the BasicCRUDService with the specified repository, translation service, and AutoMapper configuration.
|
||||
/// </summary>
|
||||
/// <param name="repository">The CRUD repository for accessing and manipulating entity data.</param>
|
||||
/// <param name="translationService">The service used for key-based text translations, facilitating localization.</param>
|
||||
/// <param name="mapper">The AutoMapper instance for mapping between DTOs and entities.</param>
|
||||
public BasicCRUDService(TCRUDRepository repository, IStringLocalizer defaultLocalizer, IMapper mapper) :
|
||||
base(repository, defaultLocalizer, mapper)
|
||||
public BasicCRUDService(TCRUDRepository repository, IMapper mapper) :
|
||||
base(repository, mapper)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using DigitalData.Core.Contracts.Infrastructure;
|
||||
using AutoMapper;
|
||||
using System.Reflection;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using DigitalData.Core.DTO;
|
||||
using AutoMapper;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using DigitalData.Core.Abstraction.Application;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
@@ -13,32 +11,21 @@ namespace DigitalData.Core.Application
|
||||
/// </summary>
|
||||
/// <typeparam name="TCreateDto">The DTO type for create operations.</typeparam>
|
||||
/// <typeparam name="TReadDto">The DTO type for read operations.</typeparam>
|
||||
/// <typeparam name="TUpdateDto">The DTO type for update operations.</typeparam>
|
||||
/// <typeparam name="TEntity">The entity type.</typeparam>
|
||||
/// <typeparam name="TId">The type of the identifier for the entity.</typeparam>
|
||||
public class CRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : ICRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TCreateDto : class where TReadDto : class where TUpdateDto : class where TEntity : class
|
||||
///
|
||||
[Obsolete("Use MediatR")]
|
||||
public class CRUDService<TCRUDRepository, TCreateDto, TReadDto, TEntity, TId> : ReadService<TCRUDRepository, TReadDto, TEntity, TId>, ICRUDService<TCreateDto, TReadDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TCreateDto : class where TReadDto : class where TEntity : class
|
||||
{
|
||||
protected readonly TCRUDRepository _repository;
|
||||
protected readonly IMapper _mapper;
|
||||
protected readonly PropertyInfo? _keyPropertyInfo;
|
||||
protected readonly IStringLocalizer _localizer;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CRUDService class with the specified repository, translation service, and mapper.
|
||||
/// </summary>
|
||||
/// <param name="repository">The CRUD repository for accessing the database.</param>
|
||||
/// <param name="localizer">The localizer for translating messages based on culture.</param>
|
||||
/// <param name="mapper">The AutoMapper instance for mapping between DTOs and entity objects.</param>
|
||||
public CRUDService(TCRUDRepository repository, IStringLocalizer localizer, IMapper mapper)
|
||||
public CRUDService(TCRUDRepository repository, IMapper mapper) : base(repository: repository, mapper: mapper)
|
||||
{
|
||||
_repository = repository;
|
||||
_mapper = mapper;
|
||||
|
||||
_keyPropertyInfo = typeof(TEntity).GetProperties()
|
||||
.FirstOrDefault(prop => Attribute.IsDefined(prop, typeof(KeyAttribute)));
|
||||
|
||||
_localizer = localizer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -46,35 +33,12 @@ namespace DigitalData.Core.Application
|
||||
/// </summary>
|
||||
/// <param name="createDto">The DTO to create an entity from.</param>
|
||||
/// <returns>A service result indicating success or failure, including the entity DTO.</returns>
|
||||
public virtual async Task<DataResult<TId>> CreateAsync(TCreateDto createDto)
|
||||
public virtual async Task<DataResult<TReadDto>> CreateAsync(TCreateDto createDto)
|
||||
{
|
||||
var entity = _mapper.MapOrThrow<TEntity>(createDto);
|
||||
var entity = _mapper.Map<TEntity>(createDto);
|
||||
var createdEntity = await _repository.CreateAsync(entity);
|
||||
return createdEntity is null ? Result.Fail<TId>() : Result.Success(KeyValueOf(createdEntity));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously reads an entity by its identifier and maps it to a read DTO.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to read.</param>
|
||||
/// <returns>A service result indicating success or failure, including the read DTO if successful.</returns>
|
||||
public virtual async Task<DataResult<TReadDto>> ReadByIdAsync(TId id)
|
||||
{
|
||||
var entity = await _repository.ReadByIdAsync(id);
|
||||
return entity is null
|
||||
? Result.Fail<TReadDto>().Message(_localizer[Key.EntityDoesNotExist])
|
||||
: Result.Success(_mapper.MapOrThrow<TReadDto>(entity));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously reads all entities and maps them to read DTOs.
|
||||
/// </summary>
|
||||
/// <returns>A service result including a collection of read DTOs.</returns>
|
||||
public virtual async Task<DataResult<IEnumerable<TReadDto>>> ReadAllAsync()
|
||||
{
|
||||
var entities = await _repository.ReadAllAsync();
|
||||
var readDto = _mapper.MapOrThrow<IEnumerable<TReadDto>>(entities);
|
||||
return Result.Success(readDto);
|
||||
var dto = _mapper.Map<TReadDto>(createdEntity);
|
||||
return createdEntity is null ? Result.Fail<TReadDto>() : Result.Success(dto);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -82,66 +46,18 @@ namespace DigitalData.Core.Application
|
||||
/// </summary>
|
||||
/// <param name="updateDto">The DTO to update an entity from.</param>
|
||||
/// <returns>A service message indicating success or failure.</returns>
|
||||
public virtual async Task<Result> UpdateAsync(TUpdateDto updateDto)
|
||||
public virtual async Task<Result> UpdateAsync<TUpdateDto>(TUpdateDto updateDto)
|
||||
{
|
||||
var entity = _mapper.MapOrThrow<TEntity>(updateDto);
|
||||
bool isUpdated = await _repository.UpdateAsync(entity);
|
||||
return isUpdated ? Result.Success() : Result.Fail().Message(_localizer[Key.UpdateFailed]);
|
||||
}
|
||||
var currentEntitiy = await _repository.ReadByIdAsync(updateDto.GetId<TId>());
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously deletes an entity by its identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to delete.</param>
|
||||
/// <returns>A service message indicating success or failure.</returns>
|
||||
public virtual async Task<Result> DeleteAsyncById(TId id)
|
||||
{
|
||||
TEntity? entity = await _repository.ReadByIdAsync(id);
|
||||
if (currentEntitiy is null)
|
||||
return Result.Fail().Notice(LogLevel.Warning, Flag.NotFound, $"{updateDto.GetIdOrDefault<TId>()} is not found in update process of {GetType()} entity.");
|
||||
|
||||
var entity = _mapper.Map(updateDto, currentEntitiy);
|
||||
|
||||
if (entity is null)
|
||||
return Result.Fail().Message(_localizer[Key.DeletionFailed], _localizer[Key.EntityDoesNotExist]);
|
||||
|
||||
bool isDeleted = await _repository.DeleteAsync(entity);
|
||||
return isDeleted ? Result.Success() : Result.Fail().Message(_localizer[Key.DeletionFailed]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously checks if an entity with the specified identifier exists.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to check.</param>
|
||||
/// <returns>A Task that represents the asynchronous operation. The task result contains a boolean value indicating whether the entity exists.</returns>
|
||||
public virtual async Task<bool> HasEntity(TId id)
|
||||
{
|
||||
var entity = await _repository.ReadByIdAsync(id);
|
||||
return entity is not null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the ID value of an entity based on the defined [Key] attribute.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity from which to extract the ID.</param>
|
||||
/// <returns>The ID of the entity.</returns>
|
||||
protected virtual TId KeyValueOf(TEntity entity)
|
||||
{
|
||||
if (_keyPropertyInfo is null)
|
||||
throw new InvalidOperationException($"No property with [Key] attribute found on {typeof(TEntity).Name} entity.");
|
||||
|
||||
object idObj = _keyPropertyInfo?.GetValue(entity) ?? throw new InvalidOperationException($"The ID property of {typeof(TEntity).Name} entity cannot be null.");
|
||||
|
||||
if (idObj is TId id)
|
||||
return id;
|
||||
else
|
||||
throw new InvalidCastException($"The ID of {typeof(TEntity).Name} entity must be type of {typeof(TId).Name}, but it is type of {idObj.GetType().Name}.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles exceptions that occur during CRUD operations, providing a structured string.
|
||||
/// </summary>
|
||||
/// <param name="ex">The exception that was caught during CRUD operations.</param>
|
||||
/// <returns>A <see cref="IServiceMessage"/> containing information about the failure, including a user-friendly error message and additional error details.</returns>
|
||||
public virtual string HandleException(Exception ex)
|
||||
{
|
||||
return $"An unexpected error occurred on the server side. Please inform the IT support team.\n{ex.GetType().Name}\n{ex.Message}";
|
||||
return await _repository.UpdateAsync(entity)
|
||||
? Result.Success()
|
||||
: Result.Fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using DigitalData.Core.Contracts.Infrastructure;
|
||||
using DigitalData.Core.Abstraction.Application;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.Configuration;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
@@ -14,57 +12,36 @@ namespace DigitalData.Core.Application
|
||||
public static class DIExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a basic CRUD service for a specific DTO and entity type to the service collection.
|
||||
/// Adds the directory search service to the <see cref="IServiceCollection"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDto">The DTO type the service operates on.</typeparam>
|
||||
/// <typeparam name="TEntity">The entity type corresponding to the DTO.</typeparam>
|
||||
/// <typeparam name="TId">The type of the entity's identifier.</typeparam>
|
||||
/// <typeparam name="TProfile">The AutoMapper profile type for configuring mappings between the DTO and the entity.</typeparam>
|
||||
/// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
|
||||
/// <param name="configureService">An optional action to configure additional services for the CRUD service.</param>
|
||||
/// <returns>The original <see cref="IServiceCollection"/> instance, allowing further configuration.</returns>
|
||||
public static IServiceCollection AddCleanBasicCRUDService<TCRUDRepository, TDto, TEntity, TId, TProfile>(this IServiceCollection services, Action<IServiceCollection>? configureService = null)
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TDto : class where TEntity : class where TProfile : Profile
|
||||
/// <param name="service">The <see cref="IServiceCollection"/> to add services to.</param>
|
||||
/// <param name="directorySearchOptions">
|
||||
/// Optional. An instance of <see cref="DirectorySearchOptions"/> to configure the directory search service.
|
||||
/// If not provided, the options need to be configured separately.
|
||||
/// </param>
|
||||
/// <returns>The updated <see cref="IServiceCollection"/>.</returns>
|
||||
/// <remarks>
|
||||
/// This method adds the necessary services for directory search functionality, including memory caching.
|
||||
/// If <paramref name="directorySearchOptions"/> is not provided, ensure to configure the options separately
|
||||
/// using the <see cref="IOptions{TOptions}"/> pattern.
|
||||
/// </remarks>
|
||||
public static IServiceCollection AddDirectorySearchService(this IServiceCollection service, IConfigurationSection directorySearchOptions)
|
||||
{
|
||||
services.AddScoped<IBasicCRUDService<TCRUDRepository, TDto, TEntity, TId>, BasicCRUDService<TCRUDRepository, TDto, TEntity, TId>>();
|
||||
configureService?.Invoke(services);
|
||||
|
||||
services.AddAutoMapper(typeof(TProfile).Assembly);
|
||||
|
||||
return services;
|
||||
return service.Configure<DirectorySearchOptions>(directorySearchOptions)
|
||||
.AddMemoryCache()
|
||||
.AddScoped<IDirectorySearchService, DirectorySearchService>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a CRUD service for managing create, read, update, and delete operations for a specific set of DTOs and an entity type to the service collection.
|
||||
/// Adds the JWT service to the <see cref="IServiceCollection"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TCRUDRepository">The repository type that provides CRUD operations for entities of type TEntity.</typeparam>
|
||||
/// <typeparam name="TCreateDto">The DTO type used for create operations.</typeparam>
|
||||
/// <typeparam name="TReadDto">The DTO type used for read operations.</typeparam>
|
||||
/// <typeparam name="TUpdateDto">The DTO type used for update operations.</typeparam>
|
||||
/// <typeparam name="TEntity">The entity type corresponding to the DTOs.</typeparam>
|
||||
/// <typeparam name="TId">The type of the entity's identifier.</typeparam>
|
||||
/// <typeparam name="TProfile">The AutoMapper profile type for configuring mappings between the DTOs and the entity.</typeparam>
|
||||
/// <typeparam name="TClaimValue">The type of the claim value used in the JWT token.</typeparam>
|
||||
/// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
|
||||
/// <param name="configureService">An optional action to configure additional services for the CRUD service.</param>
|
||||
/// <param name="tokenDescriptorFactory">A function that takes a claim value of type <typeparamref name="TClaimValue"/> and returns a <see cref="SecurityTokenDescriptor"/> used to configure the JWT token.</param>
|
||||
/// <returns>The original <see cref="IServiceCollection"/> instance, allowing further configuration.</returns>
|
||||
public static IServiceCollection AddCleanCRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId, TProfile>(this IServiceCollection services, Action<IServiceCollection>? configureService = null)
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TCreateDto : class where TReadDto : class where TUpdateDto : class where TEntity : class where TProfile : Profile
|
||||
{
|
||||
services.AddScoped<ICRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId>, CRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId>>();
|
||||
configureService?.Invoke(services);
|
||||
|
||||
services.AddAutoMapper(typeof(TProfile).Assembly);
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddDirectorySearchService(this IServiceCollection service)
|
||||
{
|
||||
service.AddMemoryCache();
|
||||
service.AddScoped<IDirectorySearchService, DirectorySearchService>();
|
||||
return service;
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// This method adds the necessary services for handling JWT tokens. The <paramref name="tokenDescriptorFactory"/> function is used to generate the <see cref="SecurityTokenDescriptor"/> which is essential for creating the JWT tokens.
|
||||
/// </remarks>
|
||||
public static IServiceCollection AddJWTService<TClaimValue>(this IServiceCollection services, Func<TClaimValue, SecurityTokenDescriptor> tokenDescriptorFactory)
|
||||
{
|
||||
return services.AddScoped<IJWTService<TClaimValue>, JWTService<TClaimValue>>(provider => new (tokenDescriptorFactory));
|
||||
|
||||
@@ -1,30 +1,61 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<Description>This package includes generic CRUD operations using Entity Framework Core, AutoMapper integration for object mapping, and additional services such as JWT handling and directory search functionality, adhering to Clean Architecture principles.</Description>
|
||||
<PackageId>DigitalData.Core.Application</PackageId>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>DigitalData.Core.Application</Product>
|
||||
<Copyright>Copyright 2024</Copyright>
|
||||
<PackageIcon>core_icon.png</PackageIcon>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
|
||||
<PackageTags>digital data core application clean architecture</PackageTags>
|
||||
<Version>3.4.0</Version>
|
||||
<AssemblyVersion>3.4.0</AssemblyVersion>
|
||||
<FileVersion>3.4.0</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="NewFolder\**" />
|
||||
<EmbeddedResource Remove="NewFolder\**" />
|
||||
<None Remove="NewFolder\**" />
|
||||
<None Include="..\Assets\core_icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.16" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
|
||||
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="7.0.1" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.5.1" />
|
||||
<PackageReference Include="System.Security.Cryptography.Cng" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
|
||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="9.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DigitalData.Core.Contracts\DigitalData.Core.Contracts.csproj" />
|
||||
<ProjectReference Include="..\DigitalData.Core.Abstraction.Application\DigitalData.Core.Abstraction.Application.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
31
DigitalData.Core.Application/DirectorySearchOptions.cs
Normal file
31
DigitalData.Core.Application/DirectorySearchOptions.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the options for configuring directory search operations.
|
||||
/// </summary>
|
||||
public class DirectorySearchOptions
|
||||
{
|
||||
//TODO: Merge with Root and rename as path
|
||||
/// <summary>
|
||||
/// Gets or initializes the name of the server to be used in the directory search.
|
||||
/// </summary>
|
||||
public required string ServerName { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or initializes the root directory path for the search.
|
||||
/// </summary>
|
||||
public required string Root { get; init; }
|
||||
|
||||
//TODO: Convert to timespan
|
||||
/// <summary>
|
||||
/// Gets or initializes the number of days before the user cache expires.
|
||||
/// </summary>
|
||||
public double? UserCacheExpirationDays { get; init; }
|
||||
|
||||
//TODO: Rename as CustomSearchFilters
|
||||
/// <summary>
|
||||
/// Gets or initializes the custom search filters to be applied during directory searches.
|
||||
/// </summary>
|
||||
public Dictionary<string, string> CustomSearchFilters { get; init; } = new();
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,14 @@
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.DirectoryServices;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.DirectoryServices.AccountManagement;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using DigitalData.Core.DTO;
|
||||
using Microsoft.Extensions.Options;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
using DigitalData.Core.Abstraction.Application;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
//TODO: rename as DirectorySearcher
|
||||
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
|
||||
public class DirectorySearchService : IDirectorySearchService
|
||||
{
|
||||
@@ -17,43 +16,75 @@ namespace DigitalData.Core.Application
|
||||
public string ServerName { get; }
|
||||
public string Root { get; }
|
||||
public string SearchRootPath { get; }
|
||||
private readonly DateTimeOffset _userCacheExpiration;
|
||||
private readonly DateTimeOffset? _userCacheExpiration;
|
||||
public Dictionary<string, string> CustomSearchFilters { get; }
|
||||
protected readonly IStringLocalizer _localizer;
|
||||
|
||||
public DirectorySearchService(IConfiguration configuration, ILogger<DirectorySearchService> logger, IMemoryCache memoryCache, IStringLocalizer localizer)
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DirectorySearchService"/> class.
|
||||
/// </summary>
|
||||
/// <param name="options">The options for directory search.</param>
|
||||
/// <param name="memoryCache">The memory cache.</param>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Thrown if the server name or root directory is not configured.
|
||||
/// </exception>
|
||||
public DirectorySearchService(IOptions<DirectorySearchOptions> options, IMemoryCache memoryCache)
|
||||
{
|
||||
_memoryCache = memoryCache;
|
||||
|
||||
ServerName = configuration["DirectorySearch:ServerName"] ?? throw new InvalidOperationException("The server name for directory search is not configured. Please specify the 'DirectorySearch:ServerName' in the configuration.");
|
||||
var dirSearchOptions = options.Value;
|
||||
|
||||
Root = configuration["DirectorySearch:Root"] ?? throw new InvalidOperationException("The root for directory search is not configured. Please specify the 'DirectorySearch:Root' in the configuration.");
|
||||
ServerName = dirSearchOptions.ServerName;
|
||||
|
||||
Root = dirSearchOptions.Root;
|
||||
|
||||
SearchRootPath = $"LDAP://{ServerName}/{Root}";
|
||||
|
||||
CustomSearchFilters = dirSearchOptions.CustomSearchFilters;
|
||||
|
||||
var customSearchFiltersSection = configuration.GetSection("DirectorySearch:CustomSearchFilters");
|
||||
CustomSearchFilters = customSearchFiltersSection.Get<Dictionary<string, string>>() ?? new();
|
||||
|
||||
var dayCounts = configuration.GetValue<int>("DirectorySearch:UserCacheExpirationDays");
|
||||
if (dayCounts == default)
|
||||
_userCacheExpiration = default;
|
||||
else
|
||||
_userCacheExpiration = DateTimeOffset.Now.Date.AddDays(dayCounts);
|
||||
|
||||
_localizer = localizer;
|
||||
if(dirSearchOptions.UserCacheExpirationDays is double expirationDays)
|
||||
_userCacheExpiration = DateTimeOffset.Now.Date.AddDays(expirationDays);
|
||||
}
|
||||
|
||||
public bool ValidateCredentials(string dirEntryUsername, string dirEntryPassword)
|
||||
/// <summary>
|
||||
/// Creates the connections to the server and returns a Boolean value that specifies
|
||||
/// whether the specified username and password are valid.
|
||||
/// </summary>
|
||||
/// <param name="userName">The username that is validated on the server. See the Remarks section
|
||||
/// for more information on the format of userName.</param>
|
||||
/// <param name="password">The password that is validated on the server.</param>
|
||||
/// <returns>True if the credentials are valid; otherwise, false.</returns>
|
||||
public bool ValidateCredentials(string userName, string password)
|
||||
{
|
||||
using var context = new PrincipalContext(ContextType.Domain, ServerName, Root);
|
||||
return context.ValidateCredentials(dirEntryUsername, dirEntryPassword);
|
||||
return context.ValidateCredentials(userName, password);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the connections to the server asynchronously and returns a Boolean value that specifies
|
||||
/// whether the specified username and password are valid.
|
||||
/// </summary>
|
||||
/// <param name="userName">The username that is validated on the server. See the Remarks section
|
||||
/// for more information on the format of userName.</param>
|
||||
/// <param name="password">The password that is validated on the server.</param>
|
||||
/// <returns>True if the credentials are valid; otherwise, false.</returns>
|
||||
public Task<bool> ValidateCredentialsAsync(string userName, string password) => Task.Run(()
|
||||
=> ValidateCredentials(userName, password));
|
||||
|
||||
//TODO: remove unnecessary DataResult
|
||||
/// <summary>
|
||||
/// Finds all directory entries matching the specified filter.
|
||||
/// </summary>
|
||||
/// <param name="searchRoot">The search root.</param>
|
||||
/// <param name="filter">The search filter.</param>
|
||||
/// <param name="searchScope">The search scope.</param>
|
||||
/// <param name="sizeLimit">The size limit.</param>
|
||||
/// <param name="properties">The properties to load.</param>
|
||||
/// <returns>A <see cref="DataResult{T}"/> containing the results.</returns>
|
||||
public DataResult<IEnumerable<ResultPropertyCollection>> FindAll(DirectoryEntry searchRoot, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties)
|
||||
{
|
||||
List<ResultPropertyCollection> list = new();
|
||||
|
||||
var searcher = new DirectorySearcher()
|
||||
using var searcher = new DirectorySearcher()
|
||||
{
|
||||
Filter = filter,
|
||||
SearchScope = searchScope,
|
||||
@@ -78,29 +109,70 @@ namespace DigitalData.Core.Application
|
||||
return Result.Success<IEnumerable<ResultPropertyCollection>>(list);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds all directory entries matching the specified filter asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="searchRoot">The search root.</param>
|
||||
/// <param name="filter">The search filter.</param>
|
||||
/// <param name="searchScope">The search scope.</param>
|
||||
/// <param name="sizeLimit">The size limit.</param>
|
||||
/// <param name="properties">The properties to load.</param>
|
||||
/// <returns>A <see cref="DataResult{T}"/> containing the results.</returns>
|
||||
public Task<DataResult<IEnumerable<ResultPropertyCollection>>> FindAllAsync(DirectoryEntry searchRoot, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties) => Task.Run(()
|
||||
=> FindAll(searchRoot, filter, searchScope, sizeLimit, properties));
|
||||
|
||||
/// <summary>
|
||||
/// Finds all directory entries matching the specified filter, using the user cache.
|
||||
/// </summary>
|
||||
/// <param name="username">The username.</param>
|
||||
/// <param name="filter">The search filter.</param>
|
||||
/// <param name="searchScope">The search scope.</param>
|
||||
/// <param name="sizeLimit">The size limit.</param>
|
||||
/// <param name="properties">The properties to load.</param>
|
||||
/// <returns>A <see cref="DataResult{T}"/> containing the results.</returns>
|
||||
public DataResult<IEnumerable<ResultPropertyCollection>> FindAllByUserCache(string username, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties)
|
||||
{
|
||||
List<ResultPropertyCollection> list = new();
|
||||
|
||||
_memoryCache.TryGetValue(username, out DirectoryEntry? searchRoot);
|
||||
|
||||
if (searchRoot is null)
|
||||
return Result.Fail<IEnumerable<ResultPropertyCollection>>().Message(_localizer[Key.DirSearcherDisconnected]);
|
||||
return Result.Fail<IEnumerable<ResultPropertyCollection>>();
|
||||
|
||||
return FindAll(searchRoot, filter, searchScope, sizeLimit, properties);
|
||||
}
|
||||
|
||||
public void SetSearchRootCache(string dirEntryUsername, string dirEntryPassword)
|
||||
/// <summary>
|
||||
/// Finds all directory entries matching the specified filter asynchronously, using the user cache.
|
||||
/// </summary>
|
||||
/// <param name="username">The username.</param>
|
||||
/// <param name="filter">The search filter.</param>
|
||||
/// <param name="searchScope">The search scope.</param>
|
||||
/// <param name="sizeLimit">The size limit.</param>
|
||||
/// <param name="properties">The properties to load.</param>
|
||||
/// <returns>A <see cref="DataResult{T}"/> containing the results.</returns>
|
||||
public Task<DataResult<IEnumerable<ResultPropertyCollection>>> FindAllByUserCacheAsync(string username, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties) => Task.Run(()
|
||||
=> FindAllByUserCache(username, filter, searchScope, sizeLimit, properties));
|
||||
|
||||
/// <summary>
|
||||
/// Sets the search root in the cache.
|
||||
/// </summary>
|
||||
/// <param name="username">The directory entry username.</param>
|
||||
/// <param name="password">The directory entry password.</param>
|
||||
public void SetSearchRootCache(string username, string password)
|
||||
{
|
||||
if (_userCacheExpiration == default)
|
||||
_memoryCache.Set(key: dirEntryUsername, new DirectoryEntry(path: SearchRootPath, username: dirEntryUsername, password: dirEntryPassword));
|
||||
if (_userCacheExpiration is DateTimeOffset cacheExpiration)
|
||||
_memoryCache.Set(key: username, new DirectoryEntry(path: SearchRootPath, username: username, password: password), absoluteExpiration: cacheExpiration);
|
||||
else
|
||||
_memoryCache.Set(key: dirEntryUsername, new DirectoryEntry(path: SearchRootPath, username: dirEntryUsername, password: dirEntryPassword), absoluteExpiration: _userCacheExpiration);
|
||||
_memoryCache.Set(key: username, new DirectoryEntry(path: SearchRootPath, username: username, password: password));
|
||||
}
|
||||
|
||||
public DirectoryEntry? GetSearchRootCache(string dirEntryUsername)
|
||||
/// <summary>
|
||||
/// Gets the search root from the cache.
|
||||
/// </summary>
|
||||
/// <param name="username">The directory entry username.</param>
|
||||
/// <returns>The cached <see cref="DirectoryEntry"/> if found; otherwise, null.</returns>
|
||||
public DirectoryEntry? GetSearchRootCache(string username)
|
||||
{
|
||||
_memoryCache.TryGetValue(dirEntryUsername, out DirectoryEntry? root);
|
||||
_memoryCache.TryGetValue(username, out DirectoryEntry? root);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +1,63 @@
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using DigitalData.Core.Abstraction.Application;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
namespace DigitalData.Core.Application;
|
||||
|
||||
/// <summary>
|
||||
/// Implements the <see cref="IJWTService{TClaimValue}"/> interface to manage JWT operations for claims of type <typeparamref name="TClaimValue"/>.
|
||||
/// </summary>
|
||||
public class JWTService<TClaimValue> : IJWTService<TClaimValue>
|
||||
{
|
||||
private readonly Func<TClaimValue, SecurityTokenDescriptor> _factory;
|
||||
|
||||
/// <summary>
|
||||
/// Implements the <see cref="IJWTService{TClaimValue}"/> interface to manage JWT operations for claims of type <typeparamref name="TClaimValue"/>.
|
||||
/// Initializes a new instance of the <see cref="JWTService{TClaimValue}"/> class.
|
||||
/// </summary>
|
||||
public class JWTService<TClaimValue> : IJWTService<TClaimValue>
|
||||
/// <param name="tokenDescriptorFactory">A factory function to produce <see cref="SecurityTokenDescriptor"/> based on the claim value.</param>
|
||||
public JWTService(Func<TClaimValue, SecurityTokenDescriptor> tokenDescriptorFactory)
|
||||
{
|
||||
private readonly Func<TClaimValue, SecurityTokenDescriptor> _factory;
|
||||
_factory = tokenDescriptorFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JWTService{TClaimValue}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="tokenDescriptorFactory">A factory function to produce <see cref="SecurityTokenDescriptor"/> based on the claim value.</param>
|
||||
public JWTService(Func<TClaimValue, SecurityTokenDescriptor> tokenDescriptorFactory)
|
||||
{
|
||||
_factory = tokenDescriptorFactory;
|
||||
}
|
||||
/// <summary>
|
||||
/// Generates a symmetric security key with the specified byte size.
|
||||
/// </summary>
|
||||
/// <param name="byteSize">The size of the security key in bytes. Default is 32 bytes.</param>
|
||||
/// <returns>A new instance of <see cref="SymmetricSecurityKey"/>.</returns>
|
||||
public static SymmetricSecurityKey GenerateSecurityKey(int byteSize = 32)
|
||||
{
|
||||
using var rng = RandomNumberGenerator.Create();
|
||||
var randomBytes = new byte[byteSize];
|
||||
rng.GetBytes(randomBytes);
|
||||
var securityKey = new SymmetricSecurityKey(randomBytes);
|
||||
|
||||
/// <summary>
|
||||
/// Generates a symmetric security key with the specified byte size.
|
||||
/// </summary>
|
||||
/// <param name="byteSize">The size of the security key in bytes. Default is 32 bytes.</param>
|
||||
/// <returns>A new instance of <see cref="SymmetricSecurityKey"/>.</returns>
|
||||
public static SymmetricSecurityKey GenerateSecurityKey(int byteSize = 32)
|
||||
{
|
||||
using var rng = RandomNumberGenerator.Create();
|
||||
var randomBytes = new byte[byteSize];
|
||||
rng.GetBytes(randomBytes);
|
||||
var securityKey = new SymmetricSecurityKey(randomBytes);
|
||||
return securityKey;
|
||||
}
|
||||
|
||||
return securityKey;
|
||||
}
|
||||
/// <summary>
|
||||
/// Generates a JWT for the specified claim value.
|
||||
/// </summary>
|
||||
/// <param name="claimValue">The claim value to encode in the JWT.</param>
|
||||
/// <returns>A JWT as a string.</returns>
|
||||
public string GenerateToken(TClaimValue claimValue)
|
||||
{
|
||||
var tokenDescriptor = _factory(claimValue);
|
||||
|
||||
/// <summary>
|
||||
/// Generates a JWT for the specified claim value.
|
||||
/// </summary>
|
||||
/// <param name="claimValue">The claim value to encode in the JWT.</param>
|
||||
/// <returns>A JWT as a string.</returns>
|
||||
public string GenerateToken(TClaimValue claimValue)
|
||||
{
|
||||
var tokenDescriptor = _factory(claimValue);
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
var token = tokenHandler.CreateToken(tokenDescriptor);
|
||||
return tokenHandler.WriteToken(token);
|
||||
}
|
||||
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
var token = tokenHandler.CreateToken(tokenDescriptor);
|
||||
return tokenHandler.WriteToken(token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads and validates a security token from a string representation.
|
||||
/// </summary>
|
||||
/// <param name="token">The JWT to read.</param>
|
||||
/// <returns>A <see cref="JwtSecurityToken"/> if the token is valid; otherwise, null.</returns>
|
||||
public JwtSecurityToken? ReadSecurityToken(string token)
|
||||
{
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
return tokenHandler.CanReadToken(token) ? tokenHandler.ReadToken(token) as JwtSecurityToken : null;
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads and validates a security token from a string representation.
|
||||
/// </summary>
|
||||
/// <param name="token">The JWT to read.</param>
|
||||
/// <returns>A <see cref="JwtSecurityToken"/> if the token is valid; otherwise, null.</returns>
|
||||
public JwtSecurityToken? ReadSecurityToken(string token)
|
||||
{
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
return tokenHandler.CanReadToken(token) ? tokenHandler.ReadToken(token) as JwtSecurityToken : null;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
namespace DigitalData.Core.Application
|
||||
namespace DigitalData.Core.Application;
|
||||
|
||||
[Obsolete("Use MediatR")]
|
||||
public static class Key
|
||||
{
|
||||
public static class Key
|
||||
{
|
||||
public static readonly string EntityDoesNotExist = "EntityDoesNotExist";
|
||||
public static readonly string ReadFailed = "ReadFailed";
|
||||
public static readonly string UpdateFailed = "UpdateFailed";
|
||||
public static readonly string DeletionFailed = "DeletionFailed";
|
||||
public static readonly string DirSearcherDisconnected = "DirSearcherDisconnected";
|
||||
}
|
||||
public static readonly string EntityDoesNotExist = "EntityDoesNotExist";
|
||||
public static readonly string ReadFailed = "ReadFailed";
|
||||
public static readonly string UpdateFailed = "UpdateFailed";
|
||||
public static readonly string DeletionFailed = "DeletionFailed";
|
||||
public static readonly string DirSearcherDisconnected = "DirSearcherDisconnected";
|
||||
}
|
||||
78
DigitalData.Core.Application/ReadService.cs
Normal file
78
DigitalData.Core.Application/ReadService.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Abstraction.Application;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
|
||||
namespace DigitalData.Core.Application;
|
||||
|
||||
/// <summary>
|
||||
/// Provides generic Read (Read and Delete) operations for a specified type of entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="TReadDto">The DTO type for read operations.</typeparam>
|
||||
/// <typeparam name="TEntity">The entity type.</typeparam>
|
||||
/// <typeparam name="TId">The type of the identifier for the entity.</typeparam>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class ReadService<TCRUDRepository, TReadDto, TEntity, TId> : IReadService<TReadDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TReadDto : class where TEntity : class
|
||||
{
|
||||
protected readonly TCRUDRepository _repository;
|
||||
protected readonly IMapper _mapper;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CRUDService class with the specified repository, translation service, and mapper.
|
||||
/// </summary>
|
||||
/// <param name="repository">The CRUD repository for accessing the database.</param>
|
||||
/// <param name="mapper">The AutoMapper instance for mapping between DTOs and entity objects.</param>
|
||||
public ReadService(TCRUDRepository repository, IMapper mapper)
|
||||
{
|
||||
_repository = repository;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously reads an entity by its identifier and maps it to a read DTO.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to read.</param>
|
||||
/// <returns>A service result indicating success or failure, including the read DTO if successful.</returns>
|
||||
public virtual async Task<DataResult<TReadDto>> ReadByIdAsync(TId id)
|
||||
{
|
||||
var entity = await _repository.ReadByIdAsync(id);
|
||||
return entity is null
|
||||
? Result.Fail<TReadDto>()
|
||||
: Result.Success(_mapper.Map<TReadDto>(entity));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously reads all entities and maps them to read DTOs.
|
||||
/// </summary>
|
||||
/// <returns>A service result including a collection of read DTOs.</returns>
|
||||
public virtual async Task<DataResult<IEnumerable<TReadDto>>> ReadAllAsync()
|
||||
{
|
||||
var entities = await _repository.ReadAllAsync();
|
||||
var readDto = _mapper.Map<IEnumerable<TReadDto>>(entities);
|
||||
return Result.Success(readDto);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously deletes an entity by its identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to delete.</param>
|
||||
/// <returns>A service message indicating success or failure.</returns>
|
||||
public virtual async Task<Result> DeleteAsyncById(TId id)
|
||||
{
|
||||
TEntity? entity = await _repository.ReadByIdAsync(id);
|
||||
|
||||
if (entity is null)
|
||||
return Result.Fail();
|
||||
|
||||
bool isDeleted = await _repository.DeleteAsync(entity);
|
||||
return isDeleted ? Result.Success() : Result.Fail();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously checks if an entity with the specified identifier exists.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to check.</param>
|
||||
/// <returns>A Task that represents the asynchronous operation. The task result contains a boolean value indicating whether the entity exists.</returns>
|
||||
public virtual async Task<bool> HasEntity(TId id) => await _repository.CountAsync(id) > 0;
|
||||
}
|
||||
Binary file not shown.
@@ -1,642 +0,0 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v7.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v7.0": {
|
||||
"DigitalData.Core.Application/1.0.0": {
|
||||
"dependencies": {
|
||||
"AutoMapper": "13.0.1",
|
||||
"Microsoft.Extensions.Caching.Abstractions": "7.0.0",
|
||||
"Microsoft.Extensions.Configuration": "7.0.0",
|
||||
"Microsoft.Extensions.Logging": "7.0.0",
|
||||
"System.DirectoryServices.AccountManagement": "7.0.1",
|
||||
"System.IdentityModel.Tokens.Jwt": "7.5.1",
|
||||
"System.Security.Cryptography.Cng": "5.0.0",
|
||||
"WebCore.Contracts": "1.0.1",
|
||||
"DigitalData.Core.Contracts": "1.0.1.0"
|
||||
},
|
||||
"runtime": {
|
||||
"DigitalData.Core.Application.dll": {}
|
||||
}
|
||||
},
|
||||
"AutoMapper/13.0.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Options": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/AutoMapper.dll": {
|
||||
"assemblyVersion": "13.0.0.0",
|
||||
"fileVersion": "13.0.1.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Caching.Abstractions/7.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Caching.Abstractions.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Caching.Memory/7.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Caching.Abstractions": "7.0.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "7.0.0",
|
||||
"Microsoft.Extensions.Options": "7.0.0",
|
||||
"Microsoft.Extensions.Primitives": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Caching.Memory.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration/7.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "7.0.0",
|
||||
"Microsoft.Extensions.Primitives": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Configuration.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions/7.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Configuration.Abstractions.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder/7.0.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Configuration.Binder.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.423.11508"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection/7.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions/7.0.0": {
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging/7.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "7.0.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "7.0.0",
|
||||
"Microsoft.Extensions.Options": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Logging.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions/7.0.0": {
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Logging.Abstractions.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Options/7.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0",
|
||||
"Microsoft.Extensions.Primitives": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Options.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives/7.0.0": {
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Primitives.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.IdentityModel.Abstractions/7.5.1": {
|
||||
"runtime": {
|
||||
"lib/net6.0/Microsoft.IdentityModel.Abstractions.dll": {
|
||||
"assemblyVersion": "7.5.1.0",
|
||||
"fileVersion": "7.5.1.50405"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.IdentityModel.JsonWebTokens/7.5.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.IdentityModel.Tokens": "7.5.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/Microsoft.IdentityModel.JsonWebTokens.dll": {
|
||||
"assemblyVersion": "7.5.1.0",
|
||||
"fileVersion": "7.5.1.50405"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.IdentityModel.Logging/7.5.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.IdentityModel.Abstractions": "7.5.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/Microsoft.IdentityModel.Logging.dll": {
|
||||
"assemblyVersion": "7.5.1.0",
|
||||
"fileVersion": "7.5.1.50405"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.IdentityModel.Tokens/7.5.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.IdentityModel.Logging": "7.5.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/Microsoft.IdentityModel.Tokens.dll": {
|
||||
"assemblyVersion": "7.5.1.0",
|
||||
"fileVersion": "7.5.1.50405"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Win32.SystemEvents/7.0.0": {
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Win32.SystemEvents.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net7.0/Microsoft.Win32.SystemEvents.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Configuration.ConfigurationManager/7.0.0": {
|
||||
"dependencies": {
|
||||
"System.Diagnostics.EventLog": "7.0.0",
|
||||
"System.Security.Cryptography.ProtectedData": "7.0.0",
|
||||
"System.Security.Permissions": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/System.Configuration.ConfigurationManager.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.EventLog/7.0.0": {
|
||||
"runtime": {
|
||||
"lib/net7.0/System.Diagnostics.EventLog.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net7.0/System.Diagnostics.EventLog.Messages.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "0.0.0.0"
|
||||
},
|
||||
"runtimes/win/lib/net7.0/System.Diagnostics.EventLog.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.DirectoryServices/7.0.1": {
|
||||
"dependencies": {
|
||||
"System.Security.Permissions": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/System.DirectoryServices.dll": {
|
||||
"assemblyVersion": "4.0.0.0",
|
||||
"fileVersion": "7.0.323.6910"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net7.0/System.DirectoryServices.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "4.0.0.0",
|
||||
"fileVersion": "7.0.323.6910"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.DirectoryServices.AccountManagement/7.0.1": {
|
||||
"dependencies": {
|
||||
"System.Configuration.ConfigurationManager": "7.0.0",
|
||||
"System.DirectoryServices": "7.0.1",
|
||||
"System.DirectoryServices.Protocols": "7.0.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/System.DirectoryServices.AccountManagement.dll": {
|
||||
"assemblyVersion": "4.0.0.0",
|
||||
"fileVersion": "7.0.1123.42427"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net7.0/System.DirectoryServices.AccountManagement.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "4.0.0.0",
|
||||
"fileVersion": "7.0.1123.42427"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.DirectoryServices.Protocols/7.0.1": {
|
||||
"runtime": {
|
||||
"lib/net7.0/System.DirectoryServices.Protocols.dll": {
|
||||
"assemblyVersion": "7.0.0.1",
|
||||
"fileVersion": "7.0.723.27404"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/linux/lib/net7.0/System.DirectoryServices.Protocols.dll": {
|
||||
"rid": "linux",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.1",
|
||||
"fileVersion": "7.0.723.27404"
|
||||
},
|
||||
"runtimes/osx/lib/net7.0/System.DirectoryServices.Protocols.dll": {
|
||||
"rid": "osx",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.1",
|
||||
"fileVersion": "7.0.723.27404"
|
||||
},
|
||||
"runtimes/win/lib/net7.0/System.DirectoryServices.Protocols.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.1",
|
||||
"fileVersion": "7.0.723.27404"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Drawing.Common/7.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Win32.SystemEvents": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/System.Drawing.Common.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net7.0/System.Drawing.Common.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Formats.Asn1/5.0.0": {},
|
||||
"System.IdentityModel.Tokens.Jwt/7.5.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.IdentityModel.JsonWebTokens": "7.5.1",
|
||||
"Microsoft.IdentityModel.Tokens": "7.5.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/System.IdentityModel.Tokens.Jwt.dll": {
|
||||
"assemblyVersion": "7.5.1.0",
|
||||
"fileVersion": "7.5.1.50405"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Security.Cryptography.Cng/5.0.0": {
|
||||
"dependencies": {
|
||||
"System.Formats.Asn1": "5.0.0"
|
||||
}
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData/7.0.0": {
|
||||
"runtime": {
|
||||
"lib/net7.0/System.Security.Cryptography.ProtectedData.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net7.0/System.Security.Cryptography.ProtectedData.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Security.Permissions/7.0.0": {
|
||||
"dependencies": {
|
||||
"System.Windows.Extensions": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/System.Security.Permissions.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Windows.Extensions/7.0.0": {
|
||||
"dependencies": {
|
||||
"System.Drawing.Common": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/System.Windows.Extensions.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net7.0/System.Windows.Extensions.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"WebCore.Contracts/1.0.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Caching.Memory": "7.0.0",
|
||||
"Microsoft.Extensions.Configuration.Binder": "7.0.4",
|
||||
"System.DirectoryServices": "7.0.1",
|
||||
"System.DirectoryServices.AccountManagement": "7.0.1",
|
||||
"System.IdentityModel.Tokens.Jwt": "7.5.1"
|
||||
},
|
||||
"runtime": {
|
||||
"DigitalData.Core.Contracts.dll": {}
|
||||
}
|
||||
},
|
||||
"DigitalData.Core.Contracts/1.0.1.0": {
|
||||
"runtime": {
|
||||
"DigitalData.Core.Contracts.dll": {
|
||||
"assemblyVersion": "1.0.1.0",
|
||||
"fileVersion": "1.0.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"DigitalData.Core.Application/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"AutoMapper/13.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-/Fx1SbJ16qS7dU4i604Sle+U9VLX+WSNVJggk6MupKVkYvvBm4XqYaeFuf67diHefHKHs50uQIS2YEDFhPCakQ==",
|
||||
"path": "automapper/13.0.1",
|
||||
"hashPath": "automapper.13.0.1.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Caching.Abstractions/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-IeimUd0TNbhB4ded3AbgBLQv2SnsiVugDyGV1MvspQFVlA07nDC7Zul7kcwH5jWN3JiTcp/ySE83AIJo8yfKjg==",
|
||||
"path": "microsoft.extensions.caching.abstractions/7.0.0",
|
||||
"hashPath": "microsoft.extensions.caching.abstractions.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Caching.Memory/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-xpidBs2KCE2gw1JrD0quHE72kvCaI3xFql5/Peb2GRtUuZX+dYPoK/NTdVMiM67Svym0M0Df9A3xyU0FbMQhHw==",
|
||||
"path": "microsoft.extensions.caching.memory/7.0.0",
|
||||
"hashPath": "microsoft.extensions.caching.memory.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Configuration/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-tldQUBWt/xeH2K7/hMPPo5g8zuLc3Ro9I5d4o/XrxvxOCA2EZBtW7bCHHTc49fcBtvB8tLAb/Qsmfrq+2SJ4vA==",
|
||||
"path": "microsoft.extensions.configuration/7.0.0",
|
||||
"hashPath": "microsoft.extensions.configuration.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-f34u2eaqIjNO9YLHBz8rozVZ+TcFiFs0F3r7nUJd7FRkVSxk8u4OpoK226mi49MwexHOR2ibP9MFvRUaLilcQQ==",
|
||||
"path": "microsoft.extensions.configuration.abstractions/7.0.0",
|
||||
"hashPath": "microsoft.extensions.configuration.abstractions.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder/7.0.4": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-8+XPvJnHZsYgHOQlcMuQe7QNF5KdVKHH1F/wW3nd8/u81Gk/XFAYMDP0Lpz18h7/AM95M662vvqMorcYxCBB4w==",
|
||||
"path": "microsoft.extensions.configuration.binder/7.0.4",
|
||||
"hashPath": "microsoft.extensions.configuration.binder.7.0.4.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-elNeOmkeX3eDVG6pYVeV82p29hr+UKDaBhrZyWvWLw/EVZSYEkZlQdkp0V39k/Xehs2Qa0mvoCvkVj3eQxNQ1Q==",
|
||||
"path": "microsoft.extensions.dependencyinjection/7.0.0",
|
||||
"hashPath": "microsoft.extensions.dependencyinjection.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-h3j/QfmFN4S0w4C2A6X7arXij/M/OVw3uQHSOFxnND4DyAzO1F9eMX7Eti7lU/OkSthEE0WzRsfT/Dmx86jzCw==",
|
||||
"path": "microsoft.extensions.dependencyinjection.abstractions/7.0.0",
|
||||
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Logging/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Nw2muoNrOG5U5qa2ZekXwudUn2BJcD41e65zwmDHb1fQegTX66UokLWZkJRpqSSHXDOWZ5V0iqhbxOEky91atA==",
|
||||
"path": "microsoft.extensions.logging/7.0.0",
|
||||
"hashPath": "microsoft.extensions.logging.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-kmn78+LPVMOWeITUjIlfxUPDsI0R6G0RkeAMBmQxAJ7vBJn4q2dTva7pWi65ceN5vPGjJ9q/Uae2WKgvfktJAw==",
|
||||
"path": "microsoft.extensions.logging.abstractions/7.0.0",
|
||||
"hashPath": "microsoft.extensions.logging.abstractions.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Options/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-lP1yBnTTU42cKpMozuafbvNtQ7QcBjr/CcK3bYOGEMH55Fjt+iecXjT6chR7vbgCMqy3PG3aNQSZgo/EuY/9qQ==",
|
||||
"path": "microsoft.extensions.options/7.0.0",
|
||||
"hashPath": "microsoft.extensions.options.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Primitives/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-um1KU5kxcRp3CNuI8o/GrZtD4AIOXDk+RLsytjZ9QPok3ttLUelLKpilVPuaFT3TFjOhSibUAso0odbOaCDj3Q==",
|
||||
"path": "microsoft.extensions.primitives/7.0.0",
|
||||
"hashPath": "microsoft.extensions.primitives.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.IdentityModel.Abstractions/7.5.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-PT16ZFbPIiMsYv07oy3zOjqUOJ7xutGBkJTOX0+IbNyU6+O6X7aIxjq9EaSSRLWbekRgamgtmfg8Xjw6A6Ua9g==",
|
||||
"path": "microsoft.identitymodel.abstractions/7.5.1",
|
||||
"hashPath": "microsoft.identitymodel.abstractions.7.5.1.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.IdentityModel.JsonWebTokens/7.5.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-93CGSa8RPdZU8zfvA3nf9NGKUqEnQrE12VzYlMqKh72ddhzusosqLNEUgH/YhFWBLRFOnY1RCgHMV7pR+sAx2w==",
|
||||
"path": "microsoft.identitymodel.jsonwebtokens/7.5.1",
|
||||
"hashPath": "microsoft.identitymodel.jsonwebtokens.7.5.1.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.IdentityModel.Logging/7.5.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-PnpAQX20BAiDIPYmWUyQSlEaWD8BLXzHpiDGTCT568Cs0ReOeyzNe401LzCeiv6ilug/KefVeV1CeqtCHTo8dw==",
|
||||
"path": "microsoft.identitymodel.logging/7.5.1",
|
||||
"hashPath": "microsoft.identitymodel.logging.7.5.1.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.IdentityModel.Tokens/7.5.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Q3DKpyFViP84IUlTFKH/zIkswIrmSh2Vd/eFDo4wlOHy4DYxoweZEEw4kDEiKt9VCX6o7SddK3HK2xDYyFpexA==",
|
||||
"path": "microsoft.identitymodel.tokens/7.5.1",
|
||||
"hashPath": "microsoft.identitymodel.tokens.7.5.1.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Win32.SystemEvents/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-2nXPrhdAyAzir0gLl8Yy8S5Mnm/uBSQQA7jEsILOS1MTyS7DbmV1NgViMtvV1sfCD1ebITpNwb1NIinKeJgUVQ==",
|
||||
"path": "microsoft.win32.systemevents/7.0.0",
|
||||
"hashPath": "microsoft.win32.systemevents.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Configuration.ConfigurationManager/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-WvRUdlL1lB0dTRZSs5XcQOd5q9MYNk90GkbmRmiCvRHThWiojkpGqWdmEDJdXyHbxG/BhE5hmVbMfRLXW9FJVA==",
|
||||
"path": "system.configuration.configurationmanager/7.0.0",
|
||||
"hashPath": "system.configuration.configurationmanager.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Diagnostics.EventLog/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-eUDP47obqQm3SFJfP6z+Fx2nJ4KKTQbXB4Q9Uesnzw9SbYdhjyoGXuvDn/gEmFY6N5Z3bFFbpAQGA7m6hrYJCw==",
|
||||
"path": "system.diagnostics.eventlog/7.0.0",
|
||||
"hashPath": "system.diagnostics.eventlog.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.DirectoryServices/7.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Z4FVdUJEVXbf7/f/hU6cFZDtxN5ozUVKJMzXoHmC+GCeTcqzlxqmWtxurejxG3K+kZ6H0UKwNshoK1CYnmJ1sg==",
|
||||
"path": "system.directoryservices/7.0.1",
|
||||
"hashPath": "system.directoryservices.7.0.1.nupkg.sha512"
|
||||
},
|
||||
"System.DirectoryServices.AccountManagement/7.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-UNytHYwA5IF55WQhashsMG57ize83JUGJxD8YJlOyO9ZlMTOD4Nt7y+A6mvmrU/swDoYWaVL+TNwE6hk9lyvbA==",
|
||||
"path": "system.directoryservices.accountmanagement/7.0.1",
|
||||
"hashPath": "system.directoryservices.accountmanagement.7.0.1.nupkg.sha512"
|
||||
},
|
||||
"System.DirectoryServices.Protocols/7.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-t9hsL+UYRzNs30pnT2Tdx6ngX8McFUjru0a0ekNgu/YXfkXN+dx5OvSEv0/p7H2q3pdJLH7TJPWX7e55J8QB9A==",
|
||||
"path": "system.directoryservices.protocols/7.0.1",
|
||||
"hashPath": "system.directoryservices.protocols.7.0.1.nupkg.sha512"
|
||||
},
|
||||
"System.Drawing.Common/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-KIX+oBU38pxkKPxvLcLfIkOV5Ien8ReN78wro7OF5/erwcmortzeFx+iBswlh2Vz6gVne0khocQudGwaO1Ey6A==",
|
||||
"path": "system.drawing.common/7.0.0",
|
||||
"hashPath": "system.drawing.common.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Formats.Asn1/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-MTvUIktmemNB+El0Fgw9egyqT9AYSIk6DTJeoDSpc3GIHxHCMo8COqkWT1mptX5tZ1SlQ6HJZ0OsSvMth1c12w==",
|
||||
"path": "system.formats.asn1/5.0.0",
|
||||
"hashPath": "system.formats.asn1.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.IdentityModel.Tokens.Jwt/7.5.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-UUw+E0R73lZLlXgneYIJQxNs1kfbcxjVzw64JQyiwjqCd4HMpAbjn+xRo86QZT84uHq8/MkqvfH82tgjgPzpuw==",
|
||||
"path": "system.identitymodel.tokens.jwt/7.5.1",
|
||||
"hashPath": "system.identitymodel.tokens.jwt.7.5.1.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Cryptography.Cng/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-jIMXsKn94T9JY7PvPq/tMfqa6GAaHpElRDpmG+SuL+D3+sTw2M8VhnibKnN8Tq+4JqbPJ/f+BwtLeDMEnzAvRg==",
|
||||
"path": "system.security.cryptography.cng/5.0.0",
|
||||
"hashPath": "system.security.cryptography.cng.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-xSPiLNlHT6wAHtugASbKAJwV5GVqQK351crnILAucUioFqqieDN79evO1rku1ckt/GfjIn+b17UaSskoY03JuA==",
|
||||
"path": "system.security.cryptography.protecteddata/7.0.0",
|
||||
"hashPath": "system.security.cryptography.protecteddata.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Permissions/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Vmp0iRmCEno9BWiskOW5pxJ3d9n+jUqKxvX4GhLwFhnQaySZmBN2FuC0N5gjFHgyFMUjC5sfIJ8KZfoJwkcMmA==",
|
||||
"path": "system.security.permissions/7.0.0",
|
||||
"hashPath": "system.security.permissions.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Windows.Extensions/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-bR4qdCmssMMbo9Fatci49An5B1UaVJZHKNq70PRgzoLYIlitb8Tj7ns/Xt5Pz1CkERiTjcVBDU2y1AVrPBYkaw==",
|
||||
"path": "system.windows.extensions/7.0.0",
|
||||
"hashPath": "system.windows.extensions.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"WebCore.Contracts/1.0.1": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"DigitalData.Core.Contracts/1.0.1.0": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB |
@@ -1,4 +0,0 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v7.0", FrameworkDisplayName = ".NET 7.0")]
|
||||
@@ -1,8 +0,0 @@
|
||||
// <auto-generated/>
|
||||
global using global::System;
|
||||
global using global::System.Collections.Generic;
|
||||
global using global::System.IO;
|
||||
global using global::System.Linq;
|
||||
global using global::System.Net.Http;
|
||||
global using global::System.Threading;
|
||||
global using global::System.Threading.Tasks;
|
||||
@@ -1,23 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("DigitalData.Core.CleanArchitecture.Application")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("DigitalData.Core.CleanArchitecture.Application")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("DigitalData.Core.CleanArchitecture.Application")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
29481b6f7a973f95145d0c63745be915f7b67045
|
||||
@@ -1,11 +0,0 @@
|
||||
is_global = true
|
||||
build_property.TargetFramework = net7.0
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = DigitalData.Core.CleanArchitecture.Application
|
||||
build_property.ProjectDir = E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\
|
||||
@@ -1,8 +0,0 @@
|
||||
// <auto-generated/>
|
||||
global using global::System;
|
||||
global using global::System.Collections.Generic;
|
||||
global using global::System.IO;
|
||||
global using global::System.Linq;
|
||||
global using global::System.Net.Http;
|
||||
global using global::System.Threading;
|
||||
global using global::System.Threading.Tasks;
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
|
||||
3adb30e8572adfa0ff48fa59bbfbff13b48112f7
|
||||
@@ -1,34 +0,0 @@
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.csproj.AssemblyReference.cache
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.GeneratedMSBuildEditorConfig.editorconfig
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.AssemblyInfoInputs.cache
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.AssemblyInfo.cs
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.csproj.CoreCompileInputs.cache
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\bin\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.deps.json
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\bin\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.dll
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\bin\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.pdb
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\bin\Debug\net7.0\DigitalData.Core.Contracts.dll
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\bin\Debug\net7.0\DigitalData.Core.Exceptions.dll
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\bin\Debug\net7.0\DigitalData.Core.Contracts.pdb
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\bin\Debug\net7.0\DigitalData.Core.Exceptions.pdb
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.csproj.CopyComplete
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.dll
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\refint\DigitalData.Core.CleanArchitecture.Application.dll
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.pdb
|
||||
E:\TekH\Visual Studio\DigitalData\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\ref\DigitalData.Core.CleanArchitecture.Application.dll
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.csproj.AssemblyReference.cache
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.GeneratedMSBuildEditorConfig.editorconfig
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.AssemblyInfoInputs.cache
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.AssemblyInfo.cs
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.csproj.CoreCompileInputs.cache
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.dll
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\refint\DigitalData.Core.CleanArchitecture.Application.dll
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.pdb
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\bin\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.deps.json
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\bin\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.dll
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\bin\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.pdb
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\bin\Debug\net7.0\DigitalData.Core.Contracts.dll
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\bin\Debug\net7.0\DigitalData.Core.Contracts.pdb
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\DigitalData.Core.CleanArchitecture.Application.csproj.CopyComplete
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\obj\Debug\net7.0\ref\DigitalData.Core.CleanArchitecture.Application.dll
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\bin\Debug\net7.0\DigitalData.Core.Utilities.dll
|
||||
E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.CleanArchitecture.Application\bin\Debug\net7.0\DigitalData.Core.Utilities.pdb
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,23 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("DigitalData.Core.Services")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("DigitalData.Core.Services")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("DigitalData.Core.Services")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
eba1674d810a2e6af850ad2ebbb9a029e7f2ff0a
|
||||
@@ -1,11 +0,0 @@
|
||||
is_global = true
|
||||
build_property.TargetFramework = net7.0
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = DigitalData.Core.Services
|
||||
build_property.ProjectDir = E:\TekH\Visual Studio\DDWeb\DigitalData.Core\DigitalData.Core.Application\
|
||||
@@ -1,8 +0,0 @@
|
||||
// <auto-generated/>
|
||||
global using global::System;
|
||||
global using global::System.Collections.Generic;
|
||||
global using global::System.IO;
|
||||
global using global::System.Linq;
|
||||
global using global::System.Net.Http;
|
||||
global using global::System.Threading;
|
||||
global using global::System.Threading.Tasks;
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\tekh\.nuget\packages\;D:\ProgramFiles\DevExpress 21.2\Components\Offline Packages</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.9.1</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\tekh\.nuget\packages\" />
|
||||
<SourceRoot Include="D:\ProgramFiles\DevExpress 21.2\Components\Offline Packages\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,229 +0,0 @@
|
||||
{
|
||||
"format": 1,
|
||||
"restore": {
|
||||
"E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.CleanArchitecture.Application\\DigitalData.Core.CleanArchitecture.Application.csproj": {}
|
||||
},
|
||||
"projects": {
|
||||
"E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.CleanArchitecture.Application\\DigitalData.Core.CleanArchitecture.Application.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.CleanArchitecture.Application\\DigitalData.Core.CleanArchitecture.Application.csproj",
|
||||
"projectName": "DigitalData.Core.CleanArchitecture.Application",
|
||||
"projectPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.CleanArchitecture.Application\\DigitalData.Core.CleanArchitecture.Application.csproj",
|
||||
"packagesPath": "C:\\Users\\tekh\\.nuget\\packages\\",
|
||||
"outputPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.CleanArchitecture.Application\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"fallbackFolders": [
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\Offline Packages",
|
||||
"D:\\ProgramFiles\\DevExpress 22.1\\Components\\Offline Packages",
|
||||
"C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"
|
||||
],
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\tekh\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 19.2.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 21.2.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 22.1.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net7.0"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"D:\\ProgramFiles\\DevExpress 19.2\\Components\\System\\Components\\Packages": {},
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\System\\Components\\Packages": {},
|
||||
"D:\\ProgramFiles\\DevExpress 22.1\\Components\\System\\Components\\Packages": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"projectReferences": {
|
||||
"E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj": {
|
||||
"projectPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj"
|
||||
},
|
||||
"E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Utilities\\DigitalData.Core.Utilities.csproj": {
|
||||
"projectPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Utilities\\DigitalData.Core.Utilities.csproj"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"dependencies": {
|
||||
"AutoMapper": {
|
||||
"target": "Package",
|
||||
"version": "[13.0.1, )"
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\7.0.202\\RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj",
|
||||
"projectName": "DigitalData.Core.Contracts",
|
||||
"projectPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj",
|
||||
"packagesPath": "C:\\Users\\tekh\\.nuget\\packages\\",
|
||||
"outputPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"fallbackFolders": [
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\Offline Packages",
|
||||
"D:\\ProgramFiles\\DevExpress 22.1\\Components\\Offline Packages",
|
||||
"C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"
|
||||
],
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\tekh\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 19.2.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 21.2.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 22.1.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net7.0"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"D:\\ProgramFiles\\DevExpress 19.2\\Components\\System\\Components\\Packages": {},
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\System\\Components\\Packages": {},
|
||||
"D:\\ProgramFiles\\DevExpress 22.1\\Components\\System\\Components\\Packages": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"dependencies": {
|
||||
"System.DirectoryServices": {
|
||||
"target": "Package",
|
||||
"version": "[7.0.1, )"
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\7.0.202\\RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Utilities\\DigitalData.Core.Utilities.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Utilities\\DigitalData.Core.Utilities.csproj",
|
||||
"projectName": "DigitalData.Core.Utilities",
|
||||
"projectPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Utilities\\DigitalData.Core.Utilities.csproj",
|
||||
"packagesPath": "C:\\Users\\tekh\\.nuget\\packages\\",
|
||||
"outputPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Utilities\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"fallbackFolders": [
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\Offline Packages",
|
||||
"D:\\ProgramFiles\\DevExpress 22.1\\Components\\Offline Packages",
|
||||
"C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"
|
||||
],
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\tekh\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 19.2.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 21.2.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 22.1.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net7.0"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"D:\\ProgramFiles\\DevExpress 19.2\\Components\\System\\Components\\Packages": {},
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\System\\Components\\Packages": {},
|
||||
"D:\\ProgramFiles\\DevExpress 22.1\\Components\\System\\Components\\Packages": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"projectReferences": {
|
||||
"E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj": {
|
||||
"projectPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\7.0.202\\RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\tekh\.nuget\packages\;D:\ProgramFiles\DevExpress 21.2\Components\Offline Packages;D:\ProgramFiles\DevExpress 22.1\Components\Offline Packages;C:\Program Files\dotnet\sdk\NuGetFallbackFolder</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.5.0</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\tekh\.nuget\packages\" />
|
||||
<SourceRoot Include="D:\ProgramFiles\DevExpress 21.2\Components\Offline Packages\" />
|
||||
<SourceRoot Include="D:\ProgramFiles\DevExpress 22.1\Components\Offline Packages\" />
|
||||
<SourceRoot Include="C:\Program Files\dotnet\sdk\NuGetFallbackFolder\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
|
||||
@@ -1,229 +0,0 @@
|
||||
{
|
||||
"format": 1,
|
||||
"restore": {
|
||||
"E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Application\\DigitalData.Core.Services.csproj": {}
|
||||
},
|
||||
"projects": {
|
||||
"E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Application\\DigitalData.Core.Services.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Application\\DigitalData.Core.Services.csproj",
|
||||
"projectName": "DigitalData.Core.Services",
|
||||
"projectPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Application\\DigitalData.Core.Services.csproj",
|
||||
"packagesPath": "C:\\Users\\tekh\\.nuget\\packages\\",
|
||||
"outputPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Application\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"fallbackFolders": [
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\Offline Packages",
|
||||
"D:\\ProgramFiles\\DevExpress 22.1\\Components\\Offline Packages",
|
||||
"C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"
|
||||
],
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\tekh\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 19.2.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 21.2.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 22.1.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net7.0"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"D:\\ProgramFiles\\DevExpress 19.2\\Components\\System\\Components\\Packages": {},
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\System\\Components\\Packages": {},
|
||||
"D:\\ProgramFiles\\DevExpress 22.1\\Components\\System\\Components\\Packages": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"projectReferences": {
|
||||
"E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj": {
|
||||
"projectPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj"
|
||||
},
|
||||
"E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Utilities\\DigitalData.Core.Utilities.csproj": {
|
||||
"projectPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Utilities\\DigitalData.Core.Utilities.csproj"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"dependencies": {
|
||||
"AutoMapper": {
|
||||
"target": "Package",
|
||||
"version": "[13.0.1, )"
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\7.0.202\\RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj",
|
||||
"projectName": "DigitalData.Core.Contracts",
|
||||
"projectPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj",
|
||||
"packagesPath": "C:\\Users\\tekh\\.nuget\\packages\\",
|
||||
"outputPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"fallbackFolders": [
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\Offline Packages",
|
||||
"D:\\ProgramFiles\\DevExpress 22.1\\Components\\Offline Packages",
|
||||
"C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"
|
||||
],
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\tekh\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 19.2.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 21.2.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 22.1.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net7.0"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"D:\\ProgramFiles\\DevExpress 19.2\\Components\\System\\Components\\Packages": {},
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\System\\Components\\Packages": {},
|
||||
"D:\\ProgramFiles\\DevExpress 22.1\\Components\\System\\Components\\Packages": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"dependencies": {
|
||||
"System.DirectoryServices": {
|
||||
"target": "Package",
|
||||
"version": "[7.0.1, )"
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\7.0.202\\RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Utilities\\DigitalData.Core.Utilities.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Utilities\\DigitalData.Core.Utilities.csproj",
|
||||
"projectName": "DigitalData.Core.Utilities",
|
||||
"projectPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Utilities\\DigitalData.Core.Utilities.csproj",
|
||||
"packagesPath": "C:\\Users\\tekh\\.nuget\\packages\\",
|
||||
"outputPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Utilities\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"fallbackFolders": [
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\Offline Packages",
|
||||
"D:\\ProgramFiles\\DevExpress 22.1\\Components\\Offline Packages",
|
||||
"C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"
|
||||
],
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\tekh\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 19.2.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 21.2.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 22.1.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net7.0"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"D:\\ProgramFiles\\DevExpress 19.2\\Components\\System\\Components\\Packages": {},
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\System\\Components\\Packages": {},
|
||||
"D:\\ProgramFiles\\DevExpress 22.1\\Components\\System\\Components\\Packages": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"projectReferences": {
|
||||
"E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj": {
|
||||
"projectPath": "E:\\TekH\\Visual Studio\\DDWeb\\DigitalData.Core\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\7.0.202\\RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\tekh\.nuget\packages\;D:\ProgramFiles\DevExpress 21.2\Components\Offline Packages;D:\ProgramFiles\DevExpress 22.1\Components\Offline Packages;C:\Program Files\dotnet\sdk\NuGetFallbackFolder</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.5.0</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\tekh\.nuget\packages\" />
|
||||
<SourceRoot Include="D:\ProgramFiles\DevExpress 21.2\Components\Offline Packages\" />
|
||||
<SourceRoot Include="D:\ProgramFiles\DevExpress 22.1\Components\Offline Packages\" />
|
||||
<SourceRoot Include="C:\Program Files\dotnet\sdk\NuGetFallbackFolder\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user