Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nullable types #345

Merged
merged 4 commits into from
Aug 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<AnalysisLevel>latest</AnalysisLevel>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<NuGetAuditLevel>critical</NuGetAuditLevel>
<Nullable>enable</Nullable>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)' == 'Release'">
Expand Down
22 changes: 9 additions & 13 deletions src/LinkDotNet.Blog.Domain/BlogPost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,29 @@ namespace LinkDotNet.Blog.Domain;

public sealed partial class BlogPost : Entity
{
private BlogPost()
{
}

public string Title { get; private set; }
public string Title { get; private set; } = default!;

public string ShortDescription { get; private set; }
public string ShortDescription { get; private set; } = default!;

public string Content { get; private set; }
public string Content { get; private set; } = default!;

public string PreviewImageUrl { get; private set; }
public string PreviewImageUrl { get; private set; } = default!;

public string PreviewImageUrlFallback { get; private set; }
public string? PreviewImageUrlFallback { get; private set; }

public DateTime UpdatedDate { get; private set; }

public DateTime? ScheduledPublishDate { get; private set; }

public IList<string> Tags { get; private set; }
public IList<string> Tags { get; private set; } = [];

public bool IsPublished { get; private set; }

public int Likes { get; set; }

public bool IsScheduled => ScheduledPublishDate is not null;

public string TagsAsString => string.Join(",", Tags ?? []);
public string TagsAsString => string.Join(",", Tags);

public int ReadingTimeInMinutes { get; private set; }

Expand Down Expand Up @@ -95,8 +91,8 @@ public static BlogPost Create(
bool isPublished,
DateTime? updatedDate = null,
DateTime? scheduledPublishDate = null,
IEnumerable<string> tags = null,
string previewImageUrlFallback = null)
IEnumerable<string>? tags = null,
string? previewImageUrlFallback = null)
{
if (scheduledPublishDate is not null && isPublished)
{
Expand Down
2 changes: 1 addition & 1 deletion src/LinkDotNet.Blog.Domain/BlogPostRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace LinkDotNet.Blog.Domain;

public class BlogPostRecord : Entity
{
public string BlogPostId { get; init; }
public required string BlogPostId { get; init; }

public DateOnly DateClicked { get; init; }

Expand Down
2 changes: 1 addition & 1 deletion src/LinkDotNet.Blog.Domain/Entity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

public abstract class Entity
{
public string Id { get; set; }
public string Id { get; set; } = default!;
}
8 changes: 2 additions & 6 deletions src/LinkDotNet.Blog.Domain/Enumeration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ public abstract class Enumeration<TEnumeration>
where TEnumeration : Enumeration<TEnumeration>
#pragma warning restore
{
protected Enumeration()
{
}

protected Enumeration(string key)
{
ArgumentException.ThrowIfNullOrWhiteSpace(key);
Expand All @@ -35,7 +31,7 @@ public static TEnumeration Create(string key)

public override int GetHashCode() => Key.GetHashCode(StringComparison.Ordinal);

public override bool Equals(object obj) => obj?.GetType() == typeof(TEnumeration) && ((TEnumeration)obj).Key == Key;
public override bool Equals(object? obj) => obj?.GetType() == typeof(TEnumeration) && ((TEnumeration)obj).Key == Key;

public override string ToString() => Key;

Expand All @@ -46,7 +42,7 @@ private static FrozenSet<TEnumeration> GetEnumerations()
return enumerationType
.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)
.Where(info => info.FieldType == typeof(TEnumeration))
.Select(info => (TEnumeration)info.GetValue(null))
.Select(info => (TEnumeration)info.GetValue(null)!)
.ToFrozenSet();
}
}
6 changes: 3 additions & 3 deletions src/LinkDotNet.Blog.Domain/Introduction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ public sealed record Introduction
{
public const string IntroductionSection = "Introduction";

public string BackgroundUrl { get; init; }
public string? BackgroundUrl { get; init; }

public string ProfilePictureUrl { get; init; }
public required string ProfilePictureUrl { get; init; }

public string Description { get; init; }
public required string Description { get; init; }
}
2 changes: 1 addition & 1 deletion src/LinkDotNet.Blog.Domain/LinkDotNet.Blog.Domain.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>disable</Nullable>
<Nullable>enable</Nullable>
<AssemblyName>LinkDotNet.Blog.Domain</AssemblyName>
<RootNamespace>LinkDotNet.Blog.Domain</RootNamespace>
</PropertyGroup>
Expand Down
6 changes: 1 addition & 5 deletions src/LinkDotNet.Blog.Domain/ProficiencyLevel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,8 @@ public sealed class ProficiencyLevel : Enumeration<ProficiencyLevel>
public static readonly ProficiencyLevel Proficient = new(nameof(Proficient));
public static readonly ProficiencyLevel Expert = new(nameof(Expert));

private ProficiencyLevel()
{
}

private ProficiencyLevel(string key)
: base(key)
{
}
}
}
7 changes: 4 additions & 3 deletions src/LinkDotNet.Blog.Domain/ProfileInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
public sealed record ProfileInformation
{
public const string ProfileInformationSection = "ProfileInformation";
public string Name { get; init; }

public string Heading { get; init; }
public required string Name { get; init; }

public string ProfilePictureUrl { get; init; }
public required string Heading { get; init; }

public required string ProfilePictureUrl { get; init; }
}
6 changes: 1 addition & 5 deletions src/LinkDotNet.Blog.Domain/ProfileInformationEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ namespace LinkDotNet.Blog.Domain;
[DebuggerDisplay("{Content} with sort order {SortOrder}")]
public sealed class ProfileInformationEntry : Entity
{
private ProfileInformationEntry()
{
}

public string Content { get; private init; }
public string Content { get; private init; } = default!;

public int SortOrder { get; set; }

Expand Down
10 changes: 3 additions & 7 deletions src/LinkDotNet.Blog.Domain/Skill.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,23 @@ namespace LinkDotNet.Blog.Domain;

public sealed class Skill : Entity
{
private Skill()
{
}

private Skill(string name, string iconUrl, string capability, ProficiencyLevel proficiencyLevel)
private Skill(string name, string? iconUrl, string capability, ProficiencyLevel proficiencyLevel)
{
IconUrl = iconUrl;
Name = name;
Capability = capability;
ProficiencyLevel = proficiencyLevel;
}

public string IconUrl { get; private set; }
public string? IconUrl { get; private set; }

public string Name { get; private set; }

public string Capability { get; private set; }

public ProficiencyLevel ProficiencyLevel { get; private set; }

public static Skill Create(string name, string iconUrl, string capability, string proficiencyLevel)
public static Skill Create(string name, string? iconUrl, string capability, string proficiencyLevel)
{
ArgumentException.ThrowIfNullOrWhiteSpace(name);
ArgumentException.ThrowIfNullOrWhiteSpace(capability);
Expand Down
8 changes: 4 additions & 4 deletions src/LinkDotNet.Blog.Domain/Social.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ public sealed record Social
{
public const string SocialSection = "Social";

public string LinkedinAccountUrl { get; init; }
public string? LinkedinAccountUrl { get; init; }

public bool HasLinkedinAccount => !string.IsNullOrEmpty(LinkedinAccountUrl);

public string GithubAccountUrl { get; init; }
public string? GithubAccountUrl { get; init; }

public bool HasGithubAccount => !string.IsNullOrEmpty(GithubAccountUrl);

public string TwitterAccountUrl { get; init; }
public string? TwitterAccountUrl { get; init; }

public bool HasTwitterAccount => !string.IsNullOrEmpty(TwitterAccountUrl);
}
}
10 changes: 3 additions & 7 deletions src/LinkDotNet.Blog.Domain/Talk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,11 @@ namespace LinkDotNet.Blog.Domain;

public sealed class Talk : Entity
{
private Talk()
{
}

public string PresentationTitle { get; private set; }
public string PresentationTitle { get; private set; } = default!;

public string Place { get; private set; }
public string Place { get; private set; } = default!;

public string Description { get; private set; }
public string Description { get; private set; } = default!;

public DateTime PublishedDate { get; private set; }

Expand Down
2 changes: 1 addition & 1 deletion src/LinkDotNet.Blog.Domain/UserRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ public sealed class UserRecord : Entity
{
public DateOnly DateClicked { get; init; }

public string UrlClicked { get; init; }
public required string UrlClicked { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFramework>net9.0</TargetFramework>
<AssemblyName>LinkDotNet.Blog.Infrastructure</AssemblyName>
<RootNamespace>LinkDotNet.Blog.Infrastructure</RootNamespace>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,24 @@ public CachedRepository(IRepository<T> repository, IMemoryCache memoryCache)

public ValueTask<HealthCheckResult> PerformHealthCheckAsync() => repository.PerformHealthCheckAsync();

public async ValueTask<T> GetByIdAsync(string id) =>
await memoryCache.GetOrCreateAsync(id, async entry =>
public async ValueTask<T?> GetByIdAsync(string id) =>
(await memoryCache.GetOrCreateAsync(id, async entry =>
{
entry.SlidingExpiration = TimeSpan.FromDays(7);
return await repository.GetByIdAsync(id);
});
}))!;

public async ValueTask<IPagedList<T>> GetAllAsync(
Expression<Func<T, bool>> filter = null,
Expression<Func<T, object>> orderBy = null,
public async ValueTask<IPagedList<T>> GetAllAsync(Expression<Func<T, bool>>? filter = null,
Expression<Func<T, object>>? orderBy = null,
bool descending = true,
int page = 1,
int pageSize = int.MaxValue) =>
await repository.GetAllAsync(filter, orderBy, descending, page, pageSize);

public async ValueTask<IPagedList<TProjection>> GetAllByProjectionAsync<TProjection>(
Expression<Func<T, TProjection>> selector,
Expression<Func<T, bool>> filter = null,
Expression<Func<T, object>> orderBy = null,
Expression<Func<T, TProjection>>? selector,
Expression<Func<T, bool>>? filter = null,
Expression<Func<T, object>>? orderBy = null,
bool descending = true,
int page = 1,
int pageSize = int.MaxValue) =>
Expand Down
13 changes: 6 additions & 7 deletions src/LinkDotNet.Blog.Infrastructure/Persistence/IRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,19 @@ public interface IRepository<TEntity>
{
ValueTask<HealthCheckResult> PerformHealthCheckAsync();

ValueTask<TEntity> GetByIdAsync(string id);
ValueTask<TEntity?> GetByIdAsync(string id);

ValueTask<IPagedList<TEntity>> GetAllAsync(
Expression<Func<TEntity, bool>> filter = null,
Expression<Func<TEntity,
object>> orderBy = null,
Expression<Func<TEntity, bool>>? filter = null,
Expression<Func<TEntity, object>>? orderBy = null,
bool descending = true,
int page = 1,
int pageSize = int.MaxValue);

ValueTask<IPagedList<TProjection>> GetAllByProjectionAsync<TProjection>(
Expression<Func<TEntity, TProjection>> selector,
Expression<Func<TEntity, bool>> filter = null,
Expression<Func<TEntity, object>> orderBy = null,
Expression<Func<TEntity, TProjection>>? selector,
Expression<Func<TEntity, bool>>? filter = null,
Expression<Func<TEntity, object>>? orderBy = null,
bool descending = true,
int page = 1,
int pageSize = int.MaxValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,23 @@ public sealed class Repository<TEntity> : IRepository<TEntity>

public ValueTask<HealthCheckResult> PerformHealthCheckAsync() => ValueTask.FromResult(HealthCheckResult.Healthy());

public ValueTask<TEntity> GetByIdAsync(string id)
public ValueTask<TEntity?> GetByIdAsync(string id)
{
var entity = entities.SingleOrDefault(b => b.Id == id);
return new ValueTask<TEntity>(entity);
var entity = entities.Find(b => b.Id == id);
return new ValueTask<TEntity?>(entity);
}

public ValueTask<IPagedList<TEntity>> GetAllAsync(
Expression<Func<TEntity, bool>> filter = null,
Expression<Func<TEntity, object>> orderBy = null,
public ValueTask<IPagedList<TEntity>> GetAllAsync(Expression<Func<TEntity, bool>>? filter = null,
Expression<Func<TEntity, object>>? orderBy = null,
bool descending = true,
int page = 1,
int pageSize = int.MaxValue) =>
GetAllByProjectionAsync(s => s, filter, orderBy, descending, page, pageSize);

public ValueTask<IPagedList<TProjection>> GetAllByProjectionAsync<TProjection>(
Expression<Func<TEntity, TProjection>> selector,
Expression<Func<TEntity, bool>> filter = null,
Expression<Func<TEntity, object>> orderBy = null,
Expression<Func<TEntity, TProjection>>? selector,
Expression<Func<TEntity, bool>>? filter = null,
Expression<Func<TEntity, object>>? orderBy = null,
bool descending = true,
int page = 1,
int pageSize = int.MaxValue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,24 @@ public async ValueTask<HealthCheckResult> PerformHealthCheckAsync()
}
}

public async ValueTask<TEntity> GetByIdAsync(string id)
public async ValueTask<TEntity?> GetByIdAsync(string id)
{
var filter = Builders<TEntity>.Filter.Eq(e => e.Id, id);
var result = await Collection.FindAsync(filter);
return await result.FirstOrDefaultAsync();
}

public async ValueTask<IPagedList<TEntity>> GetAllAsync(
Expression<Func<TEntity, bool>> filter = null,
Expression<Func<TEntity, object>> orderBy = null,
public async ValueTask<IPagedList<TEntity>> GetAllAsync(Expression<Func<TEntity, bool>>? filter = null,
Expression<Func<TEntity, object>>? orderBy = null,
bool descending = true,
int page = 1,
int pageSize = int.MaxValue) =>
await GetAllByProjectionAsync(s => s, filter, orderBy, descending, page, pageSize);

public async ValueTask<IPagedList<TProjection>> GetAllByProjectionAsync<TProjection>(
Expression<Func<TEntity, TProjection>> selector,
Expression<Func<TEntity, bool>> filter = null,
Expression<Func<TEntity, object>> orderBy = null,
Expression<Func<TEntity, TProjection>>? selector,
Expression<Func<TEntity, bool>>? filter = null,
Expression<Func<TEntity, object>>? orderBy = null,
bool descending = true,
int page = 1,
int pageSize = int.MaxValue)
Expand Down
Loading