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

Sholtee / injector / 2221

01 Dec 2023 07:49AM UTC coverage: 93.276% (-0.6%) from 93.921%
2221

push

appveyor

Sholtee
Merge branch 'v10'

1415 of 1517 relevant lines covered (93.28%)

3.69 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
using System.Linq;
8
using System.Reflection;
9

10
namespace Solti.Utils.DI.Interfaces
11
{
12
    using Properties;
13

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

45
            if (type is null)
4✔
46
                throw new ArgumentNullException(nameof(type));
4✔
47

48
            if (provider is null)
4✔
49
                throw new ArgumentNullException(nameof(provider));
4✔
50

51
            if (explicitArgs is null)
4✔
52
                throw new ArgumentNullException(nameof(explicitArgs));
4✔
53

54
            if (lifetime is null)
4✔
55
                throw new ArgumentNullException(nameof(lifetime));
4✔
56

57
            //
58
            // Further validations are done by the created xXxServiceEntry
59
            //
60

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

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

67
            return self
4✔
68
                .Service(type, key, provider, explicitArgs, lifetime, options)
69
                .Decorate(static (injector, type, instance) => ((IServiceProvider) instance).GetService(type));
70
        }
4✔
71

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

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

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

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

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

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

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

120
            return self
4✔
121
                .Service(type, key, provider, lifetime, options)
122
                .Decorate(static (injector, type, instance) => ((IServiceProvider) instance).GetService(type));
123
        }
4✔
124

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

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

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

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

230
        /// <summary>
231
        /// Registers a new service provider having non-interface dependency. Providers are "factory services" responsible for creating the concrete service:
232
        /// <code>
233
        /// class MyServiceProvider: IServiceProvider
234
        /// {
235
        ///     public int Depdendency { get; init; }
236
        ///     public object GetService(Type type) => ...;
237
        /// }
238
        /// ...
239
        /// ScopeFactory.Create
240
        /// (
241
        ///     svcs => svcs.Provider&lt;IMyService, MyServiceProvider&gt;("serviceName", new { Depdendency = 1986 }, Lifetime.Singleton),
242
        ///     ...
243
        /// )
244
        /// </code>
245
        /// </summary>
246
        /// <typeparam name="TType">The service type. It will be forwarded to the provider.</typeparam>
247
        /// <typeparam name="TProvider">The type of the provider. It may have dependencies and must implement the <see cref="IServiceProvider"/> interface.</typeparam>
248
        /// <param name="self">The target <see cref="IServiceCollection"/>.</param>
249
        /// <param name="key">The (optional) service key (usually a name)</param>
250
        /// <param name="explicitArgs">Explicit arguments, provided by the user.</param>
251
        /// <param name="lifetime">The lifetime of service.</param>
252
        /// <param name="options">Options to be assigned to the service being registered.</param>
253
        /// <remarks>The provided <see cref="IServiceProvider"/> implementation won't be disposed even if it implements the <see cref="IDisposable"/> interface.</remarks>
254
        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
255
            => self.Provider(typeof(TType), key, typeof(TProvider), explicitArgs, lifetime, options);
4✔
256
    }
257
}
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