Skip to content

Commit dd7bf5e

Browse files
committed
Apply factory method defaults to TableRepository/TablePartition constructors
Just in case objects are somehow constructed bypassing the non-nullable requirement for arguments, apply the same default values we apply in the factory methods for consistency. Fixes #13
1 parent 894e951 commit dd7bf5e

File tree

4 files changed

+41
-20
lines changed

4 files changed

+41
-20
lines changed

src/TableStorage/TablePartition.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,26 @@ public static ITablePartition<T> Create<T>(
6767
string? partitionKey = null,
6868
Func<T, string>? rowKey = null) where T : class
6969
{
70-
tableName ??= tableName ??= defaultTableNames.GetOrAdd(typeof(T),
71-
type => type.GetCustomAttribute<TableAttribute>()?.Name ?? DefaultTableName);
72-
73-
partitionKey ??= (typeof(T).Name.EndsWith("Entity") ?
74-
typeof(T).Name.Substring(0, typeof(T).Name.Length - 6) :
75-
typeof(T).Name);
76-
70+
tableName ??= GetDefaultTableName<T>();
71+
partitionKey ??= GetDefaultPartitionKey<T>();
7772
rowKey ??= RowKeyAttribute.CreateAccessor<T>();
7873

7974
return new TablePartition<T>(storageAccount, tableName, partitionKey, rowKey);
8075
}
76+
77+
/// <summary>
78+
/// Gets a default table name for entities of type <typeparamref name="T"/>. Will be the
79+
/// <see cref="TableAttribute.Name"/> if the attribute is present, or <see cref="DefaultTableName"/> otherwise.
80+
/// </summary>
81+
public static string GetDefaultTableName<T>() =>
82+
defaultTableNames.GetOrAdd(typeof(T), type => type.GetCustomAttribute<TableAttribute>()?.Name ?? DefaultTableName);
83+
84+
/// <summary>
85+
/// Gets a default partition key to use for entities of type <typeparamref name="T"/>. Will be the
86+
/// the type name, stripped of a suffix <c>Entity</c> if present.
87+
/// </summary>
88+
public static string GetDefaultPartitionKey<T>() => typeof(T).Name.EndsWith("Entity") ?
89+
typeof(T).Name.Substring(0, typeof(T).Name.Length - 6) :
90+
typeof(T).Name;
8191
}
8292
}

src/TableStorage/TablePartition`1.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,43 @@ namespace Devlooped
1313
partial class TablePartition<T> : ITablePartition<T> where T : class
1414
{
1515
readonly ITableRepository<T> repository;
16-
readonly string partitionKey;
1716

1817
/// <summary>
1918
/// Initializes the repository with the given storage account and optional table name.
2019
/// </summary>
2120
/// <param name="storageAccount">The storage account to use.</param>
2221
/// <param name="tableName">Optional table name. If no value is provided, <see cref="DefaultTableName"/> will be used.</param>
2322
public TablePartition(CloudStorageAccount storageAccount, string tableName, string partitionKey, Func<T, string> rowKey)
24-
=> (this.repository, TableName, this.partitionKey)
25-
= (new TableRepository<T>(storageAccount, tableName, _ => partitionKey, rowKey), tableName, partitionKey);
23+
{
24+
TableName = tableName ?? TablePartition.GetDefaultTableName<T>();
25+
PartitionKey = partitionKey ?? TablePartition.GetDefaultPartitionKey<T>();
26+
repository = new TableRepository<T>(storageAccount,
27+
TableName,
28+
_ => PartitionKey,
29+
rowKey ?? RowKeyAttribute.CreateAccessor<T>());
30+
}
2631

2732
/// <inheritdoc />
2833
public string TableName { get; }
2934

3035
/// <inheritdoc />
31-
public string PartitionKey => partitionKey;
36+
public string PartitionKey { get; }
3237

3338
/// <inheritdoc />
3439
public Task DeleteAsync(T entity, CancellationToken cancellation = default)
3540
=> repository.DeleteAsync(entity, cancellation);
3641

3742
/// <inheritdoc />
3843
public Task DeleteAsync(string rowKey, CancellationToken cancellation = default)
39-
=> repository.DeleteAsync(partitionKey, rowKey, cancellation);
44+
=> repository.DeleteAsync(PartitionKey, rowKey, cancellation);
4045

4146
/// <inheritdoc />
4247
public IAsyncEnumerable<T> EnumerateAsync(CancellationToken cancellation = default)
43-
=> repository.EnumerateAsync(partitionKey, cancellation);
48+
=> repository.EnumerateAsync(PartitionKey, cancellation);
4449

4550
/// <inheritdoc />
4651
public Task<T?> GetAsync(string rowKey, CancellationToken cancellation = default)
47-
=> repository.GetAsync(partitionKey, rowKey, cancellation);
52+
=> repository.GetAsync(PartitionKey, rowKey, cancellation);
4853

4954
/// <inheritdoc />
5055
public Task<T> PutAsync(T entity, CancellationToken cancellation = default)

src/TableStorage/TableRepository.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Concurrent;
3-
using System.Linq;
43
using System.Reflection;
54
using Microsoft.Azure.Cosmos.Table;
65

@@ -48,11 +47,18 @@ public static ITableRepository<T> Create<T>(
4847
Func<T, string>? partitionKey = null,
4948
Func<T, string>? rowKey = null) where T : class
5049
{
51-
tableName ??= defaultTableNames.GetOrAdd(typeof(T), type => type.GetCustomAttribute<TableAttribute>()?.Name ?? type.Name);
50+
tableName ??= GetDefaultTableName<T>();
5251
partitionKey ??= PartitionKeyAttribute.CreateAccessor<T>();
5352
rowKey ??= RowKeyAttribute.CreateAccessor<T>();
5453

5554
return new TableRepository<T>(storageAccount, tableName, partitionKey, rowKey);
5655
}
56+
57+
/// <summary>
58+
/// Gets a default table name for entities of type <typeparamref name="T"/>. Will be the
59+
/// <see cref="TableAttribute.Name"/> if the attribute is present, or the type name otherwise.
60+
/// </summary>
61+
public static string GetDefaultTableName<T>() =>
62+
defaultTableNames.GetOrAdd(typeof(T), type => type.GetCustomAttribute<TableAttribute>()?.Name ?? type.Name);
5763
}
5864
}

src/TableStorage/TableRepository`1.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ partial class TableRepository<T> : ITableRepository<T> where T : class
3131
public TableRepository(CloudStorageAccount storageAccount, string tableName, Func<T, string> partitionKey, Func<T, string> rowKey)
3232
{
3333
this.storageAccount = storageAccount;
34-
table = new AsyncLazy<CloudTable>(() => GetTableAsync(tableName));
35-
TableName = tableName;
36-
this.partitionKey = partitionKey;
37-
this.rowKey = rowKey;
34+
TableName = tableName ?? TableRepository.GetDefaultTableName<T>();
35+
this.partitionKey = partitionKey ?? PartitionKeyAttribute.CreateAccessor<T>();
36+
this.rowKey = rowKey ?? RowKeyAttribute.CreateAccessor<T>();
37+
table = new AsyncLazy<CloudTable>(() => GetTableAsync(TableName));
3838
}
3939

4040
/// <inheritdoc />

0 commit comments

Comments
 (0)