-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathServiceCollectionExtensions.cs
More file actions
144 lines (126 loc) · 6.4 KB
/
ServiceCollectionExtensions.cs
File metadata and controls
144 lines (126 loc) · 6.4 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
using Microsoft.Extensions.DependencyInjection;
using System;
namespace Birko.Data.Repositories
{
/// <summary>
/// Extension methods for configuring repository services in ASP.NET Core dependency injection.
/// </summary>
public static class ServiceCollectionExtensions
{
#region Generic Repository Registration
/// <summary>
/// Add a repository with its store to the dependency injection container.
/// </summary>
/// <typeparam name="TStore">The type of store to register.</typeparam>
/// <typeparam name="TRepository">The type of repository to register.</typeparam>
/// <param name="services">The service collection.</param>
/// <param name="lifetime">The service lifetime (defaults to Scoped).</param>
/// <returns>The service collection for chaining.</returns>
public static IServiceCollection AddRepository<TStore, TRepository>(
this IServiceCollection services,
ServiceLifetime lifetime = ServiceLifetime.Scoped)
where TStore : class, Stores.IBaseStore
where TRepository : class, IBaseRepository
{
// Register the store
services.Add(new ServiceDescriptor(typeof(TStore), typeof(TStore), lifetime));
// Register the repository with the store as a dependency
services.Add(new ServiceDescriptor(typeof(TRepository), sp =>
{
var store = sp.GetRequiredService<TStore>();
return Activator.CreateInstance(typeof(TRepository), store) as TRepository
?? throw new InvalidOperationException($"Failed to create instance of {typeof(TRepository).Name}");
}, lifetime));
return services;
}
/// <summary>
/// Add a repository with an existing store instance to the dependency injection container.
/// </summary>
/// <typeparam name="TRepository">The type of repository to register.</typeparam>
/// <param name="services">The service collection.</param>
/// <param name="store">The store instance to use.</param>
/// <param name="lifetime">The service lifetime (defaults to Scoped).</param>
/// <returns>The service collection for chaining.</returns>
public static IServiceCollection AddRepository<TRepository>(
this IServiceCollection services,
Stores.IBaseStore store,
ServiceLifetime lifetime = ServiceLifetime.Scoped)
where TRepository : class, IBaseRepository
{
services.Add(new ServiceDescriptor(typeof(TRepository), sp =>
{
return Activator.CreateInstance(typeof(TRepository), store) as TRepository
?? throw new InvalidOperationException($"Failed to create instance of {typeof(TRepository).Name}");
}, lifetime));
return services;
}
/// <summary>
/// Add a repository with a factory function to the dependency injection container.
/// </summary>
/// <typeparam name="TRepository">The type of repository to register.</typeparam>
/// <param name="services">The service collection.</param>
/// <param name="storeFactory">A factory function to create the store.</param>
/// <param name="lifetime">The service lifetime (defaults to Scoped).</param>
/// <returns>The service collection for chaining.</returns>
public static IServiceCollection AddRepository<TRepository>(
this IServiceCollection services,
Func<IServiceProvider, Stores.IBaseStore> storeFactory,
ServiceLifetime lifetime = ServiceLifetime.Scoped)
where TRepository : class, IBaseRepository
{
services.Add(new ServiceDescriptor(typeof(TRepository), sp =>
{
var store = storeFactory(sp);
return Activator.CreateInstance(typeof(TRepository), store) as TRepository
?? throw new InvalidOperationException($"Failed to create instance of {typeof(TRepository).Name}");
}, lifetime));
return services;
}
#endregion
#region Singleton Registration
/// <summary>
/// Add a repository as a singleton.
/// </summary>
/// <typeparam name="TStore">The type of store.</typeparam>
/// <typeparam name="TRepository">The type of repository.</typeparam>
/// <param name="services">The service collection.</param>
/// <returns>The service collection for chaining.</returns>
public static IServiceCollection AddRepositorySingleton<TStore, TRepository>(this IServiceCollection services)
where TStore : class, Stores.IBaseStore
where TRepository : class, IBaseRepository
{
return services.AddRepository<TStore, TRepository>(ServiceLifetime.Singleton);
}
#endregion
#region Scoped Registration
/// <summary>
/// Add a repository as a scoped service.
/// </summary>
/// <typeparam name="TStore">The type of store.</typeparam>
/// <typeparam name="TRepository">The type of repository.</typeparam>
/// <param name="services">The service collection.</param>
/// <returns>The service collection for chaining.</returns>
public static IServiceCollection AddRepositoryScoped<TStore, TRepository>(this IServiceCollection services)
where TStore : class, Stores.IBaseStore
where TRepository : class, IBaseRepository
{
return services.AddRepository<TStore, TRepository>(ServiceLifetime.Scoped);
}
#endregion
#region Transient Registration
/// <summary>
/// Add a repository as a transient service.
/// </summary>
/// <typeparam name="TStore">The type of store.</typeparam>
/// <typeparam name="TRepository">The type of repository.</typeparam>
/// <param name="services">The service collection.</param>
/// <returns>The service collection for chaining.</returns>
public static IServiceCollection AddRepositoryTransient<TStore, TRepository>(this IServiceCollection services)
where TStore : class, Stores.IBaseStore
where TRepository : class, IBaseRepository
{
return services.AddRepository<TStore, TRepository>(ServiceLifetime.Transient);
}
#endregion
}
}