-
Notifications
You must be signed in to change notification settings - Fork 94
Expand file tree
/
Copy pathServiceCollectionExtensions.cs
More file actions
45 lines (35 loc) · 1.53 KB
/
ServiceCollectionExtensions.cs
File metadata and controls
45 lines (35 loc) · 1.53 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
using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Workbench.DependencyInjection.Extensions;
public static class ServiceCollectionExtensions
{
public static IServiceCollection Decorate<TInterface, TDecorator>(this IServiceCollection services)
where TInterface : class
where TDecorator : class, TInterface
{
ServiceDescriptor innerDescriptor = services.FirstOrDefault(s => s.ServiceType == typeof(TInterface));
if (innerDescriptor == null) { throw new InvalidOperationException($"{typeof(TInterface).Name} is not registered"); }
var objectFactory = ActivatorUtilities.CreateFactory(
typeof(TDecorator),
new[] { typeof(TInterface) });
services.Replace(ServiceDescriptor.Describe(
typeof(TInterface),
s => (TInterface)objectFactory(s, new[] { s.CreateInstance(innerDescriptor) }), innerDescriptor.Lifetime)
);
return services;
}
private static object CreateInstance(this IServiceProvider services, ServiceDescriptor descriptor)
{
if (descriptor.ImplementationInstance != null)
{
return descriptor.ImplementationInstance;
}
if (descriptor.ImplementationFactory != null)
{
return descriptor.ImplementationFactory(services);
}
return ActivatorUtilities.GetServiceOrCreateInstance(services, descriptor.ImplementationType);
}
}