1
1
using System ;
2
2
using System . Collections . Generic ;
3
+ using System . Collections . Immutable ;
4
+ using System . Reflection ;
5
+ using System . Runtime . CompilerServices ;
3
6
using System . Threading ;
4
7
using LightInject ;
5
8
6
9
namespace Barotrauma . LuaCs . Services ;
7
10
11
+
8
12
public class ServicesProvider : IServicesProvider
9
13
{
10
- private ServiceContainer _serviceContainer = new ( ) ;
14
+ private ServiceContainer _serviceContainerInst ;
15
+ private ServiceContainer ServiceContainer
16
+ {
17
+ get
18
+ {
19
+ // ReSharper disable once ConvertIfStatementToNullCoalescingExpression
20
+ if ( _serviceContainerInst is null )
21
+ _serviceContainerInst = new ServiceContainer ( ) ;
22
+ return _serviceContainerInst ;
23
+ }
24
+ }
25
+
26
+ private readonly ReaderWriterLockSlim _serviceLock = new ( ) ;
11
27
12
28
public void RegisterServiceType < TSvcInterface , TService > ( ServiceLifetime lifetime , ILifetime lifetimeInstance = null ) where TSvcInterface : class , IService where TService : class , IService , TSvcInterface , new ( )
13
29
{
@@ -30,8 +46,18 @@ public class ServicesProvider : IServicesProvider
30
46
break ;
31
47
}
32
48
}
33
-
34
- _serviceContainer . Register < TSvcInterface , TService > ( lifetimeInstance ) ;
49
+
50
+ try
51
+ {
52
+ _serviceLock . EnterReadLock ( ) ;
53
+ ServiceContainer . Register < TSvcInterface , TService > ( lifetimeInstance ) ;
54
+ ServiceContainer . Compile < TService > ( ) ;
55
+ OnServiceRegistered ? . Invoke ( typeof ( TSvcInterface ) , typeof ( TService ) ) ;
56
+ }
57
+ finally
58
+ {
59
+ _serviceLock . ExitReadLock ( ) ;
60
+ }
35
61
}
36
62
37
63
public void RegisterServiceType < TSvcInterface , TService > ( string name , ServiceLifetime lifetime ,
@@ -62,46 +88,120 @@ public void RegisterServiceType<TSvcInterface, TService>(string name, ServiceLif
62
88
}
63
89
}
64
90
65
- _serviceContainer . Register < TSvcInterface , TService > ( name , lifetimeInstance ) ;
91
+ try
92
+ {
93
+ _serviceLock . EnterReadLock ( ) ;
94
+ ServiceContainer . Register < TSvcInterface , TService > ( name , lifetimeInstance ) ;
95
+ ServiceContainer . Compile < TService > ( ) ;
96
+ OnServiceRegistered ? . Invoke ( typeof ( TSvcInterface ) , typeof ( TService ) ) ;
97
+ }
98
+ finally
99
+ {
100
+ _serviceLock . ExitReadLock ( ) ;
101
+ }
66
102
}
67
103
68
- public void UnregisterServiceType < TSvcInterface , TService > ( ) where TSvcInterface : class , IService where TService : class , IService , TSvcInterface , new ( )
104
+ public void Compile ( )
69
105
{
70
- throw new NotImplementedException ( ) ;
106
+ try
107
+ {
108
+ _serviceLock . EnterReadLock ( ) ;
109
+ ServiceContainer ? . Compile ( ) ;
110
+ }
111
+ finally
112
+ {
113
+ _serviceLock . ExitReadLock ( ) ;
114
+ }
71
115
}
72
116
73
117
public event Action < Type , Type > OnServiceRegistered ;
74
118
75
119
public void InjectServices < T > ( T inst ) where T : class
76
120
{
77
- throw new NotImplementedException ( ) ;
121
+ try
122
+ {
123
+ _serviceLock . EnterReadLock ( ) ;
124
+ ServiceContainer . InjectProperties ( inst ) ;
125
+ }
126
+ finally
127
+ {
128
+ _serviceLock . ExitReadLock ( ) ;
129
+ }
78
130
}
79
131
80
- public bool TryGetService < TSvcInterface > ( out IService service , out ServiceLifetime lifetime ) where TSvcInterface : class , IService
132
+ public bool TryGetService < TSvcInterface > ( out IService service ) where TSvcInterface : class , IService
81
133
{
82
- throw new NotImplementedException ( ) ;
134
+ try
135
+ {
136
+ _serviceLock . EnterReadLock ( ) ;
137
+ service = ServiceContainer . TryGetInstance < TSvcInterface > ( ) ;
138
+ return service is not null ;
139
+ }
140
+ catch
141
+ {
142
+ service = null ;
143
+ return false ;
144
+ }
145
+ finally
146
+ {
147
+ _serviceLock . ExitReadLock ( ) ;
148
+ }
83
149
}
84
150
85
- public bool TryGetService < TSvcInterface > ( string name , out IService service , out ServiceLifetime lifetime ) where TSvcInterface : class , IService
151
+ public bool TryGetService < TSvcInterface > ( string name , out IService service ) where TSvcInterface : class , IService
86
152
{
87
- throw new NotImplementedException ( ) ;
153
+ try
154
+ {
155
+ _serviceLock . EnterReadLock ( ) ;
156
+ service = ServiceContainer . TryGetInstance < TSvcInterface > ( name ) ;
157
+ return service is not null ;
158
+ }
159
+ catch
160
+ {
161
+ service = null ;
162
+ return false ;
163
+ }
164
+ finally
165
+ {
166
+ _serviceLock . ExitReadLock ( ) ;
167
+ }
88
168
}
89
169
90
170
public event Action < Type , IService > OnServiceInstanced ;
91
171
92
- public List < TSvc > GetAllServices < TSvc > ( ) where TSvc : class , IService
172
+ public ImmutableArray < TSvc > GetAllServices < TSvc > ( ) where TSvc : class , IService
93
173
{
94
- throw new NotImplementedException ( ) ;
174
+ try
175
+ {
176
+ _serviceLock . EnterReadLock ( ) ;
177
+ return ServiceContainer . GetAllInstances < TSvc > ( ) . ToImmutableArray ( ) ;
178
+ }
179
+ finally
180
+ {
181
+ _serviceLock . ExitReadLock ( ) ;
182
+ }
95
183
}
96
184
97
- public void DisposeServicesOfType < TSvc > ( ) where TSvc : class , IService
185
+ [ MethodImpl ( MethodImplOptions . Synchronized | MethodImplOptions . PreserveSig | MethodImplOptions . NoInlining ) ]
186
+ public void DisposeAndReset ( )
98
187
{
99
- throw new NotImplementedException ( ) ;
100
- }
188
+ // Plugins should never be allowed to execute this.
189
+ if ( Assembly . GetCallingAssembly ( ) != Assembly . GetExecutingAssembly ( ) )
190
+ {
191
+ throw new MethodAccessException (
192
+ $ "Assembly { Assembly . GetCallingAssembly ( ) . FullName } attempted to call DisposeAllServices().") ;
193
+ }
101
194
102
- public void DisposeAllServices ( )
103
- {
104
- throw new NotImplementedException ( ) ;
195
+ try
196
+ {
197
+ _serviceLock . EnterWriteLock ( ) ;
198
+ _serviceContainerInst . Dispose ( ) ;
199
+ _serviceContainerInst = new ServiceContainer ( ) ;
200
+ }
201
+ finally
202
+ {
203
+ _serviceLock . ExitWriteLock ( ) ;
204
+ }
105
205
}
106
206
}
107
207
0 commit comments