-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Expand file tree
/
Copy pathService.cs
More file actions
208 lines (170 loc) · 8.13 KB
/
Service.cs
File metadata and controls
208 lines (170 loc) · 8.13 KB
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
using System;
using System.Data;
using System.Threading;
using System.Threading.Tasks;
using ServiceStack.Auth;
using ServiceStack.Caching;
using ServiceStack.Configuration;
using ServiceStack.IO;
using ServiceStack.Messaging;
using ServiceStack.Redis;
using ServiceStack.Web;
namespace ServiceStack
{
/// <summary>
/// Generic + Useful IService base class
/// </summary>
public class Service : IService, IServiceBase, IDisposable, IServiceFilters
, IAsyncDisposable
{
public static IResolver GlobalResolver { get; set; }
private IResolver resolver;
public virtual IResolver GetResolver() => resolver ?? GlobalResolver;
public virtual Service SetResolver(IResolver resolver)
{
this.resolver = resolver;
return this;
}
public virtual T TryResolve<T>()
{
return this.GetResolver() == null
? default(T)
: this.GetResolver().TryResolve<T>();
}
public T GetPlugin<T>() where T : class, IPlugin => GetResolver()?.TryResolve<T>() ?? HostContext.GetPlugin<T>();
public T AssertPlugin<T>() where T : class, IPlugin => GetResolver()?.TryResolve<T>() ?? HostContext.AssertPlugin<T>();
public virtual T ResolveService<T>()
{
var service = TryResolve<T>();
return HostContext.ResolveService(this.Request, service);
}
public IRequest Request { get; set; }
protected virtual IResponse Response => Request?.Response;
private ICacheClient cache;
public virtual ICacheClient Cache => cache ??= HostContext.AppHost.GetCacheClient(Request);
private ICacheClientAsync cacheAsync;
public virtual ICacheClientAsync CacheAsync => cacheAsync ??= HostContext.AppHost.GetCacheClientAsync(Request);
private MemoryCacheClient localCache;
/// <summary>
/// Returns <see cref="MemoryCacheClient"></see>. cache is only persisted for this running app instance.
/// </summary>
public virtual MemoryCacheClient LocalCache => localCache ??= HostContext.AppHost.GetMemoryCacheClient(Request);
private IDbConnection db;
public virtual IDbConnection Db => db ??= HostContext.AppHost.GetDbConnection(Request);
private IRedisClient redis;
public virtual IRedisClient Redis => redis ??= HostContext.AppHost.GetRedisClient(Request);
public virtual ValueTask<IRedisClientAsync> GetRedisAsync() => HostContext.AppHost.GetRedisClientAsync(Request);
private IMessageProducer messageProducer;
public virtual IMessageProducer MessageProducer => messageProducer ??= HostContext.AppHost.GetMessageProducer(Request);
private ISessionFactory sessionFactory;
public virtual ISessionFactory SessionFactory => sessionFactory ?? (sessionFactory = TryResolve<ISessionFactory>()) ?? new SessionFactory(Cache, CacheAsync);
private IAuthRepository authRepository;
public virtual IAuthRepository AuthRepository => authRepository ??= HostContext.AppHost.GetAuthRepository(Request);
private IAuthRepositoryAsync authRepositoryAsync;
public virtual IAuthRepositoryAsync AuthRepositoryAsync => authRepositoryAsync ??= HostContext.AppHost.GetAuthRepositoryAsync(Request);
private IServiceGateway gateway;
public virtual IServiceGateway Gateway => gateway ??= HostContext.AppHost.GetServiceGateway(Request);
/// <summary>
/// Cascading collection of virtual file sources, inc. Embedded Resources, File System, In Memory, S3
/// </summary>
public IVirtualPathProvider VirtualFileSources => HostContext.VirtualFileSources;
/// <summary>
/// Read/Write Virtual FileSystem. Defaults to FileSystemVirtualPathProvider
/// </summary>
public IVirtualFiles VirtualFiles => HostContext.VirtualFiles;
/// <summary>
/// Dynamic Session Bag
/// </summary>
private ISession session;
public virtual ISession SessionBag => session ??= TryResolve<ISession>() //Easier to mock
?? SessionFactory.GetOrCreateSession(Request, Response);
/// <summary>
/// Dynamic Session Bag
/// </summary>
private ISessionAsync sessionAsync;
public virtual ISessionAsync SessionBagAsync => sessionAsync ??= TryResolve<ISessionAsync>() //Easier to mock
?? SessionFactory.GetOrCreateSessionAsync(Request, Response);
public virtual IAuthSession GetSession(bool reload = false)
{
var req = this.Request;
if (req.GetSessionId() == null)
req.Response.CreateSessionIds(req);
return req.GetSession(reload);
}
public virtual Task<IAuthSession> GetSessionAsync(bool reload = false, CancellationToken token=default)
{
var req = this.Request;
if (req.GetSessionId() == null)
req.Response.CreateSessionIds(req);
return req.GetSessionAsync(reload, token);
}
/// <summary>
/// Typed UserSession
/// </summary>
protected virtual TUserSession SessionAs<TUserSession>()
{
if (HostContext.TestMode)
{
var mockSession = TryResolve<TUserSession>();
if (Equals(mockSession, default(TUserSession)))
mockSession = TryResolve<IAuthSession>() is TUserSession
? (TUserSession)TryResolve<IAuthSession>()
: default;
if (!Equals(mockSession, default(TUserSession)))
return mockSession;
}
return SessionFeature.GetOrCreateSession<TUserSession>(Cache, Request, Response);
}
/// <summary>
/// Typed UserSession
/// </summary>
protected virtual async Task<TUserSession> SessionAsAsync<TUserSession>()
{
if (HostContext.TestMode)
{
var mockSession = TryResolve<TUserSession>();
if (Equals(mockSession, default(TUserSession)))
mockSession = TryResolve<IAuthSession>() is TUserSession
? (TUserSession)TryResolve<IAuthSession>()
: default;
if (!Equals(mockSession, default(TUserSession)))
return mockSession;
}
return await SessionFeature.GetOrCreateSessionAsync<TUserSession>(CacheAsync, Request, Response);
}
/// <summary>
/// If user found in session for this request is authenticated.
/// </summary>
public virtual bool IsAuthenticated => this.GetSession().IsAuthenticated;
/// <summary>
/// Publish a MQ message over the <see cref="IMessageProducer"></see> implementation.
/// </summary>
public virtual void PublishMessage<T>(T message) => HostContext.AppHost.PublishMessage(MessageProducer, message);
private bool hasDisposed = false;
/// <summary>
/// Disposes all created disposable properties of this service
/// and executes disposing of all request <see cref="IDisposable"></see>s
/// (warning, manually triggering this might lead to unwanted disposing of all request related objects and services.)
/// </summary>
public virtual void Dispose()
{
if (hasDisposed) return;
hasDisposed = true;
using (authRepository as IDisposable) { }
db?.Dispose();
redis?.Dispose();
messageProducer?.Dispose();
RequestContext.Instance.ReleaseDisposables();
Request.ReleaseIfInProcessRequest();
}
public virtual void OnBeforeExecute(object requestDto) {}
public virtual object OnAfterExecute(object response) => response;
public virtual Task<object> OnExceptionAsync(object requestDto, Exception ex) => TypeConstants.EmptyTask;
public async ValueTask DisposeAsync()
{
if (hasDisposed) return;
await using (authRepositoryAsync as IAsyncDisposable) {}
Dispose();
}
}
}