Skip to content

Commit 733983f

Browse files
authored
Merge pull request #1 from Calabonga/skip-duplicates
Duplicates processing skipped
2 parents db5f843 + f4650be commit 733983f

File tree

7 files changed

+130
-33
lines changed

7 files changed

+130
-33
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@
44

55
## Что нового
66

7+
### Версия 2.3.0
8+
9+
Добавлена обработка дубликатов AppDefinitions, которые были найдены в сторонних сборках. Дополнительная информация о найденых дубликатах определений теперь выводиться в процессе отладке (DEBUG) включенном в настройках логирования.
10+
11+
Информация при уровне логирования `LogLevel = "Debug"`:
12+
13+
![image5](./docs/with-debug.png)
14+
15+
Информация при уровне логирования `LogLevel = "Information"`:
16+
17+
![image5](./docs/without-debug.png)
18+
19+
720
### Версия 2.2.0
821

922
Создан шаблон для генерации проекта `ASP.NET Web API c AppDefinitions`. То есть, чтобы не устанавливать каждый раз `Calabonga.AspNetCore.AppDefinitions` nuget-пакет в новый (в пустой) проект, можно воспользоваться уже готовым шаблоном, который создаст приложение с установленным nuget-пакетом (плюс еще *Serilog*). Это гораздо быстрее и удобнее. Я использую этот шаблона в своих видео на своём канале [boosty.to/calabonga](https://boosty.to/calabonga).

docs/with-debug.png

171 KB
Loading

docs/without-debug.png

26.7 KB
Loading

src/Calabonga.AspNetCore.AppDefinitions/AppDefinitionCollection.cs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,17 @@
55
/// </summary>
66
internal sealed class AppDefinitionCollection
77
{
8-
internal IList<AppDefinitionItem> Items { get; } = new List<AppDefinitionItem>();
8+
private IList<AppDefinitionItem> Items { get; } = new List<AppDefinitionItem>();
99

10+
/// <summary>
11+
/// Entry points found names
12+
/// </summary>
1013
internal IList<string> EntryPoints { get; } = new List<string>();
1114

15+
/// <summary>
16+
/// Adds collected information to collection
17+
/// </summary>
18+
/// <param name="definition"></param>
1219
internal void AddInfo(AppDefinitionItem definition)
1320
{
1421
var exists = Items.FirstOrDefault(x => x == definition);
@@ -23,10 +30,21 @@ internal void AddInfo(AppDefinitionItem definition)
2330
/// </summary>
2431
/// <param name="entryPointName"></param>
2532
public void AddEntryPoint(string entryPointName) => EntryPoints.Add(entryPointName);
26-
}
2733

28-
/// <summary>
29-
/// Information about <see cref="IAppDefinition"/>
30-
/// </summary>
31-
/// <param name="Definition"></param>
32-
public sealed record AppDefinitionItem(IAppDefinition Definition, string AssemblyName, bool Enabled, bool Exported);
34+
/// <summary>
35+
/// Returns ordered and enabled items
36+
/// </summary>
37+
internal IEnumerable<AppDefinitionItem> GetEnabled()
38+
=> Items
39+
.Where(x => x.Definition.Enabled)
40+
.OrderBy(x => x.Definition.OrderIndex);
41+
42+
/// <summary>
43+
///
44+
/// </summary>
45+
internal IEnumerable<AppDefinitionItem> GetDistinct()
46+
=> GetEnabled()
47+
.Select(x => new { x.Definition.GetType().Name, AppDefinitionItem = x })
48+
.DistinctBy(x => x.Name)
49+
.Select(x => x.AppDefinitionItem);
50+
}

src/Calabonga.AspNetCore.AppDefinitions/AppDefinitionExtensions.cs

Lines changed: 78 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -81,42 +81,65 @@ public static void AddDefinitionsWithModules(this WebApplicationBuilder builder,
8181
public static void AddDefinitions(this WebApplicationBuilder builder, params Type[] entryPointsAssembly)
8282
{
8383
var logger = builder.Services.BuildServiceProvider().GetRequiredService<ILogger<IAppDefinition>>();
84-
var definitions = new List<IAppDefinition>();
8584
var appDefinitionInfo = builder.Services.BuildServiceProvider().GetService<AppDefinitionCollection>();
86-
var info = appDefinitionInfo ?? new AppDefinitionCollection();
85+
var definitionCollection = appDefinitionInfo ?? new AppDefinitionCollection();
8786

8887
foreach (var entryPoint in entryPointsAssembly)
8988
{
90-
info.AddEntryPoint(entryPoint.Name);
89+
definitionCollection.AddEntryPoint(entryPoint.Name);
9190

9291
var types = entryPoint.Assembly.ExportedTypes.Where(Predicate);
93-
var instances = types.Select(Activator.CreateInstance).Cast<IAppDefinition>().ToList();
92+
var instances = types.Select(Activator.CreateInstance).Cast<IAppDefinition>().Where(x => x.Enabled).OrderBy(x => x.OrderIndex).ToList();
9493

9594
foreach (var definition in instances)
9695
{
97-
info.AddInfo(new AppDefinitionItem(definition, entryPoint.Name, definition.Enabled, definition.Exported));
96+
definitionCollection.AddInfo(new AppDefinitionItem(definition, entryPoint.Name, definition.Enabled, definition.Exported));
9897
}
99-
100-
var instancesOrdered = instances.Where(x => x.Enabled).OrderBy(x => x.OrderIndex).ToList();
101-
definitions.AddRange(instancesOrdered);
10298
}
10399

104-
foreach (var definition in definitions)
100+
if (logger.IsEnabled(LogLevel.Information))
105101
{
106-
definition.ConfigureServices(builder);
102+
logger.LogInformation("[AppDefinitions entry points found]: {@items}", string.Join(", ", definitionCollection.EntryPoints));
107103
}
108104

109-
if (logger.IsEnabled(LogLevel.Debug))
110-
{
111-
logger.LogDebug("[AppDefinitions]: From {@items}", string.Join(", ", info.EntryPoints));
105+
var items = definitionCollection.GetDistinct().ToList();
112106

113-
foreach (var item in info.Items.OrderBy(x => x.Definition.GetType().Name))
107+
foreach (var item in items)
108+
{
109+
if (logger.IsEnabled(LogLevel.Debug))
114110
{
115-
logger.LogDebug("[AppDefinitions]: {@AppDefinitionName} ({@AssemblyName}) (Enabled: {@Enabled})", item.Definition.GetType().Name, item.AssemblyName, item.Definition.Enabled ? "Yes" : "No");
111+
logger.LogDebug("[AppDefinitions for ConfigureServices]: {@AssemblyName}:{@AppDefinitionName} is {EnabledOrDisabled} {ExportEnabled}",
112+
item.AssemblyName,
113+
item.Definition.GetType().Name,
114+
item.Enabled ? "enabled" : "disabled",
115+
item.Exported ? "(exported)" : "export disabled");
116116
}
117+
118+
item.Definition.ConfigureServices(builder);
119+
}
120+
121+
builder.Services.AddSingleton(definitionCollection);
122+
123+
if (!logger.IsEnabled(LogLevel.Debug))
124+
{
125+
return;
126+
}
127+
128+
var skipped = definitionCollection.GetEnabled().Except(items).ToList();
129+
if (!skipped.Any())
130+
{
131+
return;
132+
}
133+
134+
logger.LogWarning("[AppDefinitions skipped for ConfigureServices: {Count}", skipped.Count);
135+
foreach (var item in skipped)
136+
{
137+
logger.LogWarning("[AppDefinitions skipped for ConfigureServices]: {@AssemblyName}:{@AppDefinitionName} is {EnabledOrDisabled}",
138+
item.AssemblyName,
139+
item.Definition.GetType().Name,
140+
item.Enabled ? "enabled" : "disabled");
117141
}
118142

119-
builder.Services.AddSingleton(info);
120143
}
121144

122145
/// <summary>
@@ -130,20 +153,52 @@ public static void AddDefinitions(this WebApplicationBuilder builder, params Typ
130153
public static void UseDefinitions(this WebApplication source)
131154
{
132155
var logger = source.Services.GetRequiredService<ILogger<AppDefinition>>();
133-
var definitions = source.Services.GetRequiredService<AppDefinitionCollection>();
156+
var definitionCollection = source.Services.GetRequiredService<AppDefinitionCollection>();
157+
158+
var items = definitionCollection.GetDistinct().ToList();
134159

135-
if (logger.IsEnabled(LogLevel.Debug))
160+
foreach (var item in items)
136161
{
137-
logger.LogDebug("From {Modules} assemblies totally AppDefinitions found: {Count} ", string.Join(", ", definitions.EntryPoints), definitions.Items.Count);
162+
if (logger.IsEnabled(LogLevel.Debug))
163+
{
164+
logger.LogDebug("[AppDefinitions for ConfigureApplication]: {@AssemblyName}:{@AppDefinitionName} is {EnabledOrDisabled}",
165+
item.AssemblyName,
166+
item.Definition.GetType().Name,
167+
item.Enabled
168+
? "enabled"
169+
: "disabled");
170+
}
171+
172+
item.Definition.ConfigureApplication(source);
138173
}
139174

140-
var instancesOrdered = definitions.Items.Where(x => x.Definition.Enabled).OrderBy(x => x.Definition.OrderIndex).ToList();
175+
if (!logger.IsEnabled(LogLevel.Debug))
176+
{
177+
if (logger.IsEnabled(LogLevel.Information))
178+
{
179+
logger.LogInformation("[AppDefinitions applied: {Count} of {Total}", items.Count, definitionCollection.GetEnabled().Count());
180+
}
181+
return;
182+
}
141183

142-
instancesOrdered.ForEach(x => x.Definition.ConfigureApplication(source));
184+
var skipped = definitionCollection.GetEnabled().Except(items).ToList();
185+
if (!skipped.Any())
186+
{
187+
logger.LogInformation("[AppDefinitions applied: {Count} of {Total}", items.Count, definitionCollection.GetEnabled().Count());
188+
return;
189+
}
143190

144-
if (logger.IsEnabled(LogLevel.Debug))
191+
logger.LogWarning("[AppDefinitions skipped for ConfigureApplication: {Count}", skipped.Count);
192+
foreach (var item in skipped)
145193
{
146-
logger.LogDebug("Total AppDefinitions applied: {Count}", instancesOrdered.Count);
194+
logger.LogWarning("[AppDefinitions skipped for ConfigureApplication]: {@AssemblyName}:{@AppDefinitionName} is {EnabledOrDisabled} {ExportEnabled}",
195+
item.AssemblyName,
196+
item.Definition.GetType().Name,
197+
item.Enabled ? "enabled" : "disabled",
198+
item.Exported ? "(exported)" : "export disabled");
147199
}
200+
201+
logger.LogInformation("[AppDefinitions applied: {Count} of {Total}", items.Count, definitionCollection.GetEnabled().Count());
202+
148203
}
149204
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace Calabonga.AspNetCore.AppDefinitions;
2+
3+
4+
/// <summary>
5+
/// Information about <see cref="IAppDefinition"/>
6+
/// </summary>
7+
/// <param name="Definition"></param>
8+
/// <param name="AssemblyName"></param>
9+
/// <param name="Enabled"></param>
10+
/// <param name="Exported"></param>
11+
public sealed record AppDefinitionItem(IAppDefinition Definition, string AssemblyName, bool Enabled, bool Exported);

src/Calabonga.AspNetCore.AppDefinitions/Calabonga.AspNetCore.AppDefinitions.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<Nullable>enable</Nullable>
77
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
88
<Title>Calabonga.AspNetCore.AppDefinitions</Title>
9-
<Version>2.2.0</Version>
9+
<Version>2.3.0</Version>
1010
<Authors>Calabonga</Authors>
1111
<Company>Calabonga Soft</Company>
1212
<Product>Calabonga.AspNetCore.AppDefinitions</Product>
@@ -17,8 +17,8 @@
1717
<PackageReadmeFile>README.md</PackageReadmeFile>
1818
<RepositoryUrl>https://github.com/Calabonga/Calabonga.AspNetCore.AppDefinitions</RepositoryUrl>
1919
<RepositoryType>git</RepositoryType>
20-
<PackageTags>calabonga;architecture;definitions;minimal-api;nimble-framework</PackageTags>
21-
<PackageReleaseNotes>Updated for profject template for dotnet CLI</PackageReleaseNotes>
20+
<PackageTags>calabonga;architecture;application;definitions;minimal-api;nimble-framework</PackageTags>
21+
<PackageReleaseNotes>Processing for dublicates was removed. Some additional information added for DEBUG logging.</PackageReleaseNotes>
2222
<PackageLicenseExpression>MIT</PackageLicenseExpression>
2323
</PropertyGroup>
2424

0 commit comments

Comments
 (0)