├── .editorconfig
├── .gitattributes
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── a-regression.md
│ ├── b-bug-report.md
│ ├── c-feature-request.md
│ ├── d-enhancement-proposal.md
│ └── e-question.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Directory.Build.props
├── Directory.Build.targets
├── GuardedActions.MvvmCross
├── GuardedActions.MvvmCross.csproj
├── GuardedActionsIoCSetup.cs
└── readme.txt
├── GuardedActions.NetCore
├── Extensions
│ ├── HostBuilderExtensions.cs
│ └── ServiceProviderExtensions.cs
├── GuardedActionIoCSetup.cs
├── GuardedActions.NetCore.csproj
└── readme.txt
├── GuardedActions.sln
├── GuardedActions
├── Commands
│ ├── Actions
│ │ ├── Contracts
│ │ │ ├── IAction.cs
│ │ │ ├── IGuardedAction.cs
│ │ │ └── IGuardedResultAction.cs
│ │ ├── GuardedAction.cs
│ │ └── GuardedResultAction.cs
│ ├── AsyncGuardedCommandBuilder.cs
│ ├── AsyncGuardedDataContextCommandBuilder.cs
│ ├── Contracts
│ │ ├── IAsyncGuardedCommandBuilder.cs
│ │ ├── IAsyncGuardedDataContextCommandBuilder.cs
│ │ ├── ICommandBuilder.cs
│ │ └── IExceptionGuard.cs
│ └── ExceptionGuard.cs
├── Contracts
│ └── IDataContext.cs
├── ExceptionHandlers
│ ├── Attributes
│ │ ├── DefaultExceptionHandlerAttribute.cs
│ │ └── ExceptionHandlerForAttribute.cs
│ ├── Contracts
│ │ ├── IExceptionHandler.cs
│ │ ├── IExceptionHandlingAction.cs
│ │ └── IExceptionHandlingActionFactory.cs
│ ├── Defaults
│ │ └── GeneralExceptionHandler.cs
│ ├── ExceptionHandler.cs
│ ├── ExceptionHandlingAction.cs
│ ├── ExceptionHandlingActionFactory.cs
│ └── Extensions
│ │ └── ExceptionHandlerExtensions.cs
├── Extensions
│ ├── AssemblyExtensions.cs
│ ├── AttributeExtensions.cs
│ ├── DictionaryExtensions.cs
│ ├── ExceptionExtensions.cs
│ ├── StringExtensions.cs
│ └── TypeExtensions.cs
├── GuardedActions.csproj
├── IoC
│ └── IoCRegistration.cs
├── Utils
│ └── AssemblyUtils.cs
└── readme.txt
├── LICENSE
├── Playground
├── GuardedActionsPlayground.Droid
│ ├── Assets
│ │ └── AboutAssets.txt
│ ├── GuardedActionsPlayground.Droid.csproj
│ ├── MainActivity.cs
│ ├── Properties
│ │ ├── AndroidManifest.xml
│ │ └── AssemblyInfo.cs
│ └── Resources
│ │ ├── AboutResources.txt
│ │ ├── layout
│ │ ├── Tabbar.xml
│ │ └── Toolbar.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── icon.xml
│ │ └── icon_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── icon.png
│ │ └── launcher_foreground.png
│ │ ├── mipmap-mdpi
│ │ ├── icon.png
│ │ └── launcher_foreground.png
│ │ ├── mipmap-xhdpi
│ │ ├── icon.png
│ │ └── launcher_foreground.png
│ │ ├── mipmap-xxhdpi
│ │ ├── icon.png
│ │ └── launcher_foreground.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── icon.png
│ │ └── launcher_foreground.png
│ │ └── values
│ │ ├── colors.xml
│ │ └── styles.xml
├── GuardedActionsPlayground.iOS
│ ├── .AssemblyAttributes.cs
│ ├── AppDelegate.cs
│ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon1024.png
│ │ │ ├── Icon120.png
│ │ │ ├── Icon152.png
│ │ │ ├── Icon167.png
│ │ │ ├── Icon180.png
│ │ │ ├── Icon20.png
│ │ │ ├── Icon29.png
│ │ │ ├── Icon40.png
│ │ │ ├── Icon58.png
│ │ │ ├── Icon60.png
│ │ │ ├── Icon76.png
│ │ │ ├── Icon80.png
│ │ │ └── Icon87.png
│ ├── Entitlements.plist
│ ├── GuardedActionsPlayground.iOS.csproj
│ ├── Info.plist
│ ├── Main.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── Resources
│ │ ├── Default-568h@2x.png
│ │ ├── Default-Portrait.png
│ │ ├── Default-Portrait@2x.png
│ │ ├── Default.png
│ │ ├── Default@2x.png
│ │ └── LaunchScreen.storyboard
├── GuardedActionsPlayground
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── AssemblyInfo.cs
│ ├── GuardedActionsPlayground.csproj
│ ├── IoCRegistration.cs
│ ├── Pages
│ │ ├── MainPage.xaml
│ │ └── MainPage.xaml.cs
│ ├── Startup.cs
│ └── appsettings.json
└── GuradedActionsPlayground.Core
│ ├── Commands
│ ├── Actions
│ │ ├── Contracts
│ │ │ ├── IDownloadUrlAction.cs
│ │ │ └── IPullDownloadListAction.cs
│ │ ├── DownloadUrlAction.cs
│ │ ├── ExceptionHandlers
│ │ │ └── DownloadUrlActionWebExceptionHandler.cs
│ │ └── PullDownloadListAction.cs
│ ├── Contracts
│ │ ├── IDownloadAllCommandBuilder.cs
│ │ ├── IDownloadCommandBuilder.cs
│ │ └── IInitializeCommandBuilder.cs
│ ├── DownloadAllCommandBuilder.cs
│ ├── DownloadCommandBuilder.cs
│ └── InitializeCommandBuilder.cs
│ ├── ExceptionHandlers
│ └── Defaults
│ │ ├── GeneralExceptionHandler.cs
│ │ ├── NotImplementedExceptionHandler.cs
│ │ └── TaskCanceledExceptionHandler.cs
│ ├── Factories
│ ├── Contracts
│ │ └── IDownloadFactory.cs
│ └── DownloadFactory.cs
│ ├── GuardedActionsPlayground.Core.csproj
│ ├── Models
│ ├── Download.cs
│ └── NotifyPropertyChanged.cs
│ └── ViewModels
│ ├── BaseViewModel.cs
│ └── MainViewModel.cs
├── README.md
├── global.json
└── icon.png
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome:http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Don't use tabs for indentation.
7 | [*]
8 | indent_style = space
9 | # (Please don't specify an indent_size here; that has too many unintended consequences.)
10 |
11 | # Code files
12 | [*.{cs,csx,vb,vbx}]
13 | indent_size = 4
14 | insert_final_newline = true
15 | charset = utf-8-bom
16 |
17 | # Xml project files
18 | [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
19 | indent_size = 2
20 |
21 | # Xml config files
22 | [*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
23 | indent_size = 2
24 |
25 | # JSON files
26 | [*.json]
27 | indent_size = 2
28 |
29 | # Dotnet code style settings:
30 | [*.{cs,vb}]
31 | # Sort using and Import directives with System.* appearing first
32 | dotnet_sort_system_directives_first = true
33 | # Avoid "this." and "Me." if not necessary
34 | dotnet_style_qualification_for_field = false:suggestion
35 | dotnet_style_qualification_for_property = false:suggestion
36 | dotnet_style_qualification_for_method = false:suggestion
37 | dotnet_style_qualification_for_event = false:suggestion
38 |
39 | # Use language keywords instead of framework type names for type references
40 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
41 | dotnet_style_predefined_type_for_member_access = true:suggestion
42 |
43 | # Suggest more modern language features when available
44 | dotnet_style_object_initializer = true:suggestion
45 | dotnet_style_collection_initializer = true:suggestion
46 | dotnet_style_coalesce_expression = true:suggestion
47 | dotnet_style_null_propagation = true:suggestion
48 | dotnet_style_explicit_tuple_names = true:suggestion
49 |
50 | # CSharp code style settings:
51 | [*.cs]
52 | # Prefer "var" everywhere
53 | csharp_style_var_for_built_in_types = true:suggestion
54 | csharp_style_var_when_type_is_apparent = true:suggestion
55 | csharp_style_var_elsewhere = true:suggestion
56 |
57 | # Prefer method-like constructs to have a block body
58 | csharp_style_expression_bodied_methods = false:none
59 | csharp_style_expression_bodied_constructors = false:none
60 | csharp_style_expression_bodied_operators = false:none
61 |
62 | # Prefer property-like constructs to have an expression-body
63 | csharp_style_expression_bodied_properties = true:none
64 | csharp_style_expression_bodied_indexers = true:none
65 | csharp_style_expression_bodied_accessors = true:none
66 |
67 | # Suggest more modern language features when available
68 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
69 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
70 | csharp_style_inlined_variable_declaration = true:suggestion
71 | csharp_style_throw_expression = true:suggestion
72 | csharp_style_conditional_delegate_call = true:suggestion
73 |
74 | # Newline settings
75 | csharp_new_line_before_open_brace = all
76 | csharp_new_line_before_else = true
77 | csharp_new_line_before_catch = true
78 | csharp_new_line_before_finally = true
79 | csharp_new_line_before_members_in_object_initializers = true
80 | csharp_new_line_before_members_in_anonymous_types = true
81 |
82 | # Braces after if
83 | csharp_prefer_braces = false
84 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # This file is understood by git 1.7.2+.
2 |
3 | # Windows specific files should always be crlf on checkout
4 | *.bat text eol=crlf
5 | *.cmd text eol=crlf
6 | *.ps1 text eol=crlf
7 |
8 | # Check out the following as ln always for osx/linux/cygwin
9 | *.sh text eol=lf
10 |
11 | # Opt in the following types to always normalize line endings
12 | # on checkin and always use native endings on checkout.
13 | *.config text
14 | *.cs text diff=csharp
15 | *.csproj text
16 | *.md text
17 | *.msbuild text
18 | *.nuspec text
19 | *.pp text
20 | *.ps1 text
21 | *.sln text
22 | *.tt text
23 | *.txt text
24 | *.xaml text
25 | *.xml text
26 |
27 | # Binary files
28 | *.bmp binary
29 | *.jpeg binary
30 | *.jpg binary
31 | *.nupkg binary
32 | *.png binary
33 | *.sdf binary
34 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: Baseflow
2 | custom: https://baseflow.com/contact
3 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/a-regression.md:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | name: 🔙 Regression
4 | about: Report unexpected behavior that worked previously
5 | ---
6 |
7 | ## 🔙 Regression
8 |
9 |
10 |
11 | ### Old (and correct) behavior
12 |
13 | ### Current behavior
14 |
15 | ### Reproduction steps
16 |
17 | ### Configuration
18 |
19 | **Version:** 1.x
20 |
21 | **Platform:**
22 | - [ ] :iphone: iOS
23 | - [ ] :robot: Android
24 | - [ ] :checkered_flag: WPF
25 | - [ ] :earth_americas: UWP
26 | - [ ] :apple: MacOS
27 | - [ ] :tv: tvOS
28 | - [ ] :monkey: Xamarin.Forms
29 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/b-bug-report.md:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | name: 🐛 Bug Report
4 | about: Create a report to help us fix bugs and make improvements
5 | ---
6 |
7 | ## 🐛 Bug Report
8 |
9 |
10 |
11 | ### Expected behavior
12 |
13 | ### Reproduction steps
14 |
15 | ### Configuration
16 |
17 | **Version:** 1.x
18 |
19 | **Platform:**
20 | - [ ] :iphone: iOS
21 | - [ ] :robot: Android
22 | - [ ] :checkered_flag: WPF
23 | - [ ] :earth_americas: UWP
24 | - [ ] :apple: MacOS
25 | - [ ] :tv: tvOS
26 | - [ ] :monkey: Xamarin.Forms
27 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/c-feature-request.md:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | name: 🚀 Feature Request
4 | about: Want to see something new included in the Framework? Submit it!
5 | ---
6 |
7 | ## 🚀 Feature Requests
8 |
9 |
10 |
11 | ### Contextualize the feature
12 |
13 |
14 | ### Describe the feature
15 |
16 |
17 | ### Platforms affected (mark all that apply)
18 | - [ ] :iphone: iOS
19 | - [ ] :robot: Android
20 | - [ ] :checkered_flag: WPF
21 | - [ ] :earth_americas: UWP
22 | - [ ] :apple: MacOS
23 | - [ ] :tv: tvOS
24 | - [ ] :monkey: Xamarin.Forms
25 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/d-enhancement-proposal.md:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | name: 🏗 Enhancement Proposal
4 | about: Proposals for code cleanup, refactor and improvements in general
5 | ---
6 |
7 | ## 🏗 Enhancement Proposal
8 |
9 |
10 |
11 | ### Pitch
12 |
13 |
14 |
15 | ### Platforms affected (mark all that apply)
16 | - [ ] :iphone: iOS
17 | - [ ] :robot: Android
18 | - [ ] :checkered_flag: WPF
19 | - [ ] :earth_americas: UWP
20 | - [ ] :apple: MacOS
21 | - [ ] :tv: tvOS
22 | - [ ] :monkey: Xamarin.Forms
23 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/e-question.md:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | name: 💬 Questions and Help
4 | about: If you have questions, please use this for support
5 | ---
6 |
7 | ## 💬 Questions and Help
8 |
9 | For questions or help we recommend checking:
10 |
11 | - The [Xamarin tag in Stack Overflow](https://stackoverflow.com/questions/tagged/xamarin)
12 | - The [General slack channel in the Xamarin Slack](https://xamarinchat.herokuapp.com/)
13 | - Ask your question in the [Xamarin Forums](https://forums.xamarin.com/)
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ### :sparkles: What kind of change does this PR introduce? (Bug fix, feature, docs update...)
2 |
3 |
4 | ### :arrow_heading_down: What is the current behavior?
5 |
6 |
7 | ### :new: What is the new behavior (if this is a feature change)?
8 |
9 |
10 | ### :boom: Does this PR introduce a breaking change?
11 |
12 |
13 | ### :bug: Recommendations for testing
14 |
15 |
16 | ### :memo: Links to relevant issues/docs
17 |
18 |
19 | ### :thinking: Checklist before submitting
20 |
21 | - [ ] All projects build
22 | - [ ] Follows style guide lines
23 | - [ ] Relevant documentation was updated
24 | - [ ] Rebased onto current develop
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | ## Android Auto-generated files
5 | Resource.designer.cs
6 |
7 | # User-specific files
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Build results
17 | [Dd]ebug/
18 | [Dd]ebugPublic/
19 | [Rr]elease/
20 | [Rr]eleases/
21 | x64/
22 | x86/
23 | build/
24 | bld/
25 | [Bb]in/
26 | [Oo]bj/
27 |
28 | # Visual Studo 2015 cache/options directory
29 | .vs/
30 |
31 | # MSTest test Results
32 | [Tt]est[Rr]esult*/
33 | [Tt]est[Rr]esult*
34 | [Bb]uild[Ll]og.*
35 |
36 | # NUNIT
37 | *.VisualState.xml
38 | TestResult.xml
39 |
40 | # Build Results of an ATL Project
41 | [Dd]ebugPS/
42 | [Rr]eleasePS/
43 | dlldata.c
44 |
45 | # .NET Core
46 | project.lock.json
47 | project.fragment.lock.json
48 | artifacts/
49 | **/Properties/launchSettings.json
50 |
51 | *_i.c
52 | *_p.c
53 | *_i.h
54 | *.ilk
55 | *.meta
56 | *.obj
57 | *.pch
58 | *.pdb
59 | *.pgc
60 | *.pgd
61 | *.rsp
62 | *.sbr
63 | *.tlb
64 | *.tli
65 | *.tlh
66 | *.tmp
67 | *.tmp_proj
68 | *.log
69 | *.vspscc
70 | *.vssscc
71 | .builds
72 | *.pidb
73 | *.svclog
74 | *.scc
75 | *.exe
76 | *.bak
77 | *.cache
78 | *.lib
79 |
80 | # Chutzpah Test files
81 | _Chutzpah*
82 |
83 | # Visual C++ cache files
84 | ipch/
85 | *.aps
86 | *.ncb
87 | *.opensdf
88 | *.sdf
89 | *.cachefile
90 |
91 | # Visual Studio profiler
92 | *.psess
93 | *.vsp
94 | *.vspx
95 |
96 | # TFS 2012 Local Workspace
97 | $tf/
98 |
99 | # Guidance Automation Toolkit
100 | *.gpState
101 |
102 | # ReSharper is a .NET coding add-in
103 | _ReSharper*/
104 | *.[Rr]e[Ss]harper
105 | *.DotSettings.user
106 |
107 | # JustCode is a .NET coding addin-in
108 | .JustCode
109 |
110 | # TeamCity is a build add-in
111 | _TeamCity*
112 |
113 | # DotCover is a Code Coverage Tool
114 | *.dotCover
115 |
116 | # NCrunch
117 | _NCrunch_*
118 | .*crunch*.local.xml
119 | *.ncrunchproject
120 |
121 | # MightyMoose
122 | *.mm.*
123 | AutoTest.Net/
124 |
125 | # Web workbench (sass)
126 | .sass-cache/
127 |
128 | # Installshield output folder
129 | [Ee]xpress/
130 |
131 | # DocProject is a documentation generator add-in
132 | DocProject/buildhelp/
133 | DocProject/Help/*.HxT
134 | DocProject/Help/*.HxC
135 | DocProject/Help/*.hhc
136 | DocProject/Help/*.hhk
137 | DocProject/Help/*.hhp
138 | DocProject/Help/Html2
139 | DocProject/Help/html
140 |
141 | # Click-Once directory
142 | publish/
143 |
144 | # Publish Web Output
145 | *.[Pp]ublish.xml
146 | *.azurePubxml
147 | # TODO: Comment the next line if you want to checkin your web deploy settings
148 | # but database connection strings (with potential passwords) will be unencrypted
149 | *.pubxml
150 | *.publishproj
151 |
152 | # NuGet Packages
153 | *.nupkg
154 | # The packages folder can be ignored because of Package Restore
155 | **/packages/*
156 | # except build/, which is used as an MSBuild target.
157 | !**/packages/build/
158 | # Uncomment if necessary however generally it will be regenerated when needed
159 | #!**/packages/repositories.config
160 | # NuGet v3's project.json files produces more ignoreable files
161 | *.nuget.props
162 | *.nuget.targets
163 |
164 | #Allow NuGet.exe (do not ignore)
165 | !NuGet.exe
166 | *.orig
167 |
168 | # Windows Azure Build Output
169 | csx/
170 | *.build.csdef
171 |
172 | # Windows Store app package directory
173 | AppPackages/
174 |
175 | # Others
176 | *.[Cc]ache
177 | ClientBin/
178 | [Ss]tyle[Cc]op.*
179 | ~$*
180 | *~
181 | *.dbmdl
182 | *.dbproj.schemaview
183 | *.pfx
184 | *.publishsettings
185 | node_modules/
186 | bower_components/
187 |
188 | # RIA/Silverlight projects
189 | Generated_Code/
190 |
191 | # Backup & report files from converting an old project file
192 | # to a newer Visual Studio version. Backup files are not needed,
193 | # because we have git ;-)
194 | _UpgradeReport_Files/
195 | Backup*/
196 | UpgradeLog*.XML
197 | UpgradeLog*.htm
198 |
199 | # SQL Server files
200 | *.mdf
201 | *.ldf
202 |
203 | # Business Intelligence projects
204 | *.rdl.data
205 | *.bim.layout
206 | *.bim_*.settings
207 |
208 | # Microsoft Fakes
209 | FakesAssemblies/
210 |
211 | # Node.js Tools for Visual Studio
212 | .ntvs_analysis.dat
213 |
214 | # Visual Studio 6 build log
215 | *.plg
216 |
217 | # Visual Studio 6 workspace options file
218 | *.opt
219 |
220 | #ignore thumbnails created by windows
221 | Thumbs.db
222 |
223 | # Xcode
224 | .DS_Store
225 | */build/*
226 | *.pbxuser
227 | !default.pbxuser
228 | *.mode1v3
229 | !default.mode1v3
230 | *.mode2v3
231 | !default.mode2v3
232 | *.perspectivev3
233 | !default.perspectivev3
234 | xcuserdata
235 | profile
236 | *.moved-aside
237 | DerivedData
238 | .idea/
239 | *.hmap
240 | *.xccheckout
241 |
242 | #CocoaPods
243 | Pods
244 | nuspec/nuget.exe
245 |
246 | # NuGet
247 | packages/
248 | repositories.config
249 |
250 | #Build
251 | project.lock.json
252 | tools/*
253 | !tools/packages.config
254 | artifacts/
255 | *.nupkg
256 | *.binlog
257 |
258 | #linting
259 | .sonarqube/
260 |
261 | # dotnet tools
262 | .store/
263 |
264 | .AssemblyAttributes
265 |
266 |
267 | .mfractor/
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, gender identity and expression, level of experience,
9 | nationality, personal appearance, race, religion, or sexual identity and
10 | orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at [jop@baseflow.com](mailto:jop@baseflow.com). All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at [http://contributor-covenant.org/version/1/4][version]
72 |
73 | [homepage]: http://contributor-covenant.org
74 | [version]: http://contributor-covenant.org/version/1/4/
75 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | ## Finding an issue to work on
4 |
5 | If you'd like to work on something that isn't in a current issue, especially if it would be a big change, please open a new issue for discussion!
6 |
7 | ## Setting up a development environment
8 |
9 | First, you'll need git to fork and clone the repo. [GitHub has help pages about setting
10 | up git](https://help.github.com/articles/set-up-git/), and once you've done
11 | that, you should be able to clone the repo and change into the repo's directory
12 | from your terminal:
13 |
14 | ```
15 | git clone https://github.com/{YourFork}/GuardedActions.git
16 | ```
17 |
18 | If you are using SourceTree or another kind of visual git application, enter the url to your fork in the add new repository field.
19 |
20 | After you are done pull the develop branch, and open `GuardedActions.sln` in Visual Studio to get started.
21 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | Copyright (c) Baseflow
4 | MIT
5 | https://github.com/Baseflow/GuardedActions
6 | https://raw.githubusercontent.com/Baseflow/GuardedActions/develop/icon.png
7 |
8 | Baseflow
9 | Baseflow
10 | xamarin, plugin, mvvm, GuardedActions
11 | https://github.com/Baseflow/GuardedActions/releases
12 | false
13 | en-US
14 | 2.12
15 |
16 | https://github.com/Baseflow/GuardedActions
17 | git
18 | $(AssemblyName) ($(TargetFramework))
19 | 1.1.0
20 |
21 | preview
22 | enable
23 | $(NoWarn);1591;1701;1702;1705;VSX1000;CS0109;CS0108;CS0618;CS0114;NU1603
24 | AnyCPU
25 |
26 |
27 | $(MSBuildProjectName.Contains('UnitTest'))
28 | $(MSBuildProjectName.Contains('GuardedActions'))
29 |
30 | true
31 |
32 |
33 |
34 |
35 | true
36 | $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
37 | true
38 |
39 | false
40 | portable
41 | true
42 |
43 | true
44 | true
45 |
46 |
47 |
48 | true
49 | true
50 |
51 |
52 |
53 | full
54 | true
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | all
78 | runtime; build; native; contentfiles; analyzers; buildtransitive
79 |
80 |
81 | all
82 | runtime; build; native; contentfiles; analyzers; buildtransitive
83 |
84 |
88 |
89 | all
90 | runtime; build; native; contentfiles; analyzers; buildtransitive
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 | $(DefineConstants);NETSTANDARD;PORTABLE
4 |
5 |
6 | $(DefineConstants);NETSTANDARD20
7 |
8 |
9 | $(DefineConstants);NET;WPF;XAML
10 |
11 |
12 | $(DefineConstants);NET;NET5
13 |
14 |
15 | $(DefineConstants);NETFX_CORE;XAML;WINDOWS;WINDOWS_UWP;UWP
16 | 10.0.17763.0
17 | 10.0.17763.0
18 |
19 |
20 | $(DefineConstants);MONO;UIKIT;COCOA;APPLE;IOS
21 |
22 |
23 | $(DefineConstants);MONO;COCOA;APPLE;MAC
24 |
25 |
26 | $(DefineConstants);MONO;COCOA;APPLE;TVOS
27 |
28 |
29 | $(DefineConstants);MONO;COCOA;APPLE;WATCHOS
30 |
31 |
32 | $(DefineConstants);MONO;ANDROID
33 | Resources
34 | Resource
35 | Resources\Resource.designer.cs
36 |
37 |
38 | $(DefineConstants);NETCOREAPP
39 |
40 |
41 | $(DefineConstants);TIZEN
42 | Tizen
43 | v4.0
44 |
45 |
--------------------------------------------------------------------------------
/GuardedActions.MvvmCross/GuardedActions.MvvmCross.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/GuardedActions.MvvmCross/GuardedActionsIoCSetup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GuardedActions.IoC;
3 | using MvvmCross.IoC;
4 |
5 | namespace GuardedActions.MvvmCross
6 | {
7 | public class GuardedActionsIoCSetup : IoCRegistration
8 | {
9 | private IMvxIoCProvider? _provider;
10 |
11 | public void Configure(IMvxIoCProvider provider, params string[] assemblyNames)
12 | {
13 | _provider = provider ?? throw new ArgumentNullException(nameof(provider));
14 |
15 | Register(assemblyNames);
16 | }
17 |
18 | public override void AddSingletonInternal(Func constructor) where TServiceType : class => _provider.RegisterSingleton(() => constructor.Invoke());
19 |
20 | public override void AddSingletonInternal(Type serviceType)
21 | {
22 | var instance = _provider.IoCConstruct(serviceType);
23 | _provider.RegisterSingleton(serviceType, instance);
24 | }
25 |
26 | public override void AddSingletonInternal(Type contractType, Type serviceType)
27 | {
28 | var instance = _provider.IoCConstruct(serviceType);
29 | _provider.RegisterSingleton(contractType, instance);
30 | }
31 |
32 | public override void AddTransientInternal(Type serviceType) => _provider.RegisterType(serviceType);
33 |
34 | public override void AddTransientInternal(Type contractType, Type serviceType) => _provider.RegisterType(contractType, serviceType);
35 |
36 | public override TServiceType GetServiceInternal() where TServiceType : class => _provider.Resolve();
37 |
38 | public override TServiceType GetServiceInternal(Type serviceType) where TServiceType : class => (TServiceType) _provider.Resolve(serviceType);
39 |
40 | public override bool CanRegister => _provider != null;
41 |
42 | public override bool CanResolve => _provider != null;
43 |
44 | public override string CannotRegisterErrorMessage => $"Make sure you've called the {nameof(Configure)} on the {nameof(GuardedActionsIoCSetup)} before the AppStart.";
45 |
46 | public override string CannotResolveErrorMessage => CannotRegisterErrorMessage;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/GuardedActions.MvvmCross/readme.txt:
--------------------------------------------------------------------------------
1 | ---------------------------------
2 | GuardedActions
3 | ---------------------------------
4 |
5 | A library to increase the error handling, testability and reusability for all your MVVM driven apps!
6 |
7 |
8 | using GuardedActions.MvvmCross;
9 |
10 | public class App : MvxApplication
11 | {
12 | public override void Initialize()
13 | {
14 | new GuardedActionsIoCSetup().Configure(Mvx.IoCProvider, "YourAssembliesStartWith");
15 |
16 | RegisterAppStart();
17 | }
18 | }
19 |
20 |
21 | ---------------------------------
22 | Star on Github if this project helps you: https://github.com/Baseflow/GuardedActions
23 |
24 | Commercial support is available. Integration with your app or services, samples, feature request, etc. Email: hello@baseflow.com
25 | Powered by: https://baseflow.com
26 | ---------------------------------
--------------------------------------------------------------------------------
/GuardedActions.NetCore/Extensions/HostBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.Extensions.Hosting;
3 |
4 | namespace GuardedActions.NetCore.Extensions
5 | {
6 | public static class HostBuilderExtensions
7 | {
8 | public static IHostBuilder ConfigureGuardedActions(this IHostBuilder builder, GuardedActionIoCSetup iocRegistration, params string[] assemblyNames)
9 | {
10 | if (builder == null)
11 | throw new ArgumentNullException(nameof(builder));
12 | if (iocRegistration == null)
13 | throw new ArgumentNullException(nameof(iocRegistration));
14 |
15 | return builder.ConfigureServices((_, sc) =>
16 | {
17 | iocRegistration.SetServiceCollection(sc);
18 | iocRegistration.Register(assemblyNames);
19 | });
20 | }
21 |
22 | public static IHost ConnectGuardedActions(this IHost host, GuardedActionIoCSetup ioCRegistration)
23 | {
24 | if (host == null)
25 | throw new ArgumentNullException(nameof(host));
26 | if (ioCRegistration == null)
27 | throw new ArgumentNullException(nameof(ioCRegistration));
28 |
29 | ioCRegistration.SetServiceProvider(host.Services);
30 |
31 | return host;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/GuardedActions.NetCore/Extensions/ServiceProviderExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GuardedActions.NetCore.Extensions
4 | {
5 | public static class ServiceProviderExtensions
6 | {
7 | public static TServiceTypeBase GetService(this IServiceProvider? serviceProvider, Type serviceType) where TServiceTypeBase : class =>
8 | serviceProvider?.GetService(serviceType) as TServiceTypeBase;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/GuardedActions.NetCore/GuardedActionIoCSetup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GuardedActions.IoC;
3 | using GuardedActions.NetCore.Extensions;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using Microsoft.Extensions.Hosting;
6 |
7 | namespace GuardedActions.NetCore
8 | {
9 | public class GuardedActionIoCSetup : IoCRegistration
10 | {
11 | private IServiceCollection? _serviceCollection;
12 | private IServiceProvider? _serviceProvider;
13 |
14 | public GuardedActionIoCSetup SetServiceCollection(IServiceCollection serviceCollection)
15 | {
16 | _serviceCollection = serviceCollection ?? throw new ArgumentNullException(nameof(serviceCollection));
17 | return this;
18 | }
19 |
20 | public GuardedActionIoCSetup SetServiceProvider(IServiceProvider serviceProvider)
21 | {
22 | _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
23 | return this;
24 | }
25 |
26 | public override void AddSingletonInternal(Func constructor) where TServiceType : class => _serviceCollection.AddSingleton((_) => constructor.Invoke());
27 |
28 | public override void AddSingletonInternal(Type serviceType) => _serviceCollection.AddSingleton(serviceType);
29 |
30 | public override void AddSingletonInternal(Type contractType, Type serviceType) => _serviceCollection.AddSingleton(contractType, serviceType);
31 |
32 | public override void AddTransientInternal(Type serviceType) => _serviceCollection.AddTransient(serviceType);
33 |
34 | public override void AddTransientInternal(Type contractType, Type serviceType) => _serviceCollection.AddTransient(contractType, serviceType);
35 |
36 | public override TServiceType GetServiceInternal() where TServiceType : class => _serviceProvider.GetService();
37 |
38 | public override TServiceType GetServiceInternal(Type serviceType) where TServiceType : class => _serviceProvider.GetService(serviceType);
39 |
40 | public override bool CanRegister => _serviceCollection != null;
41 |
42 | public override bool CanResolve => _serviceProvider != null;
43 |
44 | public override string CannotRegisterErrorMessage => $"Make sure you've called the {nameof(HostBuilderExtensions.ConfigureGuardedActions)} on the {nameof(IHostBuilder)} before building it.";
45 |
46 | public override string CannotResolveErrorMessage => $"Make sure you've called the {nameof(HostBuilderExtensions.ConnectGuardedActions)} on the {nameof(IHost)} after building the {nameof(IHostBuilder)}.";
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/GuardedActions.NetCore/GuardedActions.NetCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/GuardedActions.NetCore/readme.txt:
--------------------------------------------------------------------------------
1 | ---------------------------------
2 | GuardedActions
3 | ---------------------------------
4 |
5 | A library to increase the error handling, testability and reusability for all your MVVM driven apps!
6 |
7 |
8 | using GuardedActions.NetCore;
9 | using GuardedActions.NetCore.Extensions;
10 |
11 | public class Startup
12 | {
13 | public static void Init()
14 | {
15 | var iocSetup = new GuardedActionsIoCSetup();
16 |
17 | var host = new HostBuilder()
18 | .ConfigureGuardedActions(iocSetup, "YourAssembliesStartWith")
19 | .Build()
20 | .ConnectGuardedActions(iocSetup);
21 | }
22 | }
23 |
24 |
25 | ---------------------------------
26 | Star on Github if this project helps you: https://github.com/Baseflow/GuardedActions
27 |
28 | Commercial support is available. Integration with your app or services, samples, feature request, etc. Email: hello@baseflow.com
29 | Powered by: https://baseflow.com
30 | ---------------------------------
--------------------------------------------------------------------------------
/GuardedActions.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GuardedActions", "GuardedActions\GuardedActions.csproj", "{8BECF4A6-FBF0-417B-B142-AD92ED4933B5}"
5 | EndProject
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "02_GuardedActions", "02_GuardedActions", "{51416960-B20E-42AF-BA41-F5A153DACE30}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "03_Playground", "03_Playground", "{A231AC6D-2874-413B-9CFF-E42B0EF3F487}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "01_SolutionFiles", "01_SolutionFiles", "{8080F2A5-7F12-4F26-96AF-1E3FEA7D4DD4}"
11 | ProjectSection(SolutionItems) = preProject
12 | Directory.Build.props = Directory.Build.props
13 | Directory.Build.targets = Directory.Build.targets
14 | CONTRIBUTING.md = CONTRIBUTING.md
15 | CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md
16 | README.md = README.md
17 | LICENSE = LICENSE
18 | global.json = global.json
19 | .gitignore = .gitignore
20 | EndProjectSection
21 | EndProject
22 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GuardedActionsPlayground", "Playground\GuardedActionsPlayground\GuardedActionsPlayground.csproj", "{FA35DD42-38FD-4080-830A-D30462AAD69E}"
23 | EndProject
24 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GuardedActionsPlayground.Droid", "Playground\GuardedActionsPlayground.Droid\GuardedActionsPlayground.Droid.csproj", "{1F6DACAE-A220-42EE-94A6-2B05F673A164}"
25 | EndProject
26 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GuardedActionsPlayground.iOS", "Playground\GuardedActionsPlayground.iOS\GuardedActionsPlayground.iOS.csproj", "{2C9D3E04-20E9-48C7-A8DB-0D1A2F6948C8}"
27 | EndProject
28 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub", "GitHub", "{36188102-875F-4E53-8936-53AB3AAD3F29}"
29 | ProjectSection(SolutionItems) = preProject
30 | .github\PULL_REQUEST_TEMPLATE.md = .github\PULL_REQUEST_TEMPLATE.md
31 | .github\ISSUE_TEMPLATE\e-question.md = .github\ISSUE_TEMPLATE\e-question.md
32 | .github\ISSUE_TEMPLATE\d-enhancement-proposal.md = .github\ISSUE_TEMPLATE\d-enhancement-proposal.md
33 | .github\ISSUE_TEMPLATE\c-feature-request.md = .github\ISSUE_TEMPLATE\c-feature-request.md
34 | .github\ISSUE_TEMPLATE\b-bug-report.md = .github\ISSUE_TEMPLATE\b-bug-report.md
35 | .github\ISSUE_TEMPLATE\a-regression.md = .github\ISSUE_TEMPLATE\a-regression.md
36 | .github\FUNDING.yml = .github\FUNDING.yml
37 | EndProjectSection
38 | EndProject
39 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GuardedActions.NetCore", "GuardedActions.NetCore\GuardedActions.NetCore.csproj", "{FA21DBBE-A29E-4363-9EC3-2AF620CBB870}"
40 | EndProject
41 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GuardedActions.MvvmCross", "GuardedActions.MvvmCross\GuardedActions.MvvmCross.csproj", "{717303FD-D29A-45D1-A2A6-5D588245FD63}"
42 | EndProject
43 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GuardedActionsPlayground.Core", "Playground\GuradedActionsPlayground.Core\GuardedActionsPlayground.Core.csproj", "{1D7BD4CF-ED08-4FDA-A043-0C94452B3D48}"
44 | EndProject
45 | Global
46 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
47 | Debug|Any CPU = Debug|Any CPU
48 | Release|Any CPU = Release|Any CPU
49 | Debug|iPhoneSimulator = Debug|iPhoneSimulator
50 | Release|iPhoneSimulator = Release|iPhoneSimulator
51 | Debug|iPhone = Debug|iPhone
52 | Release|iPhone = Release|iPhone
53 | EndGlobalSection
54 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
55 | {8BECF4A6-FBF0-417B-B142-AD92ED4933B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
56 | {8BECF4A6-FBF0-417B-B142-AD92ED4933B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
57 | {8BECF4A6-FBF0-417B-B142-AD92ED4933B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
58 | {8BECF4A6-FBF0-417B-B142-AD92ED4933B5}.Release|Any CPU.Build.0 = Release|Any CPU
59 | {8BECF4A6-FBF0-417B-B142-AD92ED4933B5}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
60 | {8BECF4A6-FBF0-417B-B142-AD92ED4933B5}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
61 | {8BECF4A6-FBF0-417B-B142-AD92ED4933B5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
62 | {8BECF4A6-FBF0-417B-B142-AD92ED4933B5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
63 | {8BECF4A6-FBF0-417B-B142-AD92ED4933B5}.Debug|iPhone.ActiveCfg = Debug|Any CPU
64 | {8BECF4A6-FBF0-417B-B142-AD92ED4933B5}.Debug|iPhone.Build.0 = Debug|Any CPU
65 | {8BECF4A6-FBF0-417B-B142-AD92ED4933B5}.Release|iPhone.ActiveCfg = Release|Any CPU
66 | {8BECF4A6-FBF0-417B-B142-AD92ED4933B5}.Release|iPhone.Build.0 = Release|Any CPU
67 | {FA35DD42-38FD-4080-830A-D30462AAD69E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
68 | {FA35DD42-38FD-4080-830A-D30462AAD69E}.Debug|Any CPU.Build.0 = Debug|Any CPU
69 | {FA35DD42-38FD-4080-830A-D30462AAD69E}.Release|Any CPU.ActiveCfg = Release|Any CPU
70 | {FA35DD42-38FD-4080-830A-D30462AAD69E}.Release|Any CPU.Build.0 = Release|Any CPU
71 | {FA35DD42-38FD-4080-830A-D30462AAD69E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
72 | {FA35DD42-38FD-4080-830A-D30462AAD69E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
73 | {FA35DD42-38FD-4080-830A-D30462AAD69E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
74 | {FA35DD42-38FD-4080-830A-D30462AAD69E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
75 | {FA35DD42-38FD-4080-830A-D30462AAD69E}.Debug|iPhone.ActiveCfg = Debug|Any CPU
76 | {FA35DD42-38FD-4080-830A-D30462AAD69E}.Debug|iPhone.Build.0 = Debug|Any CPU
77 | {FA35DD42-38FD-4080-830A-D30462AAD69E}.Release|iPhone.ActiveCfg = Release|Any CPU
78 | {FA35DD42-38FD-4080-830A-D30462AAD69E}.Release|iPhone.Build.0 = Release|Any CPU
79 | {1F6DACAE-A220-42EE-94A6-2B05F673A164}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
80 | {1F6DACAE-A220-42EE-94A6-2B05F673A164}.Debug|Any CPU.Build.0 = Debug|Any CPU
81 | {1F6DACAE-A220-42EE-94A6-2B05F673A164}.Release|Any CPU.ActiveCfg = Release|Any CPU
82 | {1F6DACAE-A220-42EE-94A6-2B05F673A164}.Release|Any CPU.Build.0 = Release|Any CPU
83 | {1F6DACAE-A220-42EE-94A6-2B05F673A164}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
84 | {1F6DACAE-A220-42EE-94A6-2B05F673A164}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
85 | {1F6DACAE-A220-42EE-94A6-2B05F673A164}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
86 | {1F6DACAE-A220-42EE-94A6-2B05F673A164}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
87 | {1F6DACAE-A220-42EE-94A6-2B05F673A164}.Debug|iPhone.ActiveCfg = Debug|Any CPU
88 | {1F6DACAE-A220-42EE-94A6-2B05F673A164}.Debug|iPhone.Build.0 = Debug|Any CPU
89 | {1F6DACAE-A220-42EE-94A6-2B05F673A164}.Release|iPhone.ActiveCfg = Release|Any CPU
90 | {1F6DACAE-A220-42EE-94A6-2B05F673A164}.Release|iPhone.Build.0 = Release|Any CPU
91 | {2C9D3E04-20E9-48C7-A8DB-0D1A2F6948C8}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator
92 | {2C9D3E04-20E9-48C7-A8DB-0D1A2F6948C8}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator
93 | {2C9D3E04-20E9-48C7-A8DB-0D1A2F6948C8}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator
94 | {2C9D3E04-20E9-48C7-A8DB-0D1A2F6948C8}.Release|Any CPU.Build.0 = Release|iPhoneSimulator
95 | {2C9D3E04-20E9-48C7-A8DB-0D1A2F6948C8}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
96 | {2C9D3E04-20E9-48C7-A8DB-0D1A2F6948C8}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
97 | {2C9D3E04-20E9-48C7-A8DB-0D1A2F6948C8}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
98 | {2C9D3E04-20E9-48C7-A8DB-0D1A2F6948C8}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
99 | {2C9D3E04-20E9-48C7-A8DB-0D1A2F6948C8}.Debug|iPhone.ActiveCfg = Debug|iPhone
100 | {2C9D3E04-20E9-48C7-A8DB-0D1A2F6948C8}.Debug|iPhone.Build.0 = Debug|iPhone
101 | {2C9D3E04-20E9-48C7-A8DB-0D1A2F6948C8}.Release|iPhone.ActiveCfg = Release|iPhone
102 | {2C9D3E04-20E9-48C7-A8DB-0D1A2F6948C8}.Release|iPhone.Build.0 = Release|iPhone
103 | {FA21DBBE-A29E-4363-9EC3-2AF620CBB870}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
104 | {FA21DBBE-A29E-4363-9EC3-2AF620CBB870}.Debug|Any CPU.Build.0 = Debug|Any CPU
105 | {FA21DBBE-A29E-4363-9EC3-2AF620CBB870}.Release|Any CPU.ActiveCfg = Release|Any CPU
106 | {FA21DBBE-A29E-4363-9EC3-2AF620CBB870}.Release|Any CPU.Build.0 = Release|Any CPU
107 | {FA21DBBE-A29E-4363-9EC3-2AF620CBB870}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
108 | {FA21DBBE-A29E-4363-9EC3-2AF620CBB870}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
109 | {FA21DBBE-A29E-4363-9EC3-2AF620CBB870}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
110 | {FA21DBBE-A29E-4363-9EC3-2AF620CBB870}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
111 | {FA21DBBE-A29E-4363-9EC3-2AF620CBB870}.Debug|iPhone.ActiveCfg = Debug|Any CPU
112 | {FA21DBBE-A29E-4363-9EC3-2AF620CBB870}.Debug|iPhone.Build.0 = Debug|Any CPU
113 | {FA21DBBE-A29E-4363-9EC3-2AF620CBB870}.Release|iPhone.ActiveCfg = Release|Any CPU
114 | {FA21DBBE-A29E-4363-9EC3-2AF620CBB870}.Release|iPhone.Build.0 = Release|Any CPU
115 | {717303FD-D29A-45D1-A2A6-5D588245FD63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
116 | {717303FD-D29A-45D1-A2A6-5D588245FD63}.Debug|Any CPU.Build.0 = Debug|Any CPU
117 | {717303FD-D29A-45D1-A2A6-5D588245FD63}.Release|Any CPU.ActiveCfg = Release|Any CPU
118 | {717303FD-D29A-45D1-A2A6-5D588245FD63}.Release|Any CPU.Build.0 = Release|Any CPU
119 | {717303FD-D29A-45D1-A2A6-5D588245FD63}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
120 | {717303FD-D29A-45D1-A2A6-5D588245FD63}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
121 | {717303FD-D29A-45D1-A2A6-5D588245FD63}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
122 | {717303FD-D29A-45D1-A2A6-5D588245FD63}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
123 | {717303FD-D29A-45D1-A2A6-5D588245FD63}.Debug|iPhone.ActiveCfg = Debug|Any CPU
124 | {717303FD-D29A-45D1-A2A6-5D588245FD63}.Debug|iPhone.Build.0 = Debug|Any CPU
125 | {717303FD-D29A-45D1-A2A6-5D588245FD63}.Release|iPhone.ActiveCfg = Release|Any CPU
126 | {717303FD-D29A-45D1-A2A6-5D588245FD63}.Release|iPhone.Build.0 = Release|Any CPU
127 | {1D7BD4CF-ED08-4FDA-A043-0C94452B3D48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
128 | {1D7BD4CF-ED08-4FDA-A043-0C94452B3D48}.Debug|Any CPU.Build.0 = Debug|Any CPU
129 | {1D7BD4CF-ED08-4FDA-A043-0C94452B3D48}.Release|Any CPU.ActiveCfg = Release|Any CPU
130 | {1D7BD4CF-ED08-4FDA-A043-0C94452B3D48}.Release|Any CPU.Build.0 = Release|Any CPU
131 | {1D7BD4CF-ED08-4FDA-A043-0C94452B3D48}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
132 | {1D7BD4CF-ED08-4FDA-A043-0C94452B3D48}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
133 | {1D7BD4CF-ED08-4FDA-A043-0C94452B3D48}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
134 | {1D7BD4CF-ED08-4FDA-A043-0C94452B3D48}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
135 | {1D7BD4CF-ED08-4FDA-A043-0C94452B3D48}.Debug|iPhone.ActiveCfg = Debug|Any CPU
136 | {1D7BD4CF-ED08-4FDA-A043-0C94452B3D48}.Debug|iPhone.Build.0 = Debug|Any CPU
137 | {1D7BD4CF-ED08-4FDA-A043-0C94452B3D48}.Release|iPhone.ActiveCfg = Release|Any CPU
138 | {1D7BD4CF-ED08-4FDA-A043-0C94452B3D48}.Release|iPhone.Build.0 = Release|Any CPU
139 | EndGlobalSection
140 | GlobalSection(NestedProjects) = preSolution
141 | {8BECF4A6-FBF0-417B-B142-AD92ED4933B5} = {51416960-B20E-42AF-BA41-F5A153DACE30}
142 | {36188102-875F-4E53-8936-53AB3AAD3F29} = {8080F2A5-7F12-4F26-96AF-1E3FEA7D4DD4}
143 | {FA21DBBE-A29E-4363-9EC3-2AF620CBB870} = {51416960-B20E-42AF-BA41-F5A153DACE30}
144 | {717303FD-D29A-45D1-A2A6-5D588245FD63} = {51416960-B20E-42AF-BA41-F5A153DACE30}
145 | {FA35DD42-38FD-4080-830A-D30462AAD69E} = {A231AC6D-2874-413B-9CFF-E42B0EF3F487}
146 | {1F6DACAE-A220-42EE-94A6-2B05F673A164} = {A231AC6D-2874-413B-9CFF-E42B0EF3F487}
147 | {2C9D3E04-20E9-48C7-A8DB-0D1A2F6948C8} = {A231AC6D-2874-413B-9CFF-E42B0EF3F487}
148 | {1D7BD4CF-ED08-4FDA-A043-0C94452B3D48} = {A231AC6D-2874-413B-9CFF-E42B0EF3F487}
149 | EndGlobalSection
150 | EndGlobal
151 |
--------------------------------------------------------------------------------
/GuardedActions/Commands/Actions/Contracts/IAction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GuardedActions.Commands.Actions.Contracts
4 | {
5 | public interface IAction : IDisposable
6 | {
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/GuardedActions/Commands/Actions/Contracts/IGuardedAction.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using GuardedActions.Contracts;
3 |
4 | namespace GuardedActions.Commands.Actions.Contracts
5 | {
6 | public interface IGuardedAction : IAction
7 | {
8 | Task ExecuteGuarded(TParameter parameter);
9 | }
10 |
11 | public interface IGuardedAction : IAction
12 | {
13 | Task ExecuteGuarded();
14 | }
15 |
16 | public interface IGuardedDataContextAction : IGuardedAction, IDataContext
17 | where TDataContext : class
18 | {
19 | void RegisterDataContext(TDataContext dataContext);
20 | }
21 |
22 | public interface IGuardedDataContextAction : IGuardedAction, IDataContext
23 | where TDataContext : class
24 | {
25 | void RegisterDataContext(TDataContext dataContext);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/GuardedActions/Commands/Actions/Contracts/IGuardedResultAction.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using GuardedActions.Contracts;
3 |
4 | namespace GuardedActions.Commands.Actions.Contracts
5 | {
6 | public interface IGuardedResultAction : IAction
7 | {
8 | Task ExecuteGuarded(TParameter parameter);
9 | }
10 |
11 | public interface IGuardedResultAction : IAction
12 | {
13 | Task ExecuteGuarded();
14 | }
15 |
16 | public interface IGuardedDataContextResultAction : IGuardedResultAction, IDataContext
17 | where TDataContext : class
18 | {
19 | void RegisterDataContext(TDataContext dataContext);
20 | }
21 |
22 | public interface IGuardedDataContextResultAction : IGuardedResultAction, IDataContext
23 | where TDataContext : class
24 | {
25 | void RegisterDataContext(TDataContext dataContext);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/GuardedActions/Commands/Actions/GuardedAction.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using GuardedActions.Commands.Actions.Contracts;
3 | using GuardedActions.Commands.Contracts;
4 | using System;
5 | using GuardedActions.IoC;
6 |
7 | namespace GuardedActions.Commands.Actions
8 | {
9 | public abstract class GuardedAction : IGuardedAction
10 | {
11 | protected GuardedAction()
12 | {
13 | // See if DI could be used
14 | ExceptionGuard = IoCRegistration.Instance.GetService();
15 | //Messenger = ??
16 | }
17 |
18 | protected IExceptionGuard ExceptionGuard { get; private set; }
19 | //TODO find some other solution to inject a messenger or something
20 | //protected IMvxMessenger Messenger { get; private set; }
21 |
22 | protected abstract Task Execute();
23 |
24 | public async Task ExecuteGuarded()
25 | {
26 | await ExceptionGuard.Guard(
27 | this,
28 | async () => await Execute(),
29 | ExecuteAfter
30 | );
31 | }
32 |
33 | protected virtual Task ExecuteAfter() => Task.CompletedTask;
34 |
35 | public virtual void Dispose()
36 | {
37 | ExceptionGuard = null;
38 | //Messenger = null;
39 | }
40 | }
41 |
42 | public abstract class GuardedAction : IGuardedAction
43 | {
44 | protected GuardedAction()
45 | {
46 | ExceptionGuard = IoCRegistration.Instance.GetService();
47 | //Messenger = ??
48 | }
49 |
50 | protected IExceptionGuard ExceptionGuard { get; private set; }
51 | //protected IMvxMessenger Messenger { get; private set; }
52 |
53 | protected abstract Task Execute(TParameter parameter);
54 |
55 | public async Task ExecuteGuarded(TParameter parameter)
56 | {
57 | await ExceptionGuard.Guard(
58 | this,
59 | async () => await Execute(parameter),
60 | ExecuteAfter
61 | );
62 | }
63 |
64 | protected virtual Task ExecuteAfter() => Task.CompletedTask;
65 |
66 | public virtual void Dispose()
67 | {
68 | ExceptionGuard = null;
69 | //Messenger = null;
70 | }
71 | }
72 |
73 | public abstract class GuardedDataContextAction : GuardedAction, IGuardedDataContextAction
74 | where TDataContext : class
75 | {
76 | public virtual void RegisterDataContext(TDataContext dataContext) => DataContext = dataContext;
77 |
78 | public TDataContext DataContext { get; private set; }
79 |
80 | public new Task ExecuteGuarded()
81 | {
82 | if (DataContext == null)
83 | throw new InvalidOperationException($"{GetType().FullName}.{nameof(ExecuteGuarded)}: {nameof(DataContext)} cannot be null make sure to register the {nameof(DataContext)} by calling the {nameof(RegisterDataContext)} method before you call the {nameof(ExecuteGuarded)} method. Maybe look if you need to override the RegisterDataContext on your command builder class and pass the data source trough to this instance.");
84 |
85 | return base.ExecuteGuarded();
86 | }
87 |
88 | public override void Dispose()
89 | {
90 | base.Dispose();
91 | DataContext = null;
92 | }
93 | }
94 |
95 | public abstract class GuardedDataContextAction : GuardedAction, IGuardedDataContextAction
96 | where TDataContext : class
97 | {
98 | public virtual void RegisterDataContext(TDataContext dataContext) => DataContext = dataContext;
99 |
100 | public TDataContext DataContext { get; private set; }
101 |
102 | public new Task ExecuteGuarded(TParameter parameter)
103 | {
104 | if (DataContext == null)
105 | throw new InvalidOperationException($"{GetType().FullName}.{nameof(ExecuteGuarded)}({nameof(TParameter)}): {nameof(DataContext)} cannot be null make sure to register the {nameof(DataContext)} by calling the {nameof(RegisterDataContext)} method before you call the {nameof(ExecuteGuarded)} method. Maybe look if you need to override the RegisterDataContext on your command builder class and pass the data source trough to this instance.");
106 |
107 | return base.ExecuteGuarded(parameter);
108 | }
109 |
110 | public override void Dispose()
111 | {
112 | base.Dispose();
113 | DataContext = null;
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/GuardedActions/Commands/Actions/GuardedResultAction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using GuardedActions.Commands.Actions.Contracts;
4 | using GuardedActions.Commands.Contracts;
5 | using GuardedActions.IoC;
6 |
7 | namespace GuardedActions.Commands.Actions
8 | {
9 | public abstract class GuardedResultAction : IGuardedResultAction
10 | {
11 | protected GuardedResultAction()
12 | {
13 | ExceptionGuard = IoCRegistration.Instance.GetService();
14 | }
15 |
16 | protected IExceptionGuard ExceptionGuard { get; private set; }
17 |
18 | protected abstract Task Execute();
19 |
20 | public async Task ExecuteGuarded()
21 | {
22 | return await ExceptionGuard.Guard(
23 | this,
24 | async () => await Execute(),
25 | ExecuteAfter
26 | );
27 | }
28 |
29 | protected virtual Task ExecuteAfter() => Task.CompletedTask;
30 |
31 | public virtual void Dispose()
32 | {
33 | ExceptionGuard = null;
34 | }
35 | }
36 |
37 | public abstract class GuardedResultAction : IGuardedResultAction
38 | {
39 | protected GuardedResultAction()
40 | {
41 | ExceptionGuard = IoCRegistration.Instance.GetService();
42 | }
43 |
44 | protected IExceptionGuard ExceptionGuard { get; private set; }
45 |
46 | protected abstract Task Execute(TParameter parameter);
47 |
48 | public async Task ExecuteGuarded(TParameter parameter)
49 | {
50 | return await ExceptionGuard.Guard(
51 | this,
52 | async () => await Execute(parameter),
53 | ExecuteAfter
54 | );
55 | }
56 |
57 | protected virtual Task ExecuteAfter() => Task.CompletedTask;
58 |
59 | public virtual void Dispose()
60 | {
61 | ExceptionGuard = null;
62 | }
63 | }
64 |
65 | public abstract class GuardedDataContextResultAction : GuardedResultAction,
66 | IGuardedDataContextResultAction
67 | where TDataContext : class
68 | {
69 | protected GuardedDataContextResultAction()
70 | {
71 | }
72 |
73 | public new Task ExecuteGuarded()
74 | {
75 | if (DataContext == null)
76 | throw new InvalidOperationException($"{GetType().FullName}.{nameof(ExecuteGuarded)}(): {nameof(DataContext)} cannot be null make sure to register the {nameof(DataContext)} by calling the {nameof(RegisterDataContext)} method before you call the {nameof(ExecuteGuarded)} method. Maybe look if you need to override the RegisterDataContext on your command builder class and pass the data source trough to this instance.");
77 |
78 | return base.ExecuteGuarded();
79 | }
80 |
81 | public void RegisterDataContext(TDataContext dataContext) => DataContext = dataContext;
82 |
83 | public TDataContext DataContext { get; private set; }
84 |
85 | public virtual void Dispose()
86 | {
87 | base.Dispose();
88 | DataContext = null;
89 | }
90 | }
91 |
92 | public abstract class GuardedDataContextResultAction : GuardedResultAction,
93 | IGuardedDataContextResultAction
94 | where TDataContext : class
95 | {
96 | protected GuardedDataContextResultAction()
97 | {
98 | }
99 |
100 | public new Task ExecuteGuarded(TParameter parameter)
101 | {
102 | if (DataContext == null)
103 | throw new InvalidOperationException($"{GetType().FullName}.{nameof(ExecuteGuarded)}({nameof(TParameter)}): {nameof(DataContext)} cannot be null make sure to register the {nameof(DataContext)} by calling the {nameof(RegisterDataContext)} method before you call the {nameof(ExecuteGuarded)} method. Maybe look if you need to override the RegisterDataContext on your command builder class and pass the data source trough to this instance.");
104 |
105 | return base.ExecuteGuarded(parameter);
106 | }
107 |
108 | public void RegisterDataContext(TDataContext dataContext) => DataContext = dataContext;
109 |
110 | public TDataContext DataContext { get; private set; }
111 |
112 | public override void Dispose()
113 | {
114 | base.Dispose();
115 | DataContext = null;
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/GuardedActions/Commands/AsyncGuardedCommandBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using AsyncAwaitBestPractices.MVVM;
6 | using GuardedActions.Commands.Contracts;
7 | using GuardedActions.IoC;
8 |
9 | namespace GuardedActions.Commands
10 | {
11 | public abstract class AsyncGuardedCommandBuilder : IAsyncGuardedCommandBuilder
12 | {
13 | protected Queue InvokeAfterCommandExecutedTaskQueue { get; } = new Queue();
14 | protected Queue InvokeBeforeCommandExecutedTaskQueue { get; } = new Queue();
15 | protected bool CommandBeingExecuted { get; set; }
16 | protected Func CanExecuteFunction { get; set; }
17 |
18 | protected AsyncGuardedCommandBuilder()
19 | {
20 | ExceptionGuard = IoCRegistration.Instance.GetService();
21 | }
22 |
23 | protected virtual bool ShouldNotifyAboutLongOperation { get; } = true;
24 |
25 | public IExceptionGuard ExceptionGuard { get; protected set; }
26 |
27 | public IAsyncGuardedCommandBuilder EnqueueAfterCommandExecuted(Action taskToInvoke)
28 | {
29 | InvokeAfterCommandExecutedTaskQueue.Enqueue(taskToInvoke);
30 | return this;
31 | }
32 |
33 | public IAsyncGuardedCommandBuilder EnqueueBeforeCommandExecuted(Action taskToInvoke)
34 | {
35 | InvokeBeforeCommandExecutedTaskQueue.Enqueue(taskToInvoke);
36 | return this;
37 | }
38 |
39 | public AsyncGuardedCommandBuilder ConfigureCanExecute(Func canExecute)
40 | {
41 | CanExecuteFunction = canExecute;
42 | return this;
43 | }
44 |
45 | public IAsyncCommand BuildCommand()
46 | {
47 | IAsyncCommand command = null;
48 |
49 | // ReSharper disable once AccessToModifiedClosure
50 | command = new AsyncCommand(() => BuildCommandBody(command), _ =>
51 | {
52 | if (CanExecute())
53 | return !CommandBeingExecuted;
54 |
55 | return false;
56 | });
57 |
58 | return command;
59 | }
60 |
61 | protected virtual async Task BuildCommandBody(IAsyncCommand command)
62 | {
63 | await ExceptionGuard.Guard(this,
64 | async () =>
65 | {
66 | CommandBeingExecuted = true;
67 |
68 | while (InvokeBeforeCommandExecutedTaskQueue.Count > 0)
69 | {
70 | await Task.Run(InvokeBeforeCommandExecutedTaskQueue.Dequeue());
71 | }
72 |
73 | command.RaiseCanExecuteChanged();
74 |
75 | await ExecuteCommandAction();
76 | },
77 | async () =>
78 | {
79 | CommandBeingExecuted = false;
80 | command.RaiseCanExecuteChanged();
81 | Finally();
82 |
83 | while (InvokeAfterCommandExecutedTaskQueue.Count > 0)
84 | {
85 | await Task.Run(InvokeAfterCommandExecutedTaskQueue.Dequeue());
86 | }
87 | }
88 | );
89 | }
90 |
91 | protected virtual void Finally()
92 | {
93 | }
94 |
95 | protected abstract Task ExecuteCommandAction();
96 |
97 | protected virtual bool CanExecute()
98 | {
99 | return CanExecuteFunction?.Invoke() != false;
100 | }
101 |
102 | public virtual void Dispose()
103 | {
104 | ExceptionGuard = null;
105 | }
106 | }
107 |
108 | public abstract class AsyncGuardedCommandBuilder : IAsyncGuardedCommandBuilder
109 | {
110 | protected Queue InvokeAfterCommandExecutedTaskQueue { get; } = new Queue();
111 | protected Queue InvokeBeforeCommandExecutedTaskQueue { get; } = new Queue();
112 | protected bool CommandBeingExecuted { get; set; }
113 | protected Func CanExecuteFunction { get; set; }
114 |
115 | protected AsyncGuardedCommandBuilder()
116 | {
117 | ExceptionGuard = IoCRegistration.Instance.GetService();
118 | }
119 |
120 | protected virtual bool ShouldNotifyAboutLongOperation { get; } = true;
121 | public IExceptionGuard ExceptionGuard { get; protected set; }
122 |
123 | public IAsyncGuardedCommandBuilder EnqueueAfterCommandExecuted(Action taskToInvoke)
124 | {
125 | InvokeAfterCommandExecutedTaskQueue.Enqueue(taskToInvoke);
126 | return this;
127 | }
128 |
129 | public IAsyncGuardedCommandBuilder EnqueueBeforeCommandExecuted(Action taskToInvoke)
130 | {
131 | InvokeBeforeCommandExecutedTaskQueue.Enqueue(taskToInvoke);
132 | return this;
133 | }
134 |
135 | public AsyncGuardedCommandBuilder ConfigureCanExecute(Func canExecute)
136 | {
137 | CanExecuteFunction = canExecute;
138 | return this;
139 | }
140 |
141 | public IAsyncCommand BuildCommand()
142 | {
143 | IAsyncCommand command = null;
144 |
145 | command = new AsyncCommand(async model => await BuildCommandBody(command, model), p =>
146 | {
147 | if (p is TCommandParameter commandParameter)
148 | {
149 | var canExecute = CanExecute(commandParameter);
150 | if (canExecute)
151 | {
152 | return !CommandBeingExecuted;
153 | }
154 | }
155 | else
156 | {
157 | // This should never happen
158 | }
159 | return false;
160 | });
161 |
162 | return command;
163 | }
164 |
165 | protected virtual async Task BuildCommandBody(IAsyncCommand command, TCommandParameter model)
166 | {
167 | await ExceptionGuard.Guard(this,
168 | async () =>
169 | {
170 | CommandBeingExecuted = true;
171 |
172 | while (InvokeBeforeCommandExecutedTaskQueue.Any())
173 | {
174 | await Task.Run(InvokeBeforeCommandExecutedTaskQueue.Dequeue());
175 | }
176 |
177 | command.RaiseCanExecuteChanged();
178 |
179 | await ExecuteCommandAction(model);
180 | },
181 | async () =>
182 | {
183 | CommandBeingExecuted = false;
184 | command.RaiseCanExecuteChanged();
185 | Finally();
186 |
187 | while (InvokeAfterCommandExecutedTaskQueue.Any())
188 | {
189 | await Task.Run(InvokeAfterCommandExecutedTaskQueue.Dequeue());
190 | }
191 | }
192 | );
193 | }
194 |
195 | protected virtual void Finally()
196 | {
197 | }
198 |
199 | protected virtual bool CanExecute(TCommandParameter item)
200 | {
201 | return CanExecuteFunction == null || CanExecuteFunction.Invoke(item);
202 | }
203 |
204 | protected abstract Task ExecuteCommandAction(TCommandParameter item);
205 |
206 | public virtual void Dispose()
207 | {
208 | ExceptionGuard = null;
209 | }
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/GuardedActions/Commands/AsyncGuardedDataContextCommandBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using AsyncAwaitBestPractices.MVVM;
4 | using GuardedActions.Commands.Contracts;
5 |
6 | namespace GuardedActions.Commands
7 | {
8 | public abstract class AsyncGuardedDataContextCommandBuilder : AsyncGuardedCommandBuilder, IAsyncGuardedDataContextCommandBuilder where TDataContext : class
9 | {
10 | public TDataContext DataContext { get; private set; }
11 |
12 | public virtual IAsyncGuardedDataContextCommandBuilder RegisterDataContext(TDataContext dataContext)
13 | {
14 | if (dataContext == null)
15 | {
16 | // TODO Add logging
17 | }
18 |
19 | DataContext = dataContext;
20 | return this;
21 | }
22 |
23 | public new IAsyncCommand BuildCommand()
24 | {
25 | if (DataContext == null)
26 | throw new InvalidOperationException($"{GetType().FullName}.{nameof(BuildCommand)}<{nameof(TCommandParameter)}>(): {nameof(DataContext)} cannot be null make sure to register the {nameof(DataContext)} by calling the {nameof(RegisterDataContext)} method before you call the {nameof(BuildCommand)} method.");
27 |
28 | return base.BuildCommand();
29 | }
30 |
31 | protected override Task BuildCommandBody(IAsyncCommand command, TCommandParameter model)
32 | {
33 | if (DataContext == null)
34 | {
35 | // TODO: Find framework independent solution
36 | //Messenger.Publish(new ExceptionMessage(this, new DataContextNotRegisteredForCommandBuilderException(GetType(), typeof(TDataContext))));
37 | return Task.CompletedTask;
38 | }
39 |
40 | return base.BuildCommandBody(command, model);
41 | }
42 |
43 | public override void Dispose()
44 | {
45 | base.Dispose();
46 | DataContext = null;
47 | }
48 | }
49 |
50 | public abstract class AsyncGuardedDataContextCommandBuilder : AsyncGuardedCommandBuilder, IAsyncGuardedDataContextCommandBuilder where TDataContext : class
51 | {
52 | public TDataContext DataContext { get; private set; }
53 |
54 | public virtual IAsyncGuardedDataContextCommandBuilder RegisterDataContext(TDataContext dataContext)
55 | {
56 | if (dataContext == null)
57 | {
58 | // TODO Add logging
59 | }
60 |
61 | DataContext = dataContext;
62 | return this;
63 | }
64 |
65 | public new IAsyncCommand BuildCommand()
66 | {
67 | if (DataContext == null)
68 | throw new InvalidOperationException($"{GetType().FullName}.{nameof(BuildCommand)}(): {nameof(DataContext)} cannot be null make sure to register the {nameof(DataContext)} by calling the {nameof(RegisterDataContext)} method before you call the {nameof(BuildCommand)} method.");
69 |
70 | return base.BuildCommand();
71 | }
72 |
73 | protected override Task BuildCommandBody(IAsyncCommand command)
74 | {
75 | if (DataContext == null)
76 | {
77 | // TODO: Find framework independent solution
78 | //Messenger.Publish(new ExceptionMessage(this, new DataContextNotRegisteredForCommandBuilderException(GetType(), typeof(TDataContext))));
79 | return Task.CompletedTask;
80 | }
81 |
82 | return base.BuildCommandBody(command);
83 | }
84 |
85 | public override void Dispose()
86 | {
87 | base.Dispose();
88 | DataContext = null;
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/GuardedActions/Commands/Contracts/IAsyncGuardedCommandBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using AsyncAwaitBestPractices.MVVM;
3 |
4 | namespace GuardedActions.Commands.Contracts
5 | {
6 | public interface IAsyncGuardedCommandBuilder : ICommandBuilder
7 | {
8 | IAsyncCommand BuildCommand();
9 |
10 | IAsyncGuardedCommandBuilder EnqueueAfterCommandExecuted(Action taskToInvoke);
11 | IAsyncGuardedCommandBuilder EnqueueBeforeCommandExecuted(Action taskToInvoke);
12 | }
13 |
14 | public interface IAsyncGuardedCommandBuilder : ICommandBuilder
15 | {
16 | IAsyncCommand BuildCommand();
17 |
18 | IAsyncGuardedCommandBuilder EnqueueAfterCommandExecuted(Action taskToInvoke);
19 | IAsyncGuardedCommandBuilder EnqueueBeforeCommandExecuted(Action taskToInvoke);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/GuardedActions/Commands/Contracts/IAsyncGuardedDataContextCommandBuilder.cs:
--------------------------------------------------------------------------------
1 | using GuardedActions.Contracts;
2 |
3 | namespace GuardedActions.Commands.Contracts
4 | {
5 | public interface IAsyncGuardedDataContextCommandBuilder : IAsyncGuardedCommandBuilder, IDataContext
6 | {
7 | IAsyncGuardedDataContextCommandBuilder RegisterDataContext(TDataContext dataContext);
8 | }
9 |
10 | public interface IAsyncGuardedDataContextCommandBuilder : IAsyncGuardedCommandBuilder, IDataContext
11 | {
12 | IAsyncGuardedDataContextCommandBuilder RegisterDataContext(TDataContext dataContext);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/GuardedActions/Commands/Contracts/ICommandBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GuardedActions.Commands.Contracts
4 | {
5 | public interface ICommandBuilder : IDisposable
6 | {
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/GuardedActions/Commands/Contracts/IExceptionGuard.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 | using GuardedActions.ExceptionHandlers.Contracts;
5 |
6 | namespace GuardedActions.Commands.Contracts
7 | {
8 | public interface IExceptionGuard
9 | {
10 | Task Guard(object sender, Func job, Func onFinally = null);
11 | Task Guard(object sender, Func> job, Func onFinally = null);
12 | List ExceptionHandlers { get; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/GuardedActions/Commands/ExceptionGuard.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using GuardedActions.ExceptionHandlers.Attributes;
6 | using GuardedActions.ExceptionHandlers.Defaults;
7 | using GuardedActions.ExceptionHandlers.Contracts;
8 | using GuardedActions.ExceptionHandlers.Extensions;
9 | using GuardedActions.Extensions;
10 | using GuardedActions.Commands.Contracts;
11 |
12 | namespace GuardedActions.Commands
13 | {
14 | public class ExceptionGuard : IExceptionGuard
15 | {
16 | private readonly IExceptionHandlingActionFactory _exceptionHandlingActionFactory;
17 |
18 | public ExceptionGuard(IEnumerable handlers, IExceptionHandlingActionFactory exceptionHandlingActionFactory)
19 | {
20 | _exceptionHandlingActionFactory = exceptionHandlingActionFactory;
21 |
22 | ExceptionHandlers.AddRange(handlers);
23 | }
24 |
25 | public List ExceptionHandlers { get; } = new List();
26 |
27 | private IExceptionHandler this[Type type] => ExceptionHandlers.SingleOrDefault(h =>
28 | h.GetType().GetInterfaces().FirstOrDefault(i => i == type) != null ||
29 | h.GetType() == type
30 | );
31 |
32 | public async Task Guard(object sender, Func job, Func onFinally = null)
33 | {
34 | try
35 | {
36 | if (job == null)
37 | throw new InvalidOperationException($"{GetType().FullName}.{nameof(Guard)}(): The {nameof(job)} provided cannot be null.");
38 |
39 | await job();
40 | }
41 | catch (Exception exception)
42 | {
43 | await HandleException(sender, exception);
44 | }
45 | finally
46 | {
47 | if (onFinally != null)
48 | {
49 | await onFinally();
50 | }
51 | }
52 | }
53 |
54 | public async Task Guard(object sender, Func> job, Func onFinally = null)
55 | {
56 | TResult result = default;
57 | try
58 | {
59 | if (job == null)
60 | throw new InvalidOperationException($"{GetType().FullName}.{nameof(Guard)}<{nameof(TResult)}>(): The {nameof(job)} provided cannot be null.");
61 |
62 | result = await job();
63 | }
64 | catch (Exception exception)
65 | {
66 | await HandleException(sender, exception);
67 | }
68 | finally
69 | {
70 | if (onFinally != null)
71 | {
72 | await onFinally();
73 | }
74 | }
75 |
76 | return result;
77 | }
78 |
79 | private async Task HandleException(object sender, Exception exception)
80 | {
81 | if (ExceptionHandlers?.Any() != true)
82 | return;
83 |
84 | GetHandlers(sender, exception, out var fallbackHandler, out var defaultHandlers, out var customHandlers, out var skipDefaultHandlers);
85 |
86 | var context = GetContextFromSender(sender);
87 |
88 | var exceptionHandlingAction = _exceptionHandlingActionFactory.Create(exception, context);
89 |
90 | foreach (var exceptionHandler in DetermineHandlersToUse(fallbackHandler, defaultHandlers, customHandlers, skipDefaultHandlers))
91 | {
92 | if (!await exceptionHandler.CanHandle(exceptionHandlingAction))
93 | continue;
94 |
95 | await exceptionHandler.Handle(exceptionHandlingAction);
96 |
97 | if (exceptionHandlingAction.HandlingShouldFinish)
98 | break;
99 | }
100 | }
101 |
102 | private void GetHandlers(object sender, Exception exception, out IExceptionHandler fallbackHandler, out List defaultHandlers, out List customHandlers, out bool skipDefaultHandlers)
103 | {
104 | fallbackHandler = null;
105 | defaultHandlers = new List();
106 | customHandlers = new List();
107 | skipDefaultHandlers = false;
108 |
109 | var customHandlersDictionary = new SortedDictionary>();
110 |
111 | foreach (var handler in ExceptionHandlers.Where(h => h.Implements(exception)))
112 | {
113 | if (handler.GetType().FullName == typeof(GeneralExceptionHandler).FullName)
114 | {
115 | fallbackHandler = handler;
116 | continue;
117 | }
118 |
119 | var defaultHandlerAttribute = handler.GetAttribute();
120 | if (defaultHandlerAttribute != null)
121 | {
122 | defaultHandlers.Add(handler);
123 | continue;
124 | }
125 |
126 | var handlingOnAttribute = handler.GetAttribute();
127 | if (handlingOnAttribute != null)
128 | {
129 | if (!handlingOnAttribute.TypesToHandleOn.Any(t => t.IsInstanceOfType(sender)))
130 | continue;
131 |
132 | if (handlingOnAttribute.SkipDefaultHandlers)
133 | skipDefaultHandlers = true;
134 |
135 | customHandlersDictionary.AddOrCreate(handlingOnAttribute.PriorityLevel, handler);
136 | }
137 | }
138 |
139 | foreach (var customHandlersDictionaryEntry in customHandlersDictionary.Reverse())
140 | {
141 | customHandlers.AddRange(customHandlersDictionaryEntry.Value);
142 | }
143 | }
144 |
145 | private static List DetermineHandlersToUse(IExceptionHandler fallbackHandler, List defaultHandlers, List customHandlers, bool skipDefaultHandlers)
146 | {
147 | var handlersToUse = new List();
148 |
149 | if (customHandlers.Count == 0 && defaultHandlers.Count == 0)
150 | {
151 | handlersToUse.Add(fallbackHandler);
152 | }
153 | else
154 | {
155 | if (!skipDefaultHandlers)
156 | {
157 | if (defaultHandlers.Count > 0)
158 | handlersToUse.AddRange(defaultHandlers);
159 | else
160 | handlersToUse.Add(fallbackHandler);
161 | }
162 |
163 | handlersToUse.AddRange(customHandlers);
164 | }
165 |
166 | return handlersToUse;
167 | }
168 |
169 | private static object? GetContextFromSender(object sender)
170 | {
171 | return sender?.GetType()?.GetProperties()?.FirstOrDefault(f => f.Name == "DataContext")?.GetValue(sender);
172 | }
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/GuardedActions/Contracts/IDataContext.cs:
--------------------------------------------------------------------------------
1 | namespace GuardedActions.Contracts
2 | {
3 | public interface IDataContext
4 | {
5 | TDataContext DataContext { get; }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/GuardedActions/ExceptionHandlers/Attributes/DefaultExceptionHandlerAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GuardedActions.ExceptionHandlers.Attributes
4 | {
5 | public class DefaultExceptionHandlerAttribute : Attribute
6 | {
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/GuardedActions/ExceptionHandlers/Attributes/ExceptionHandlerForAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GuardedActions.ExceptionHandlers.Attributes
4 | {
5 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
6 | public class ExceptionHandlerForAttribute : Attribute
7 | {
8 | public ExceptionHandlerForAttribute(int priorityLevel, bool skipDefaultHandlers, params Type[] typesToHandleOn)
9 | {
10 | PriorityLevel = priorityLevel;
11 | SkipDefaultHandlers = skipDefaultHandlers;
12 | TypesToHandleOn = typesToHandleOn;
13 | }
14 |
15 | public ExceptionHandlerForAttribute(bool skipDefaultHandlers, params Type[] typesToHandleOn)
16 | {
17 | SkipDefaultHandlers = skipDefaultHandlers;
18 | TypesToHandleOn = typesToHandleOn;
19 | }
20 |
21 | public ExceptionHandlerForAttribute(int priorityLevel, params Type[] typesToHandleOn)
22 | {
23 | PriorityLevel = priorityLevel;
24 | TypesToHandleOn = typesToHandleOn;
25 | }
26 |
27 | public ExceptionHandlerForAttribute(params Type[] typesToHandleOn)
28 | {
29 | PriorityLevel = 0;
30 | TypesToHandleOn = typesToHandleOn ?? throw new ArgumentNullException(nameof(typesToHandleOn));
31 | }
32 |
33 | public int PriorityLevel { get; }
34 | public bool SkipDefaultHandlers { get; }
35 | public Type[] TypesToHandleOn { get; }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/GuardedActions/ExceptionHandlers/Contracts/IExceptionHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 |
4 | namespace GuardedActions.ExceptionHandlers.Contracts
5 | {
6 | public interface IExceptionHandler
7 | {
8 | Task Handle(IExceptionHandlingAction exceptionHandlingAction);
9 | Task CanHandle(IExceptionHandlingAction exceptionHandlingAction);
10 | }
11 |
12 | public interface IExceptionHandler : IExceptionHandler
13 | where TException : Exception
14 | {
15 | Task CanHandle(IExceptionHandlingAction exceptionHandlingAction);
16 | Task Handle(IExceptionHandlingAction exceptionHandlingAction);
17 | }
18 |
19 | public interface IExceptionHandler : IExceptionHandler
20 | where TException : Exception
21 | where TDataContext : class
22 | {
23 | Task CanHandle(IExceptionHandlingAction exceptionHandlingAction);
24 | Task Handle(IExceptionHandlingAction exceptionHandlingAction);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/GuardedActions/ExceptionHandlers/Contracts/IExceptionHandlingAction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GuardedActions.Contracts;
3 |
4 | namespace GuardedActions.ExceptionHandlers.Contracts
5 | {
6 | public interface IExceptionHandlingAction
7 | {
8 | bool HandlingShouldFinish { get; set; }
9 | }
10 |
11 | public interface IExceptionHandlingAction : IExceptionHandlingAction
12 | where TException : Exception
13 | {
14 | TException Exception { get; }
15 | }
16 |
17 | public interface IExceptionHandlingAction : IExceptionHandlingAction, IDataContext
18 | where TException : Exception
19 | where TDataContext : class
20 | {
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/GuardedActions/ExceptionHandlers/Contracts/IExceptionHandlingActionFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GuardedActions.ExceptionHandlers.Contracts
4 | {
5 | public interface IExceptionHandlingActionFactory
6 | {
7 | IExceptionHandlingAction Create(Exception exception, object context = null);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/GuardedActions/ExceptionHandlers/Defaults/GeneralExceptionHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Threading.Tasks;
4 | using GuardedActions.ExceptionHandlers.Attributes;
5 | using GuardedActions.ExceptionHandlers.Contracts;
6 |
7 | namespace GuardedActions.ExceptionHandlers.Defaults
8 | {
9 | [DefaultExceptionHandler]
10 | public class GeneralExceptionHandler : ExceptionHandler
11 | {
12 | public override Task Handle(IExceptionHandlingAction exceptionHandlingAction)
13 | {
14 | //TODO handle, display dialog, send to appcenter etc
15 | //TODO Jop: Maybe also generate a code to show in the dialog when QA criteria met so they can report the code and the dev can trace it's code easily in App Center.
16 | Debug.WriteLine(exceptionHandlingAction?.Exception);
17 | return Task.CompletedTask;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/GuardedActions/ExceptionHandlers/ExceptionHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using GuardedActions.ExceptionHandlers.Contracts;
4 |
5 | namespace GuardedActions.ExceptionHandlers
6 | {
7 | public abstract class ExceptionHandler : IExceptionHandler
8 | where TException : Exception
9 | {
10 | public virtual Task CanHandle(IExceptionHandlingAction exceptionHandlingAction) => Task.FromResult(exceptionHandlingAction?.Exception != null);
11 |
12 | public Task CanHandle(IExceptionHandlingAction exceptionHandlingAction) => CanHandle(exceptionHandlingAction as IExceptionHandlingAction);
13 |
14 | public abstract Task Handle(IExceptionHandlingAction exceptionHandlingAction);
15 |
16 | public Task Handle(IExceptionHandlingAction exceptionHandlingAction) => Handle(exceptionHandlingAction as IExceptionHandlingAction);
17 | }
18 |
19 | public abstract class ContextExceptionHandler : IExceptionHandler
20 | where TException : Exception
21 | where TDataContext : class
22 | {
23 | public virtual Task CanHandle(IExceptionHandlingAction exceptionHandlingAction) =>
24 | Task.FromResult(exceptionHandlingAction?.Exception != null && exceptionHandlingAction?.DataContext != null);
25 |
26 | public Task CanHandle(IExceptionHandlingAction exceptionHandlingAction) => CanHandle(exceptionHandlingAction as IExceptionHandlingAction);
27 |
28 | public abstract Task Handle(IExceptionHandlingAction exceptionHandlingAction);
29 |
30 | public Task Handle(IExceptionHandlingAction exceptionHandlingAction) => Handle(exceptionHandlingAction as IExceptionHandlingAction);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/GuardedActions/ExceptionHandlers/ExceptionHandlingAction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GuardedActions.ExceptionHandlers.Contracts;
3 |
4 | namespace GuardedActions.ExceptionHandlers
5 | {
6 | public class ExceptionHandlingAction : IExceptionHandlingAction
7 | where TException : Exception
8 | {
9 | public ExceptionHandlingAction(TException exception)
10 | {
11 | Exception = exception;
12 | }
13 |
14 | public bool HandlingShouldFinish { get; set; }
15 |
16 | public TException Exception { get; }
17 | }
18 |
19 | public class ExceptionHandlingAction : IExceptionHandlingAction
20 | where TException : Exception
21 | where TDataContext : class
22 | {
23 | public ExceptionHandlingAction(TException exception, TDataContext dataContext)
24 | {
25 | Exception = exception;
26 | DataContext = dataContext;
27 | }
28 |
29 | public bool HandlingShouldFinish { get; set; }
30 |
31 | public new TException Exception { get; }
32 |
33 | public TDataContext DataContext { get; }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/GuardedActions/ExceptionHandlers/ExceptionHandlingActionFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GuardedActions.ExceptionHandlers.Contracts;
3 |
4 | namespace GuardedActions.ExceptionHandlers
5 | {
6 | public class ExceptionHandlingActionFactory : IExceptionHandlingActionFactory
7 | {
8 | public IExceptionHandlingAction Create(Exception exception, object context = null)
9 | {
10 | if (exception == null)
11 | {
12 | // write log.
13 | return null;
14 | }
15 |
16 | if (context == null)
17 | {
18 | var genericType = typeof(ExceptionHandlingAction<>).MakeGenericType(exception.GetType());
19 |
20 | return Activator.CreateInstance(genericType, exception) as IExceptionHandlingAction;
21 | }
22 |
23 | var genericContextType = typeof(ExceptionHandlingAction<,>).MakeGenericType(exception.GetType(), context.GetType());
24 |
25 | return Activator.CreateInstance(genericContextType, exception, context) as IExceptionHandlingAction;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/GuardedActions/ExceptionHandlers/Extensions/ExceptionHandlerExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using GuardedActions.ExceptionHandlers.Contracts;
4 | using GuardedActions.Extensions;
5 |
6 | namespace GuardedActions.ExceptionHandlers.Extensions
7 | {
8 | public static class ExceptionHandlerExtensions
9 | {
10 | public static bool Implements(this IExceptionHandler exceptionHandler, Exception exception)
11 | {
12 | if (exceptionHandler == null)
13 | return false;
14 |
15 | var type = exceptionHandler.GetExceptionType();
16 | if (type == null)
17 | return false;
18 | return type.IsInstanceOfType(exception);
19 | }
20 |
21 | public static Type? GetExceptionType(this IExceptionHandler exceptionHandler)
22 | {
23 | if (exceptionHandler == null)
24 | return null;
25 |
26 | return exceptionHandler.GetType().GetImplementedInterfaces().FirstOrDefault(i =>
27 | i.Name.StartsWith(nameof(IExceptionHandler), StringComparison.Ordinal) &&
28 | i.IsGenericType
29 | )?.GenericTypeArguments[0];
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/GuardedActions/Extensions/AssemblyExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Reflection;
6 |
7 | namespace GuardedActions.Extensions
8 | {
9 | // TODO: Seperate NuGet?
10 | public static class AssemblyExtensions
11 | {
12 | private static readonly Dictionary> _assembliesTypes = new Dictionary>();
13 |
14 | public static IEnumerable GetCreatableTypes(this Assembly[] assemblies) => assemblies.AsEnumerable().GetCreatableTypes();
15 |
16 | public static IEnumerable GetCreatableTypes(this IEnumerable assemblies) => assemblies.SelectMany(GetCreatableTypes);
17 |
18 | public static IEnumerable GetCreatableTypes(this Assembly assembly)
19 | {
20 | if (assembly == null)
21 | return Array.Empty();
22 |
23 | if (!_assembliesTypes.ContainsKey(assembly.FullName))
24 | {
25 | var types = assembly
26 | .ExceptionSafeGetTypes()
27 | .Select(t => t.GetTypeInfo())
28 | .Where(t => !t.IsAbstract && t.DeclaredConstructors.Any(c => !c.IsStatic && c.IsPublic))
29 | .Select(t => t.AsType());
30 |
31 | _assembliesTypes.Add(assembly.FullName, types);
32 | }
33 |
34 | return _assembliesTypes[assembly.FullName];
35 | }
36 |
37 | public static IEnumerable GetCreatableTypes(this Assembly[] assemblies, Type inheritedFrom) => assemblies.AsEnumerable().GetCreatableTypes(inheritedFrom);
38 |
39 | public static IEnumerable GetCreatableTypes(this IEnumerable assemblies, Type inheritedFrom) => assemblies.SelectMany(a => a.GetCreatableTypes(inheritedFrom));
40 |
41 | public static IEnumerable GetCreatableTypes(this Assembly assembly, Type inheritedFrom)
42 | {
43 | if (assembly == null)
44 | return Array.Empty();
45 |
46 | return assembly.GetCreatableTypes().Inherits(inheritedFrom);
47 | }
48 |
49 | private static IEnumerable ExceptionSafeGetTypes(this Assembly assembly)
50 | {
51 | try
52 | {
53 | return assembly.GetTypes();
54 | }
55 | catch (ReflectionTypeLoadException ex)
56 | {
57 | // MvxLog.Instance can be null, when reflecting for Setup.cs
58 | // Check for null
59 | //...LogError($"ReflectionTypeLoadException masked during loading of {assembly.FullName} - error {ex.ToLongString()}");
60 |
61 | if (ex.LoaderExceptions != null)
62 | {
63 | foreach (var excp in ex.LoaderExceptions)
64 | {
65 | //...LogWarn(ex.Message);
66 | }
67 | }
68 |
69 | if (Debugger.IsAttached)
70 | Debugger.Break();
71 |
72 | return Array.Empty();
73 | }
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/GuardedActions/Extensions/AttributeExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 |
4 | namespace GuardedActions.Extensions
5 | {
6 | // TODO: Seperate NuGet?
7 | public static class AttributeExtensions
8 | {
9 | public static T GetAttribute(this object obj) where T: Attribute
10 | {
11 | if (obj == null)
12 | return null;
13 |
14 | return Attribute.GetCustomAttribute(obj.GetType(), typeof(T)) is T attr ? attr : default;
15 | }
16 |
17 | public static T GetAttribute(this Type type) where T : Attribute
18 | {
19 | return Attribute.GetCustomAttribute(type, typeof(T)) is T attr ? attr : default;
20 | }
21 |
22 | public static T GetAttribute(this Assembly assembly) where T : Attribute
23 | {
24 | return assembly.GetCustomAttribute();
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/GuardedActions/Extensions/DictionaryExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace GuardedActions.Extensions
4 | {
5 | public static class DictionaryExtensions
6 | {
7 | public static void AddOrCreate(this SortedDictionary> dictionary, TKey key, TValue value)
8 | {
9 | if (dictionary == null)
10 | return;
11 |
12 | if (!dictionary.ContainsKey(key))
13 | dictionary.Add(key, new List { value });
14 | else
15 | dictionary[key].Add(value);
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/GuardedActions/Extensions/ExceptionExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GuardedActions.Extensions
4 | {
5 | // TODO: Seperate NuGet?
6 | public static class ExceptionExtensions
7 | {
8 | public static string ToLongString(this Exception exception)
9 | {
10 | if (exception == null)
11 | return "null";
12 |
13 | if (exception.InnerException != null)
14 | {
15 | var innerExceptionText = exception.InnerException.ToLongString();
16 | return $"{exception.GetType().Name}: {exception.Message ?? "-"}\n\t{exception.StackTrace}\nInnerException was {innerExceptionText}";
17 | }
18 | return $"{exception.GetType().Name}: {exception.Message ?? "-"}\n\t{exception.StackTrace}";
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/GuardedActions/Extensions/StringExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace GuardedActions.Extensions
2 | {
3 | public static class StringExtensions
4 | {
5 | public static bool IsNull(this string source) => source == null;
6 | public static bool IsNullOrEmpty(this string source) => string.IsNullOrEmpty(source);
7 | public static bool IsNullOrWhiteSpace(this string source) => string.IsNullOrWhiteSpace(source);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/GuardedActions/Extensions/TypeExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using GuardedActions.IoC;
6 |
7 | namespace GuardedActions.Extensions
8 | {
9 | // TODO: Seperate NuGet?
10 | public static class TypeExtensions
11 | {
12 | public static IEnumerable Inherits(this IEnumerable types, Type baseType)
13 | {
14 | return types.Where(x => baseType.IsAssignableFrom(x));
15 | }
16 |
17 | public static IEnumerable Inherits(this IEnumerable types) => types.Inherits(typeof(TBase));
18 |
19 | public static IEnumerable EndingWith(this IEnumerable types, string endingWith)
20 | {
21 | return types.Where(x => x.Name.EndsWith(endingWith, StringComparison.Ordinal));
22 | }
23 |
24 | public static IEnumerable GetImplementedInterfaces(this Type type, bool excludeBaseTypeInterfaces = false)
25 | {
26 | if (type == null)
27 | return Array.Empty();
28 |
29 | var interfaces = type.GetTypeInfo().ImplementedInterfaces.Where(i => i != typeof(IDisposable)).ToList();
30 |
31 | if (!excludeBaseTypeInterfaces)
32 | return interfaces;
33 |
34 | var baseTypeInterfaces = type.BaseType.GetImplementedInterfaces();
35 | return interfaces.Except(baseTypeInterfaces);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/GuardedActions/GuardedActions.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/GuardedActions/IoC/IoCRegistration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using GuardedActions.Commands.Actions.Contracts;
4 | using GuardedActions.Commands.Contracts;
5 | using GuardedActions.ExceptionHandlers;
6 | using GuardedActions.ExceptionHandlers.Contracts;
7 | using GuardedActions.Extensions;
8 | using GuardedActions.Utils;
9 | using GuardedActions.Commands;
10 | using System.Linq;
11 |
12 | namespace GuardedActions.IoC
13 | {
14 | public abstract class IoCRegistration
15 | {
16 | private IEnumerable _createableTypes = Array.Empty();
17 |
18 | public static IoCRegistration Instance { get; private set; }
19 |
20 | protected IoCRegistration()
21 | {
22 | Instance = this;
23 | }
24 |
25 | public abstract bool CanRegister { get; }
26 |
27 | public abstract bool CanResolve { get; }
28 |
29 | public void Register(params string[] assemblyNames)
30 | {
31 | if (!CanRegister)
32 | throw new InvalidOperationException($"{GetType().FullName}: {CannotRegisterErrorMessage}.");
33 |
34 | DetermineCreatableTypes(assemblyNames);
35 |
36 | AddSweep(IoCRegistrationType.Transient);
37 |
38 | AddSweep(IoCRegistrationType.Transient);
39 |
40 | var exceptionHandlerTypes = AddSweep(IoCRegistrationType.Singleton);
41 |
42 | AddSingleton();
43 |
44 | AddSingleton(() =>
45 | {
46 | var factory = GetService();
47 | var handlers = exceptionHandlerTypes.Select(handlerType => GetService(handlerType)).ToList();
48 | return new ExceptionGuard(handlers, factory);
49 | });
50 | }
51 |
52 | private void DetermineCreatableTypes(string[] assemblyNames)
53 | {
54 | var assemblies = assemblyNames != null ? AssemblyUtils.GetRegistrationAssemblies(assemblyNames) : AppDomain.CurrentDomain.GetAssemblies();
55 |
56 | _createableTypes = assemblies.GetCreatableTypes() ?? Array.Empty();
57 | }
58 |
59 | protected IEnumerable AddSweep(string kind, IoCRegistrationType registrationType)
60 | {
61 | var types = _createableTypes.EndingWith(kind);
62 |
63 | AddTypes(types, registrationType);
64 |
65 | return types;
66 | }
67 |
68 | protected IEnumerable AddSweep(Type inheritedFrom, IoCRegistrationType registrationType)
69 | {
70 | var types = _createableTypes.Inherits(inheritedFrom);
71 |
72 | AddTypes(types, registrationType);
73 |
74 | return types;
75 | }
76 |
77 | protected IEnumerable AddSweep(IoCRegistrationType registrationType) => AddSweep(typeof(T), registrationType);
78 |
79 | private void AddTypes(IEnumerable types, IoCRegistrationType registrationType)
80 | {
81 | foreach (var type in types)
82 | {
83 | if (registrationType == IoCRegistrationType.Manual)
84 | continue;
85 |
86 | var implementing = type.GetImplementedInterfaces(true);
87 |
88 | if (registrationType == IoCRegistrationType.Transient)
89 | {
90 | foreach (var implementedType in implementing)
91 | {
92 | AddTransient(implementedType, type);
93 | }
94 | AddTransient(type);
95 | continue;
96 | }
97 |
98 | if (registrationType == IoCRegistrationType.Singleton)
99 | {
100 | foreach (var implementedType in implementing)
101 | {
102 | AddSingleton(implementedType, type);
103 | }
104 | AddSingleton(type);
105 | }
106 | }
107 | }
108 |
109 | public void AddTransient() where TServiceType : class => AddTransient(typeof(TServiceType));
110 |
111 | public void AddTransient(Type serviceType)
112 | {
113 | if (!CanRegister)
114 | throw new InvalidOperationException($"{GetType().FullName}.{nameof(AddTransient)}({nameof(Type)}): {CannotResolveErrorMessage}");
115 |
116 | AddTransientInternal(serviceType);
117 | }
118 |
119 | public abstract void AddTransientInternal(Type serviceType);
120 |
121 | public void AddTransient() where TContractType : class where TServiceType : class => AddTransient(typeof(TContractType), typeof(TServiceType));
122 |
123 | public void AddTransient(Type contractType, Type serviceType)
124 | {
125 | if (!CanRegister)
126 | throw new InvalidOperationException($"{GetType().FullName}.{nameof(AddTransient)}({nameof(Type)}, {nameof(Type)}): {CannotResolveErrorMessage}");
127 |
128 | AddTransientInternal(contractType, serviceType);
129 | }
130 |
131 | public abstract void AddTransientInternal(Type contractType, Type serviceType);
132 |
133 | public void AddSingleton() where TServiceType : class => AddSingleton(typeof(TServiceType));
134 |
135 | public void AddSingleton(Func constructor) where TServiceType : class
136 | {
137 | if (!CanRegister)
138 | throw new InvalidOperationException($"{GetType().FullName}.{nameof(AddSingleton)}<{nameof(TServiceType)}>({typeof(Func)}): {CannotResolveErrorMessage}");
139 |
140 | AddSingletonInternal(constructor);
141 | }
142 |
143 | public abstract void AddSingletonInternal(Func constructor) where TServiceType : class;
144 |
145 | public void AddSingleton(Type serviceType)
146 | {
147 | if (!CanRegister)
148 | throw new InvalidOperationException($"{GetType().FullName}.{nameof(AddSingleton)}({nameof(Type)}): {CannotResolveErrorMessage}");
149 |
150 | AddSingletonInternal(serviceType);
151 | }
152 |
153 | public abstract void AddSingletonInternal(Type serviceType);
154 |
155 | public void AddSingleton() where TContractType : class where TServiceType : class => AddSingleton(typeof(TContractType), typeof(TServiceType));
156 |
157 | public void AddSingleton(Type contractType, Type serviceType)
158 | {
159 | if (!CanRegister)
160 | throw new InvalidOperationException($"{GetType().FullName}.{nameof(AddSingleton)}({nameof(Type)}, {nameof(Type)}): {CannotResolveErrorMessage}");
161 |
162 | AddSingletonInternal(contractType, serviceType);
163 | }
164 |
165 | public abstract void AddSingletonInternal(Type contractType, Type serviceType);
166 |
167 | public TServiceType GetService() where TServiceType : class
168 | {
169 | if (!CanResolve)
170 | throw new InvalidOperationException($"{GetType().FullName}.{nameof(GetService)}<{nameof(TServiceType)}>: {CannotResolveErrorMessage}");
171 |
172 | return GetServiceInternal();
173 | }
174 |
175 | public abstract TServiceType GetServiceInternal() where TServiceType : class;
176 |
177 | public TServiceType GetService(Type serviceType) where TServiceType : class
178 | {
179 | if (!CanResolve)
180 | throw new InvalidOperationException($"{GetType().FullName}.{nameof(GetService)}<{nameof(TServiceType)}>({nameof(Type)}): {CannotResolveErrorMessage}");
181 |
182 | return GetServiceInternal(serviceType);
183 | }
184 |
185 | public abstract TServiceType GetServiceInternal(Type serviceType) where TServiceType : class;
186 |
187 | public virtual string CannotRegisterErrorMessage => "Registering your service is not possible please check your GuardedActions IoC setup implementation.";
188 |
189 | public virtual string CannotResolveErrorMessage => "Resolving your service is not possible please check your GuardedActions IoC setup implementation.";
190 | }
191 |
192 | public enum IoCRegistrationType
193 | {
194 | Manual,
195 | Transient,
196 | Singleton
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/GuardedActions/Utils/AssemblyUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 |
6 | namespace GuardedActions.Utils
7 | {
8 | public static class AssemblyUtils
9 | {
10 | public static IEnumerable GetRegistrationAssemblies(params string[] assemblyNames)
11 | {
12 | var assemblies = GetAssembliesWhereNameStartingWith(assemblyNames).ToList();
13 |
14 | assemblies.Add(Assembly.GetExecutingAssembly());
15 |
16 | return assemblies;
17 | }
18 |
19 | public static IEnumerable GetAssembliesWhereNameStartingWith(string assemblyName)
20 | {
21 | return AppDomain.CurrentDomain
22 | .GetAssemblies()
23 | .Where(assembly => assembly.GetName().Name.StartsWith(assemblyName, StringComparison.InvariantCulture));
24 | }
25 |
26 | public static IEnumerable GetAssembliesWhereNameStartingWith(params string[] assemblyNames)
27 | {
28 | return AppDomain.CurrentDomain
29 | .GetAssemblies()
30 | .Where(assembly =>
31 | assemblyNames.Any(assemblyName =>
32 | assembly.GetName().Name.StartsWith(assemblyName, StringComparison.InvariantCulture)));
33 | }
34 |
35 | public static Assembly GetAssemblyByName(string assemblyName)
36 | {
37 | return AppDomain.CurrentDomain
38 | .GetAssemblies()
39 | .SingleOrDefault(assembly => assembly.GetName().Name == assemblyName);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/GuardedActions/readme.txt:
--------------------------------------------------------------------------------
1 | ---------------------------------
2 | GuardedActions
3 | ---------------------------------
4 |
5 | A library to increase the error handling, testability and reusability for all your MVVM driven apps!
6 |
7 |
8 | using GuardedActions.NetCore;
9 | using GuardedActions.NetCore.Extensions;
10 |
11 | public class Startup
12 | {
13 | public static void Init()
14 | {
15 | var iocSetup = new GuardedActionsIoCSetup();
16 |
17 | var host = new HostBuilder()
18 | .ConfigureGuardedActions(iocSetup, "YourAssembliesStartWith")
19 | .Build()
20 | .ConnectGuardedActions(iocSetup);
21 | }
22 | }
23 |
24 |
25 | ---------------------------------
26 | Star on Github if this project helps you: https://github.com/Baseflow/GuardedActions
27 |
28 | Commercial support is available. Integration with your app or services, samples, feature request, etc. Email: hello@baseflow.com
29 | Powered by: https://baseflow.com
30 | ---------------------------------
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Baseflow
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Assets/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "AndroidAsset".
3 |
4 | These files will be deployed with your package and will be accessible using Android's
5 | AssetManager, like this:
6 |
7 | public class ReadAsset : Activity
8 | {
9 | protected override void OnCreate (Bundle bundle)
10 | {
11 | base.OnCreate (bundle);
12 |
13 | InputStream input = Assets.Open ("my_asset.txt");
14 | }
15 | }
16 |
17 | Additionally, some Android functions will automatically load asset files:
18 |
19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");
20 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/GuardedActionsPlayground.Droid.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | {1F6DACAE-A220-42EE-94A6-2B05F673A164}
7 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
8 | {c9e5eea5-ca05-42a1-839b-61506e0a37df}
9 | Library
10 | GuardedActionsPlayground.Droid
11 | GuardedActionsPlayground.Droid
12 | True
13 | True
14 | Resources\Resource.designer.cs
15 | Resource
16 | Properties\AndroidManifest.xml
17 | Resources
18 | Assets
19 | v9.0
20 | true
21 | true
22 | Xamarin.Android.Net.AndroidClientHandler
23 |
24 |
25 |
26 |
27 | true
28 | portable
29 | false
30 | bin\Debug
31 | DEBUG;
32 | prompt
33 | 4
34 | None
35 |
36 |
37 | true
38 | portable
39 | true
40 | bin\Release
41 | prompt
42 | 4
43 | true
44 | false
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | 3.1.5
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | {fa35dd42-38fd-4080-830a-d30462aad69e}
96 | GuardedActionsPlayground
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using Android.App;
4 | using Android.Content.PM;
5 | using Android.Runtime;
6 | using Android.Views;
7 | using Android.Widget;
8 | using Android.OS;
9 |
10 | namespace GuardedActionsPlayground.Droid
11 | {
12 | [Activity(Label = "GuardedActionsPlayground", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
13 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
14 | {
15 | protected override void OnCreate(Bundle savedInstanceState)
16 | {
17 | TabLayoutResource = Resource.Layout.Tabbar;
18 | ToolbarResource = Resource.Layout.Toolbar;
19 |
20 | base.OnCreate(savedInstanceState);
21 |
22 | Xamarin.Essentials.Platform.Init(this, savedInstanceState);
23 | global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
24 | LoadApplication(new App());
25 | }
26 | public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
27 | {
28 | Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
29 |
30 | base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Properties/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 | using Android.App;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("GuardedActionsPlayground.Droid")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("GuardedActionsPlayground.Droid")]
14 | [assembly: AssemblyCopyright("Copyright © 2014")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 | [assembly: ComVisible(false)]
18 |
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | [assembly: AssemblyVersion("1.0.0.0")]
26 | [assembly: AssemblyFileVersion("1.0.0.0")]
27 |
28 | // Add some common permissions, these can be removed if not needed
29 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)]
30 | [assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
31 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/AboutResources.txt:
--------------------------------------------------------------------------------
1 | Images, layout descriptions, binary blobs and string dictionaries can be included
2 | in your application as resource files. Various Android APIs are designed to
3 | operate on the resource IDs instead of dealing with images, strings or binary blobs
4 | directly.
5 |
6 | For example, a sample Android app that contains a user interface layout (main.xml),
7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
8 | would keep its resources in the "Resources" directory of the application:
9 |
10 | Resources/
11 | drawable-hdpi/
12 | icon.png
13 |
14 | drawable-ldpi/
15 | icon.png
16 |
17 | drawable-mdpi/
18 | icon.png
19 |
20 | layout/
21 | main.xml
22 |
23 | values/
24 | strings.xml
25 |
26 | In order to get the build system to recognize Android resources, set the build action to
27 | "AndroidResource". The native Android APIs do not operate directly with filenames, but
28 | instead operate on resource IDs. When you compile an Android application that uses resources,
29 | the build system will package the resources for distribution and generate a class called
30 | "Resource" that contains the tokens for each one of the resources included. For example,
31 | for the above Resources layout, this is what the Resource class would expose:
32 |
33 | public class Resource {
34 | public class drawable {
35 | public const int icon = 0x123;
36 | }
37 |
38 | public class layout {
39 | public const int main = 0x456;
40 | }
41 |
42 | public class strings {
43 | public const int first_string = 0xabc;
44 | public const int second_string = 0xbcd;
45 | }
46 | }
47 |
48 | You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main
49 | to reference the layout/main.xml file, or Resource.strings.first_string to reference the first
50 | string in the dictionary file values/strings.xml.
51 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/layout/Tabbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/layout/Toolbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-anydpi-v26/icon.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-anydpi-v26/icon_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-hdpi/icon.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-hdpi/launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-hdpi/launcher_foreground.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-mdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-mdpi/icon.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-mdpi/launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-mdpi/launcher_foreground.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-xhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-xhdpi/icon.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-xhdpi/launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-xhdpi/launcher_foreground.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-xxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-xxhdpi/icon.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-xxhdpi/launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-xxhdpi/launcher_foreground.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-xxxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-xxxhdpi/icon.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-xxxhdpi/launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.Droid/Resources/mipmap-xxxhdpi/launcher_foreground.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 | #3F51B5
5 | #303F9F
6 | #FF4081
7 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.Droid/Resources/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
24 |
27 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/.AssemblyAttributes.cs:
--------------------------------------------------------------------------------
1 | //
2 | using System;
3 | using System.Reflection;
4 | [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute("Xamarin.iOS,Version=v1.0", FrameworkDisplayName = "Xamarin.iOS")]
5 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace GuardedActionsPlayground.iOS
9 | {
10 | // The UIApplicationDelegate for the application. This class is responsible for launching the
11 | // User Interface of the application, as well as listening (and optionally responding) to
12 | // application events from iOS.
13 | [Register("AppDelegate")]
14 | public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
15 | {
16 | //
17 | // This method is invoked when the application has loaded and is ready to run. In this
18 | // method you should instantiate the window, load the UI into it and then make the window
19 | // visible.
20 | //
21 | // You have 17 seconds to return from this method, or iOS will terminate your application.
22 | //
23 | public override bool FinishedLaunching(UIApplication app, NSDictionary options)
24 | {
25 | global::Xamarin.Forms.Forms.Init();
26 | LoadApplication(new App());
27 |
28 | return base.FinishedLaunching(app, options);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "scale": "2x",
5 | "size": "20x20",
6 | "idiom": "iphone",
7 | "filename": "Icon40.png"
8 | },
9 | {
10 | "scale": "3x",
11 | "size": "20x20",
12 | "idiom": "iphone",
13 | "filename": "Icon60.png"
14 | },
15 | {
16 | "scale": "2x",
17 | "size": "29x29",
18 | "idiom": "iphone",
19 | "filename": "Icon58.png"
20 | },
21 | {
22 | "scale": "3x",
23 | "size": "29x29",
24 | "idiom": "iphone",
25 | "filename": "Icon87.png"
26 | },
27 | {
28 | "scale": "2x",
29 | "size": "40x40",
30 | "idiom": "iphone",
31 | "filename": "Icon80.png"
32 | },
33 | {
34 | "scale": "3x",
35 | "size": "40x40",
36 | "idiom": "iphone",
37 | "filename": "Icon120.png"
38 | },
39 | {
40 | "scale": "2x",
41 | "size": "60x60",
42 | "idiom": "iphone",
43 | "filename": "Icon120.png"
44 | },
45 | {
46 | "scale": "3x",
47 | "size": "60x60",
48 | "idiom": "iphone",
49 | "filename": "Icon180.png"
50 | },
51 | {
52 | "scale": "1x",
53 | "size": "20x20",
54 | "idiom": "ipad",
55 | "filename": "Icon20.png"
56 | },
57 | {
58 | "scale": "2x",
59 | "size": "20x20",
60 | "idiom": "ipad",
61 | "filename": "Icon40.png"
62 | },
63 | {
64 | "scale": "1x",
65 | "size": "29x29",
66 | "idiom": "ipad",
67 | "filename": "Icon29.png"
68 | },
69 | {
70 | "scale": "2x",
71 | "size": "29x29",
72 | "idiom": "ipad",
73 | "filename": "Icon58.png"
74 | },
75 | {
76 | "scale": "1x",
77 | "size": "40x40",
78 | "idiom": "ipad",
79 | "filename": "Icon40.png"
80 | },
81 | {
82 | "scale": "2x",
83 | "size": "40x40",
84 | "idiom": "ipad",
85 | "filename": "Icon80.png"
86 | },
87 | {
88 | "scale": "1x",
89 | "size": "76x76",
90 | "idiom": "ipad",
91 | "filename": "Icon76.png"
92 | },
93 | {
94 | "scale": "2x",
95 | "size": "76x76",
96 | "idiom": "ipad",
97 | "filename": "Icon152.png"
98 | },
99 | {
100 | "scale": "2x",
101 | "size": "83.5x83.5",
102 | "idiom": "ipad",
103 | "filename": "Icon167.png"
104 | },
105 | {
106 | "scale": "1x",
107 | "size": "1024x1024",
108 | "idiom": "ios-marketing",
109 | "filename": "Icon1024.png"
110 | }
111 | ],
112 | "properties": {},
113 | "info": {
114 | "version": 1,
115 | "author": "xcode"
116 | }
117 | }
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/GuardedActionsPlayground.iOS.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | iPhoneSimulator
6 | 8.0.30703
7 | 2.0
8 | {2C9D3E04-20E9-48C7-A8DB-0D1A2F6948C8}
9 | {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
10 | {6143fdea-f3c2-4a09-aafa-6e230626515e}
11 | Exe
12 | GuardedActionsPlayground.iOS
13 | Resources
14 | GuardedActionsPlayground.iOS
15 | true
16 | NSUrlSessionHandler
17 | automatic
18 |
19 |
20 | true
21 | full
22 | false
23 | bin\iPhoneSimulator\Debug
24 | DEBUG
25 | prompt
26 | 4
27 | x86_64
28 | None
29 | true
30 |
31 |
32 | none
33 | true
34 | bin\iPhoneSimulator\Release
35 | prompt
36 | 4
37 | None
38 | x86_64
39 |
40 |
41 | true
42 | full
43 | false
44 | bin\iPhone\Debug
45 | DEBUG
46 | prompt
47 | 4
48 | ARM64
49 | iPhone Developer
50 | true
51 | Entitlements.plist
52 | None
53 | -all
54 |
55 |
56 | none
57 | true
58 | bin\iPhone\Release
59 | prompt
60 | 4
61 | ARM64
62 | iPhone Developer
63 | Entitlements.plist
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | false
76 |
77 |
78 | false
79 |
80 |
81 | false
82 |
83 |
84 | false
85 |
86 |
87 | false
88 |
89 |
90 | false
91 |
92 |
93 | false
94 |
95 |
96 | false
97 |
98 |
99 | false
100 |
101 |
102 | false
103 |
104 |
105 | false
106 |
107 |
108 | false
109 |
110 |
111 | false
112 |
113 |
114 | false
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 | 3.1.5
130 |
131 |
132 |
133 |
134 | {fa35dd42-38fd-4080-830a-d30462aad69e}
135 | GuardedActionsPlayground
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIDeviceFamily
6 |
7 | 1
8 | 2
9 |
10 | UISupportedInterfaceOrientations
11 |
12 | UIInterfaceOrientationPortrait
13 | UIInterfaceOrientationLandscapeLeft
14 | UIInterfaceOrientationLandscapeRight
15 |
16 | UISupportedInterfaceOrientations~ipad
17 |
18 | UIInterfaceOrientationPortrait
19 | UIInterfaceOrientationPortraitUpsideDown
20 | UIInterfaceOrientationLandscapeLeft
21 | UIInterfaceOrientationLandscapeRight
22 |
23 | MinimumOSVersion
24 | 8.0
25 | CFBundleDisplayName
26 | GuardedActionsPlayground
27 | CFBundleIdentifier
28 | com.companyname.GuardedActionsPlayground
29 | CFBundleVersion
30 | 1.0
31 | UILaunchStoryboardName
32 | LaunchScreen
33 | CFBundleName
34 | GuardedActionsPlayground
35 | XSAppIconAssets
36 | Assets.xcassets/AppIcon.appiconset
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Main.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace GuardedActionsPlayground.iOS
9 | {
10 | public class Application
11 | {
12 | // This is the main entry point of the application.
13 | static void Main(string[] args)
14 | {
15 | // if you want to use a different Application Delegate class from "AppDelegate"
16 | // you can specify it here.
17 | UIApplication.Main(args, null, "AppDelegate");
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("GuardedActionsPlayground.iOS")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("GuardedActionsPlayground.iOS")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("72bdc44f-c588-44f3-b6df-9aace7daafdd")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Resources/Default-Portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Resources/Default-Portrait.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Resources/Default-Portrait@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Resources/Default-Portrait@2x.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Resources/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Resources/Default.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Resources/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baseflow/GuardedActions/79bd1997e13f287ee5c42e7cace11ac69bec498e/Playground/GuardedActionsPlayground.iOS/Resources/Default@2x.png
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground.iOS/Resources/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground/App.xaml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using GuardedActionsPlayground.Pages;
2 | using Xamarin.Forms;
3 |
4 | namespace GuardedActionsPlayground
5 | {
6 | public partial class App : Application
7 | {
8 | public App()
9 | {
10 | InitializeComponent();
11 |
12 | Startup.Init();
13 |
14 | MainPage = new MainPage();
15 | }
16 |
17 | protected override void OnStart()
18 | {
19 | }
20 |
21 | protected override void OnSleep()
22 | {
23 | }
24 |
25 | protected override void OnResume()
26 | {
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using Xamarin.Forms.Xaml;
2 |
3 | [assembly: XamlCompilation(XamlCompilationOptions.Compile)]
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground/GuardedActionsPlayground.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | true
6 | GuardedActionsPlayground
7 |
8 |
9 |
10 | portable
11 | true
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground/IoCRegistration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GuardedActions.NetCore.Extensions;
3 | using Microsoft.Extensions.DependencyInjection;
4 | using Microsoft.Extensions.Hosting;
5 |
6 | namespace GuardedActions.NetCore
7 | {
8 | public class IoCRegistration : IoC.IoCRegistration
9 | {
10 | private IServiceCollection? _serviceCollection;
11 | private IServiceProvider? _serviceProvider;
12 |
13 | public IoCRegistration SetServiceCollection(IServiceCollection serviceCollection)
14 | {
15 | _serviceCollection = serviceCollection ?? throw new ArgumentNullException(nameof(serviceCollection));
16 | return this;
17 | }
18 |
19 | public IoCRegistration SetServiceProvider(IServiceProvider serviceProvider)
20 | {
21 | _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
22 | return this;
23 | }
24 |
25 | public override void AddSingletonInternal(Func constructor) where TServiceType : class => _serviceCollection.AddSingleton((_) => constructor.Invoke());
26 |
27 | public override void AddSingletonInternal(Type serviceType) => _serviceCollection.AddSingleton(serviceType);
28 |
29 | public override void AddSingletonInternal(Type serviceType, Type implementationType) => _serviceCollection.AddSingleton(serviceType, implementationType);
30 |
31 | public override void AddTransientInternal(Type serviceType) => _serviceCollection.AddTransient(serviceType);
32 |
33 | public override void AddTransientInternal(Type serviceType, Type implementationType) => _serviceCollection.AddTransient(serviceType, implementationType);
34 |
35 | public override TServiceType GetServiceInternal() where TServiceType : class => _serviceProvider.GetService();
36 |
37 | public override TServiceType GetServiceInternal(Type serviceType) where TServiceType : class => _serviceProvider.GetService(serviceType);
38 |
39 | public override bool CanRegister => _serviceCollection != null;
40 |
41 | public override bool CanResolve => _serviceProvider != null;
42 |
43 | public override string CannotRegisterErrorMessage => $"Make sure you've called the {nameof(HostBuilderExtensions.ConfigureGuardedActions)} on the {nameof(IHostBuilder)} before building it.";
44 |
45 | public override string CannotResolveErrorMessage => $"Make sure you've called the {nameof(HostBuilderExtensions.ConnectGuardedActions)} on the {nameof(IHost)} after building the {nameof(IHostBuilder)}.";
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground/Pages/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground/Pages/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using GuardedActionsPlayground.Core.ViewModels;
3 | using Xamarin.Forms;
4 | using Microsoft.Extensions.DependencyInjection;
5 |
6 | namespace GuardedActionsPlayground.Pages
7 | {
8 | [DesignTimeVisible(false)]
9 | public partial class MainPage : ContentPage
10 | {
11 | public MainPage()
12 | {
13 | InitializeComponent();
14 |
15 | BindingContext = Startup.Services.GetService();
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using GuardedActions.Extensions;
4 | using GuardedActions.NetCore;
5 | using GuardedActions.NetCore.Extensions;
6 | using GuardedActionsPlayground.Core.Factories;
7 | using GuardedActionsPlayground.Core.Factories.Contracts;
8 | using GuardedActionsPlayground.Core.ViewModels;
9 | using Microsoft.Extensions.Configuration;
10 | using Microsoft.Extensions.DependencyInjection;
11 | using Microsoft.Extensions.Hosting;
12 | using Microsoft.Extensions.Logging;
13 | using Xamarin.Essentials;
14 |
15 | namespace GuardedActionsPlayground
16 | {
17 | public class Startup
18 | {
19 | public static IServiceProvider Services { get; set; }
20 |
21 | public static void Init()
22 | {
23 | var assembly = Assembly.GetExecutingAssembly();
24 | using var stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.appsettings.json");
25 |
26 | var iocSetup = new GuardedActionIoCSetup();
27 |
28 | #pragma warning disable IDISP001 // Dispose created.
29 | var host = new HostBuilder()
30 | .ConfigureHostConfiguration(c =>
31 | {
32 | c.AddCommandLine(new string[] { $"ContentRoot={FileSystem.AppDataDirectory}" });
33 | c.AddJsonStream(stream);
34 | })
35 | .ConfigureLogging((l) => l.AddConsole(o =>
36 | {
37 | o.DisableColors = true;
38 | }))
39 | .ConfigureServices(ConfigureServices)
40 | .ConfigureGuardedActions(iocSetup, nameof(GuardedActionsPlayground))
41 | .Build()
42 | .ConnectGuardedActions(iocSetup);
43 | #pragma warning restore IDISP001 // Dispose created.
44 |
45 | //Save our service provider so we can use it later.
46 | Services = host.Services;
47 | }
48 |
49 | private static void ConfigureServices(HostBuilderContext hostBuilderContext, IServiceCollection serviceCollection)
50 | {
51 | ConfigureViewModels(serviceCollection);
52 | ConfigureFactories(serviceCollection);
53 | }
54 |
55 | private static void ConfigureViewModels(IServiceCollection serviceCollection)
56 | {
57 | foreach (var viewModel in AppDomain.CurrentDomain.GetAssemblies().GetCreatableTypes(typeof(BaseViewModel)))
58 | {
59 | serviceCollection.AddTransient(viewModel);
60 | }
61 | }
62 |
63 | private static void ConfigureFactories(IServiceCollection serviceCollection)
64 | {
65 | serviceCollection.AddSingleton();
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Playground/GuardedActionsPlayground/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Hello": "World",
3 | "Environment": "Development",
4 | "Logging": {
5 | "IncludeScopes": false,
6 | "LogLevel": {
7 | "Default": "Debug",
8 | "System": "Information",
9 | "Microsoft": "Information"
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/Commands/Actions/Contracts/IDownloadUrlAction.cs:
--------------------------------------------------------------------------------
1 | using GuardedActions.Commands.Actions.Contracts;
2 | using GuardedActionsPlayground.Core.Models;
3 |
4 | namespace GuardedActionsPlayground.Core.Commands.Actions.Contracts
5 | {
6 | public interface IDownloadUrlAction : IGuardedDataContextAction
7 | {
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/Commands/Actions/Contracts/IPullDownloadListAction.cs:
--------------------------------------------------------------------------------
1 | using GuardedActions.Commands.Actions.Contracts;
2 | using GuardedActionsPlayground.Core.ViewModels;
3 |
4 | namespace GuardedActionsPlayground.Core.Commands.Actions.Contracts
5 | {
6 | public interface IPullDownloadListAction : IGuardedDataContextAction
7 | {
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/Commands/Actions/DownloadUrlAction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Threading.Tasks;
4 | using GuardedActions.Commands.Actions;
5 | using GuardedActionsPlayground.Core.Commands.Actions.Contracts;
6 | using GuardedActionsPlayground.Core.Models;
7 |
8 | namespace GuardedActionsPlayground.Core.Commands.Actions
9 | {
10 | public class DownloadUrlAction : GuardedDataContextAction, IDownloadUrlAction
11 | {
12 | protected override Task Execute()
13 | {
14 | var correctUrl = Uri.TryCreate(DataContext.Url, UriKind.Absolute, out var result);
15 |
16 | if (!correctUrl)
17 | throw new WebException("Manually triggered");
18 |
19 | DataContext.IsDownloaded = true;
20 |
21 | return Task.CompletedTask;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/Commands/Actions/ExceptionHandlers/DownloadUrlActionWebExceptionHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Net;
2 | using System.Threading.Tasks;
3 | using GuardedActions.ExceptionHandlers;
4 | using GuardedActions.ExceptionHandlers.Attributes;
5 | using GuardedActions.ExceptionHandlers.Contracts;
6 | using GuardedActionsPlayground.Core.Commands.Actions.Contracts;
7 | using GuardedActionsPlayground.Core.Models;
8 |
9 | namespace GuardedActionsPlayground.Core.Commands.Actions.ExceptionHandlers
10 | {
11 | [ExceptionHandlerFor(typeof(IDownloadUrlAction))]
12 | public class DownloadUrlActionWebExceptionHandler : ContextExceptionHandler
13 | {
14 | public override Task Handle(IExceptionHandlingAction exceptionHandlingAction)
15 | {
16 | if (exceptionHandlingAction?.DataContext != null)
17 | {
18 | exceptionHandlingAction.DataContext.ErrorMessage = exceptionHandlingAction?.Exception?.Message;
19 | }
20 |
21 | return Task.CompletedTask;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/Commands/Actions/PullDownloadListAction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 | using GuardedActions.Commands.Actions;
5 | using GuardedActionsPlayground.Core.Commands.Actions.Contracts;
6 | using GuardedActionsPlayground.Core.Factories.Contracts;
7 | using GuardedActionsPlayground.Core.Models;
8 | using GuardedActionsPlayground.Core.ViewModels;
9 |
10 | namespace GuardedActionsPlayground.Core.Commands.Actions
11 | {
12 | public class PullDownloadListAction : GuardedDataContextAction, IPullDownloadListAction
13 | {
14 | private readonly IDownloadFactory _downloadFactory;
15 |
16 | public PullDownloadListAction(IDownloadFactory downloadFactory)
17 | {
18 | _downloadFactory = downloadFactory ?? throw new ArgumentNullException(nameof(downloadFactory));
19 | }
20 |
21 | protected override Task Execute()
22 | {
23 | DataContext.Downloads = new List
24 | {
25 | _downloadFactory.Create("https://www.google.com/"),
26 | _downloadFactory.Create("https://www.facebook.com/"),
27 | _downloadFactory.Create("This is not an URL")
28 | };
29 | return Task.CompletedTask;
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/Commands/Contracts/IDownloadAllCommandBuilder.cs:
--------------------------------------------------------------------------------
1 | using GuardedActions.Commands.Contracts;
2 | using GuardedActionsPlayground.Core.ViewModels;
3 |
4 | namespace GuardedActionsPlayground.Core.Commands.Contracts
5 | {
6 | public interface IDownloadAllCommandBuilder : IAsyncGuardedDataContextCommandBuilder
7 | {
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/Commands/Contracts/IDownloadCommandBuilder.cs:
--------------------------------------------------------------------------------
1 | using GuardedActions.Commands.Contracts;
2 | using GuardedActionsPlayground.Core.Models;
3 |
4 | namespace GuardedActionsPlayground.Core.Commands.Contracts
5 | {
6 | public interface IDownloadCommandBuilder : IAsyncGuardedDataContextCommandBuilder
7 | {
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/Commands/Contracts/IInitializeCommandBuilder.cs:
--------------------------------------------------------------------------------
1 | using GuardedActions.Commands.Contracts;
2 | using GuardedActionsPlayground.Core.ViewModels;
3 |
4 | namespace GuardedActionsPlayground.Core.Commands.Contracts
5 | {
6 | public interface IInitializeCommandBuilder : IAsyncGuardedDataContextCommandBuilder
7 | {
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/Commands/DownloadAllCommandBuilder.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using GuardedActions.Commands;
4 | using GuardedActionsPlayground.Core.Commands.Contracts;
5 | using GuardedActionsPlayground.Core.ViewModels;
6 |
7 | namespace GuardedActionsPlayground.Core.Commands
8 | {
9 | public class DownloadAllCommandBuilder : AsyncGuardedDataContextCommandBuilder, IDownloadAllCommandBuilder
10 | {
11 | protected override Task ExecuteCommandAction()
12 | {
13 | var commands = new List();
14 | foreach (var download in DataContext.Downloads)
15 | {
16 | commands.Add(download.DownloadCommand.ExecuteAsync());
17 | }
18 | return Task.WhenAll(commands.ToArray());
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/Commands/DownloadCommandBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using GuardedActions.Commands;
4 | using GuardedActions.Commands.Contracts;
5 | using GuardedActionsPlayground.Core.Commands.Actions.Contracts;
6 | using GuardedActionsPlayground.Core.Commands.Contracts;
7 | using GuardedActionsPlayground.Core.Models;
8 |
9 | namespace GuardedActionsPlayground.Core.Commands
10 | {
11 | public class DownloadCommandBuilder : AsyncGuardedDataContextCommandBuilder, IDownloadCommandBuilder
12 | {
13 | private readonly IDownloadUrlAction _downloadUrlAction;
14 |
15 | public DownloadCommandBuilder(IDownloadUrlAction downloadUrlAction)
16 | {
17 | _downloadUrlAction = downloadUrlAction ?? throw new ArgumentNullException(nameof(downloadUrlAction));
18 | }
19 |
20 | protected override Task ExecuteCommandAction()
21 | {
22 | _downloadUrlAction.ExecuteGuarded();
23 |
24 | // And more actions to handle the download
25 |
26 | return Task.CompletedTask;
27 | }
28 |
29 | public override IAsyncGuardedDataContextCommandBuilder RegisterDataContext(Download dataContext)
30 | {
31 | _downloadUrlAction.RegisterDataContext(dataContext);
32 |
33 | return base.RegisterDataContext(dataContext);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/Commands/InitializeCommandBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using GuardedActions.Commands;
4 | using GuardedActions.Commands.Contracts;
5 | using GuardedActionsPlayground.Core.Commands.Actions.Contracts;
6 | using GuardedActionsPlayground.Core.Commands.Contracts;
7 | using GuardedActionsPlayground.Core.ViewModels;
8 |
9 | namespace GuardedActionsPlayground.Core.Commands
10 | {
11 | public class InitializeCommandBuilder : AsyncGuardedDataContextCommandBuilder, IInitializeCommandBuilder
12 | {
13 | private readonly IPullDownloadListAction _pullDownloadListAction;
14 |
15 | public InitializeCommandBuilder(IPullDownloadListAction pullDownloadListAction)
16 | {
17 | _pullDownloadListAction = pullDownloadListAction ?? throw new ArgumentNullException(nameof(pullDownloadListAction));
18 | }
19 |
20 | protected override Task ExecuteCommandAction()
21 | {
22 | _pullDownloadListAction.ExecuteGuarded();
23 |
24 | // And more actions to initialize
25 |
26 | return Task.CompletedTask;
27 | }
28 |
29 | public override IAsyncGuardedDataContextCommandBuilder RegisterDataContext(MainViewModel dataContext)
30 | {
31 | _pullDownloadListAction.RegisterDataContext(dataContext);
32 |
33 | return base.RegisterDataContext(dataContext);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/ExceptionHandlers/Defaults/GeneralExceptionHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using GuardedActions.ExceptionHandlers.Attributes;
4 | using GuardedActions.ExceptionHandlers.Contracts;
5 |
6 | namespace GuardedActionsPlayground.Core.ExceptionHandlers.Defaults
7 | {
8 | [DefaultExceptionHandler]
9 | public class GeneralExceptionHandler : GuardedActions.ExceptionHandlers.Defaults.GeneralExceptionHandler
10 | {
11 | public override Task Handle(IExceptionHandlingAction exceptionHandlingAction)
12 | {
13 | #if DEBUG
14 | Console.WriteLine("Custom general exception hanlder!");
15 | #endif
16 | return base.Handle(exceptionHandlingAction);
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/ExceptionHandlers/Defaults/NotImplementedExceptionHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using GuardedActions.ExceptionHandlers;
4 | using GuardedActions.ExceptionHandlers.Attributes;
5 | using GuardedActions.ExceptionHandlers.Contracts;
6 |
7 | namespace GuardedActionsPlayground.Core.ExceptionHandlers.Defaults
8 | {
9 | //TODO Think of a good implementation.
10 | [DefaultExceptionHandler]
11 | public class NotImplementedExceptionHandler : ExceptionHandler
12 | {
13 | //private readonly IUserDialogs _userDialogs;
14 |
15 | //public NotImplementedExceptionHandler(IUserDialogs userDialogs)
16 | public NotImplementedExceptionHandler()
17 | {
18 | //_userDialogs = userDialogs;
19 | }
20 |
21 | public override Task Handle(IExceptionHandlingAction exceptionHandlingAction)
22 | {
23 | //await _userDialogs.AlertAsync("This is not implemented... yet.", "Coming soon™", "Ok, I will wait");
24 | return Task.CompletedTask;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/ExceptionHandlers/Defaults/TaskCanceledExceptionHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using GuardedActions.ExceptionHandlers;
3 | using GuardedActions.ExceptionHandlers.Attributes;
4 | using GuardedActions.ExceptionHandlers.Contracts;
5 |
6 | namespace GuardedActionsPlayground.Core.ExceptionHandlers.Defaults
7 | {
8 | [DefaultExceptionHandler]
9 | public class TaskCanceledExceptionHandler : ExceptionHandler
10 | {
11 | public override Task Handle(IExceptionHandlingAction exceptionHandlingAction) => Task.CompletedTask; //ignore
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/Factories/Contracts/IDownloadFactory.cs:
--------------------------------------------------------------------------------
1 | using GuardedActionsPlayground.Core.Commands.Contracts;
2 | using GuardedActionsPlayground.Core.Models;
3 |
4 | namespace GuardedActionsPlayground.Core.Factories.Contracts
5 | {
6 | public interface IDownloadFactory
7 | {
8 | Download Create(string url);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/Factories/DownloadFactory.cs:
--------------------------------------------------------------------------------
1 | using GuardedActionsPlayground.Core.Commands;
2 | using GuardedActionsPlayground.Core.Commands.Actions;
3 | using GuardedActionsPlayground.Core.Factories.Contracts;
4 | using GuardedActionsPlayground.Core.Models;
5 |
6 | namespace GuardedActionsPlayground.Core.Factories
7 | {
8 | public class DownloadFactory : IDownloadFactory
9 | {
10 | public Download Create(string url)
11 | {
12 | var action = new DownloadUrlAction();
13 | var commandBuilder = new DownloadCommandBuilder(action);
14 | var download = new Download(url, commandBuilder);
15 | return download;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Playground/GuradedActionsPlayground.Core/GuardedActionsPlayground.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |