• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Sholtee / injector / 2237

20 Dec 2023 02:12PM UTC coverage: 93.013% (-0.2%) from 93.167%
2237

push

appveyor

Sholtee
validate service implementation II

1451 of 1560 relevant lines covered (93.01%)

3.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.89
/SRC/Interfaces/Public/Extensions/IServiceCollectionBasicExtensions/Provider.cs
1
/********************************************************************************
2
* Provider.cs                                                                   *
3
*                                                                               *
4
* Author: Denes Solti                                                           *
5
********************************************************************************/
6
using System;
7

8
namespace Solti.Utils.DI.Interfaces
9
{
10
    using Properties;
11

12
    public static partial class IServiceCollectionBasicExtensions
13
    {
14
        /// <summary>
15
        /// Registers a new service provider. Providers are "factory services" responsible for creating the concrete service:
16
        /// <code>
17
        /// class MyServiceProvider: IServiceProvider
18
        /// {
19
        ///     public int Depdendency { get; init; }
20
        ///     public object GetService(Type type) => ...;
21
        /// }
22
        /// ...
23
        /// ScopeFactory.Create
24
        /// (
25
        ///     svcs => svcs.Provider(typeof(IMyService), "serviceName", typeof(MyServiceProvider), new { Depdendency = 1986 }, Lifetime.Singleton),
26
        ///     ...
27
        /// )
28
        /// </code>
29
        /// </summary>
30
        /// <param name="self">The target <see cref="IServiceCollection"/>.</param>
31
        /// <param name="type">The service type. This parameter will be forwarded to the provider.</param>
32
        /// <param name="key">The (optional) service key (usually a name).</param>
33
        /// <param name="provider">The type of the provider. It may have dependencies and must implement the <see cref="IServiceProvider"/> interface.</param>
34
        /// <param name="explicitArgs">Explicit arguments, provided by the user.</param>
35
        /// <param name="lifetime">The lifetime of service.</param>
36
        /// <param name="options">Options to be assigned to the service being registered.</param>
37
        /// <remarks>The provided <see cref="IServiceProvider"/> implementation won't be disposed even if it implements the <see cref="IDisposable"/> interface.</remarks>
38
        public static IServiceCollection Provider(this IServiceCollection self, Type type, object? key, Type provider, object explicitArgs, LifetimeBase lifetime, ServiceOptions? options = null)
39
        {
4✔
40
            if (self is null)
4✔
41
                throw new ArgumentNullException(nameof(self));
×
42

43
            if (type is null)
4✔
44
                throw new ArgumentNullException(nameof(type));
4✔
45

46
            if (provider is null)
4✔
47
                throw new ArgumentNullException(nameof(provider));
4✔
48

49
            if (explicitArgs is null)
4✔
50
                throw new ArgumentNullException(nameof(explicitArgs));
4✔
51

52
            if (lifetime is null)
4✔
53
                throw new ArgumentNullException(nameof(lifetime));
4✔
54

55
            //
56
            // Further validations are done by the created xXxServiceEntry
57
            //
58

59
            if (!typeof(IServiceProvider).IsAssignableFrom(provider))
4✔
60
                throw new ArgumentException(string.Format(Resources.Culture, Resources.NOT_IMPLEMENTED, typeof(IServiceProvider)), nameof(provider));
4✔
61

62
            if (type.IsGenericTypeDefinition)
4✔
63
                throw new NotSupportedException(Resources.OPEN_GENERIC);
×
64

65
            return self
4✔
66
                .Register
67
                (
68
                    lifetime.CreateFrom(type, key, provider, explicitArgs, options ?? ServiceOptions.Default)
69
                )
70
                .Decorate(static (injector, type, instance) => ((IServiceProvider) instance).GetService(type));
71
        }
4✔
72

73
        /// <summary>
74
        /// Registers a new service provider. Providers are "factory services" responsible for creating the concrete service.
75
        /// <code>
76
        /// class MyServiceProvider: IServiceProvider
77
        /// {
78
        ///     [Inject]
79
        ///     public IDependency Depdendency { get; init; }
80
        ///     public object GetService(Type type) => ...;
81
        /// }
82
        /// ...
83
        /// ScopeFactory.Create
84
        /// (
85
        ///     svcs => svcs.Provider(typeof(IMyService), "serviceName", typeof(MyServiceProvider), Lifetime.Singleton),
86
        ///     ...
87
        /// )
88
        /// </code>
89
        /// </summary>
90
        /// <param name="self">The target <see cref="IServiceCollection"/>.</param>
91
        /// <param name="type">The service type. This parameter will be forwarded to the provider.</param>
92
        /// <param name="key">The (optional) service key (usually a name).</param>
93
        /// <param name="provider">The type of the provider. It may have dependencies and must implement the <see cref="IServiceProvider"/> interface.</param>
94
        /// <param name="lifetime">The lifetime of service.</param>
95
        /// <param name="options">Options to be assigned to the service being registered.</param>
96
        /// <remarks>The provided <see cref="IServiceProvider"/> implementation won't be disposed even if it implements the <see cref="IDisposable"/> interface.</remarks>
97
        public static IServiceCollection Provider(this IServiceCollection self, Type type, object? key, Type provider, LifetimeBase lifetime, ServiceOptions? options = null)
98
        {
4✔
99
            if (self is null)
4✔
100
                throw new ArgumentNullException(nameof(self));
×
101

102
            if (type is null)
4✔
103
                throw new ArgumentNullException(nameof(type));
4✔
104

105
            if (provider is null)
4✔
106
                throw new ArgumentNullException(nameof(provider));
4✔
107

108
            if (lifetime is null)
4✔
109
                throw new ArgumentNullException(nameof(lifetime));
4✔
110

111
            //
112
            // Further validations are done by the created xXxServiceEntry
113
            //
114

115
            if (!typeof(IServiceProvider).IsAssignableFrom(provider))
4✔
116
                throw new ArgumentException(string.Format(Resources.Culture, Resources.NOT_IMPLEMENTED, typeof(IServiceProvider)), nameof(provider));
4✔
117

118
            if (type.IsGenericTypeDefinition)
4✔
119
                throw new NotSupportedException(Resources.OPEN_GENERIC);
4✔
120

121
            return self
4✔
122
                .Register
123
                (
124
                    lifetime.CreateFrom(type, key, provider, options ?? ServiceOptions.Default)
125
                )
126
                .Decorate(static (injector, type, instance) => ((IServiceProvider) instance).GetService(type));
127
        }
4✔
128

129
        /// <summary>
130
        /// Registers a new service provider. Providers are "factory services" responsible for creating the concrete service:
131
        /// <code>
132
        /// class MyServiceProvider: IServiceProvider
133
        /// {
134
        ///     [Inject]
135
        ///     public IDependency Depdendency { get; init; }
136
        ///     public object GetService(Type type) => ...;
137
        /// }
138
        /// ...
139
        /// ScopeFactory.Create
140
        /// (
141
        ///     svcs => svcs.Provider(typeof(IMyService), typeof(MyServiceProvider), Lifetime.Singleton),
142
        ///     ...
143
        /// )
144
        /// </code>
145
        /// </summary>
146
        /// <param name="self">The target <see cref="IServiceCollection"/>.</param>
147
        /// <param name="type">The service type. This parameter will be forwarded to the provider.</param>
148
        /// <param name="provider">The type of the provider. It may have dependencies and must implement the <see cref="IServiceProvider"/> interface.</param>
149
        /// <param name="lifetime">The lifetime of service.</param>
150
        /// <param name="options">Options to be assigned to the service being registered.</param>
151
        /// <remarks>The provided <see cref="IServiceProvider"/> implementation won't be disposed even if it implements the <see cref="IDisposable"/> interface.</remarks>
152
        public static IServiceCollection Provider(this IServiceCollection self, Type type, Type provider, LifetimeBase lifetime, ServiceOptions? options = null)
153
            => self.Provider(type, key: null, provider, lifetime, options);
4✔
154

155
        /// <summary>
156
        /// Registers a new service provider having non-interface dependency. Providers are "factory services" responsible for creating the concrete service:
157
        /// <code>
158
        /// class MyServiceProvider: IServiceProvider
159
        /// {
160
        ///     public int Depdendency { get; init; }
161
        ///     public object GetService(Type type) => ...;
162
        /// }
163
        /// ...
164
        /// ScopeFactory.Create
165
        /// (
166
        ///     svcs => svcs.Provider(typeof(IMyService), typeof(MyServiceProvider), new { Depdendency = 1986 }, Lifetime.Singleton),
167
        ///     ...
168
        /// )
169
        /// </code>
170
        /// </summary>
171
        /// <param name="self">The target <see cref="IServiceCollection"/>.</param>
172
        /// <param name="type">The service type. This parameter will be forwarded to the provider.</param>
173
        /// <param name="provider">The type of the provider. It may have dependencies and must implement the <see cref="IServiceProvider"/> interface.</param>
174
        /// <param name="explicitArgs">Explicit arguments, provided by the user.</param>
175
        /// <param name="lifetime">The lifetime of service.</param>
176
        /// <param name="options">Options to be assigned to the service being registered.</param>
177
        /// <remarks>The provided <see cref="IServiceProvider"/> implementation won't be disposed even if it implements the <see cref="IDisposable"/> interface.</remarks>
178
        public static IServiceCollection Provider(this IServiceCollection self, Type type, Type provider, object explicitArgs, LifetimeBase lifetime, ServiceOptions? options = null)
179
            => self.Provider(type, null, provider, explicitArgs, lifetime, options);
4✔
180

181
        /// <summary>
182
        /// Registers a new service provider. Providers are "factory services" responsible for creating the concrete service:
183
        /// <code>
184
        /// class MyServiceProvider: IServiceProvider
185
        /// {
186
        ///     [Inject]
187
        ///     public IDependency Depdendency { get; init; }
188
        ///     public object GetService(Type type) => ...;
189
        /// }
190
        /// ...
191
        /// ScopeFactory.Create
192
        /// (
193
        ///     svcs => svcs.Provider&lt;IMyService, MyServiceProvider&gt;("serviceName", Lifetime.Singleton),
194
        ///     ...
195
        /// )
196
        /// </code>
197
        /// </summary>
198
        /// <typeparam name="TType">The service type. It will be forwarded to the provider.</typeparam>
199
        /// <typeparam name="TProvider">The type of the provider. It may have dependencies and must implement the <see cref="IServiceProvider"/> interface.</typeparam>
200
        /// <param name="self">The target <see cref="IServiceCollection"/>.</param>
201
        /// <param name="key">The (optional) service key (usually a name)</param>
202
        /// <param name="lifetime">The lifetime of service.</param>
203
        /// <param name="options">Options to be assigned to the service being registered.</param>
204
        /// <remarks>The provided <see cref="IServiceProvider"/> implementation won't be disposed even if it implements the <see cref="IDisposable"/> interface.</remarks>
205
        public static IServiceCollection Provider<TType, TProvider>(this IServiceCollection self, object? key, LifetimeBase lifetime, ServiceOptions? options = null) where TProvider : class, IServiceProvider where TType : class
206
            => self.Provider(typeof(TType), key, typeof(TProvider), lifetime, options);
4✔
207

208
        /// <summary>
209
        /// Registers a new service provider. Providers are "factory services" responsible for creating the concrete service:
210
        /// <code>
211
        /// class MyServiceProvider: IServiceProvider
212
        /// {
213
        ///     [Inject]
214
        ///     public IDependency Depdendency { get; init; }
215
        ///     public object GetService(Type type) => ...;
216
        /// }
217
        /// ...
218
        /// ScopeFactory.Create
219
        /// (
220
        ///     svcs => svcs.Provider&lt;IMyService, MyServiceProvider&gt;(Lifetime.Singleton),
221
        ///     ...
222
        /// )
223
        /// </code>
224
        /// </summary>
225
        /// <typeparam name="TType">The service type. It will be forwarded to the provider.</typeparam>
226
        /// <typeparam name="TProvider">The type of the provider. It may have dependencies and must implement the <see cref="IServiceProvider"/> interface.</typeparam>
227
        /// <param name="self">The target <see cref="IServiceCollection"/>.</param>
228
        /// <param name="lifetime">The lifetime of service.</param>
229
        /// <param name="options">Options to be assigned to the service being registered.</param>
230
        /// <remarks>The provided <see cref="IServiceProvider"/> implementation won't be disposed even if it implements the <see cref="IDisposable"/> interface.</remarks>
231
        public static IServiceCollection Provider<TType, TProvider>(this IServiceCollection self, LifetimeBase lifetime, ServiceOptions? options = null) where TProvider : class, IServiceProvider where TType : class
232
            => self.Provider<TType, TProvider>(key: null, lifetime, options);
4✔
233

234
        /// <summary>
235
        /// Registers a new service provider having non-interface dependency. Providers are "factory services" responsible for creating the concrete service:
236
        /// <code>
237
        /// class MyServiceProvider: IServiceProvider
238
        /// {
239
        ///     public int Depdendency { get; init; }
240
        ///     public object GetService(Type type) => ...;
241
        /// }
242
        /// ...
243
        /// ScopeFactory.Create
244
        /// (
245
        ///     svcs => svcs.Provider&lt;IMyService, MyServiceProvider&gt;("serviceName", new { Depdendency = 1986 }, Lifetime.Singleton),
246
        ///     ...
247
        /// )
248
        /// </code>
249
        /// </summary>
250
        /// <typeparam name="TType">The service type. It will be forwarded to the provider.</typeparam>
251
        /// <typeparam name="TProvider">The type of the provider. It may have dependencies and must implement the <see cref="IServiceProvider"/> interface.</typeparam>
252
        /// <param name="self">The target <see cref="IServiceCollection"/>.</param>
253
        /// <param name="key">The (optional) service key (usually a name)</param>
254
        /// <param name="explicitArgs">Explicit arguments, provided by the user.</param>
255
        /// <param name="lifetime">The lifetime of service.</param>
256
        /// <param name="options">Options to be assigned to the service being registered.</param>
257
        /// <remarks>The provided <see cref="IServiceProvider"/> implementation won't be disposed even if it implements the <see cref="IDisposable"/> interface.</remarks>
258
        public static IServiceCollection Provider<TType, TProvider>(this IServiceCollection self, object? key, object explicitArgs, LifetimeBase lifetime, ServiceOptions? options = null) where TProvider : class, IServiceProvider where TType : class
259
            => self.Provider(typeof(TType), key, typeof(TProvider), explicitArgs, lifetime, options);
4✔
260
    }
261
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc