-
Notifications
You must be signed in to change notification settings - Fork 2
/
Without.cs
137 lines (112 loc) · 3.43 KB
/
Without.cs
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
using Lamar;
using Xunit;
namespace WithoutMediatR.ExceptionHandling.WithIoC.Without;
public class Ping
{
}
public class PingResource : Ping
{
}
public class PingProtectedResource : PingResource
{
}
public class Pong
{
}
public class ConnectionException : Exception
{
}
public class ForbiddenException : ConnectionException
{
}
public interface IPingProtectedResourceHandler
{
Task<Pong> Handle(PingProtectedResource request);
}
public class PingProtectedResourceHandler : IPingProtectedResourceHandler
{
Task<Pong> IPingProtectedResourceHandler.Handle(PingProtectedResource request) =>
throw new ForbiddenException();
}
public class AccessDeniedExceptionHandler : IPingProtectedResourceHandler
{
private readonly TextWriter _writer;
private readonly IPingProtectedResourceHandler _handler;
public AccessDeniedExceptionHandler(IPingProtectedResourceHandler handler, TextWriter writer)
{
_handler = handler;
_writer = writer;
}
async Task<Pong> IPingProtectedResourceHandler.Handle(PingProtectedResource request)
{
try
{
return await _handler.Handle(request);
}
catch (Exception e)
{
await _writer.WriteLineAsync($"---- Exception Handler: '{typeof(AccessDeniedExceptionHandler).FullName}'").ConfigureAwait(false);
return new Pong();
}
}
}
public class Without
{
private readonly Container _container;
private readonly StringWriter _stringWriter;
public Without()
{
_stringWriter = new StringWriter();
_container = new Container(cfg =>
{
cfg.For<TextWriter>().Add(_stringWriter);
cfg.For<IPingProtectedResourceHandler>().Use<PingProtectedResourceHandler>();
cfg.For<IPingProtectedResourceHandler>().DecorateAllWith<AccessDeniedExceptionHandler>();
});
}
[Fact]
async Task exceptions_are_handled()
{
var handler = _container.GetInstance<IPingProtectedResourceHandler>();
await handler.Handle(new PingProtectedResource());
Assert.Equal("---- Exception Handler: 'WithoutMediatR.ExceptionHandling.WithIoC.Without.AccessDeniedExceptionHandler'\r\n", _stringWriter.ToString());
}
[Fact]
async Task not_over_engineered()
{
async Task<Pong> JustHandleExceptions(IPingProtectedResourceHandler pingProtectedResourceHandler)
{
try
{
return await pingProtectedResourceHandler.Handle(new PingProtectedResource());
}
catch (ConnectionException e)
{
return new Pong();
}
}
var handler = new PingProtectedResourceHandler();
var result = await JustHandleExceptions(handler);
Assert.NotNull(result);
}
[Fact]
async Task with_an_extension_method()
{
IPingProtectedResourceHandler handler = new PingProtectedResourceHandler();
var result = await Try(() =>
handler.Handle(new PingProtectedResource()),
new Pong());
Assert.NotNull(result);
}
private static Task<T> Try<T>(Func<Task<T>> f, T fallback)
{
try
{
return f();
}
catch (Exception e)
{
return Task.FromResult(fallback);
}
}
}