Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ public enum StronglyTypedIdBackingType
Long = 4,
NullableString = 5,
MassTransitNewId = 6,
ObjectId = 7
}
}
5 changes: 5 additions & 0 deletions src/StronglyTypedIds.Attributes/StronglyTypedIdConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,10 @@ public enum StronglyTypedIdConverter
/// Creates a Dapper TypeHandler for converting to and from the type
/// </summary>
DapperTypeHandler = 32,

/// <summary>
/// Creates a Mongo Serializer for converting string to and from type
/// </summary>
MongoSerializer = 64,
}
}
23 changes: 23 additions & 0 deletions src/StronglyTypedIds/EmbeddedSources.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ internal static class EmbeddedSources
LoadEmbeddedResource("StronglyTypedIds.Templates.Guid.Guid_EfCoreValueConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Guid.Guid_DapperTypeHandler.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Guid.Guid_IComparable.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Guid.Guid_MongoSerializer.cs"),
false
);

Expand All @@ -37,6 +38,7 @@ internal static class EmbeddedSources
LoadEmbeddedResource("StronglyTypedIds.Templates.Int.Int_EfCoreValueConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Int.Int_DapperTypeHandler.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Int.Int_IComparable.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Int.Int_MongoSerializer.cs"),
false
);

Expand All @@ -49,6 +51,7 @@ internal static class EmbeddedSources
LoadEmbeddedResource("StronglyTypedIds.Templates.Long.Long_EfCoreValueConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Long.Long_DapperTypeHandler.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Long.Long_IComparable.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Long.Long_MongoSerializer.cs"),
false
);

Expand All @@ -61,6 +64,7 @@ internal static class EmbeddedSources
LoadEmbeddedResource("StronglyTypedIds.Templates.String.String_EfCoreValueConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.String.String_DapperTypeHandler.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.String.String_IComparable.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.String.String_MongoSerializer.cs"),
false
);

Expand All @@ -73,6 +77,7 @@ internal static class EmbeddedSources
LoadEmbeddedResource("StronglyTypedIds.Templates.NullableString.NullableString_EfCoreValueConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.NullableString.NullableString_DapperTypeHandler.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.NullableString.NullableString_IComparable.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.NullableString.NullableString_MongoSerializer.cs"),
true
);

Expand All @@ -85,12 +90,27 @@ internal static class EmbeddedSources
LoadEmbeddedResource("StronglyTypedIds.Templates.NewId.NewId_EfCoreValueConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.NewId.NewId_DapperTypeHandler.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.NewId.NewId_IComparable.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.NewId.NewId_MongoSerializer.cs"),
false
);

internal static readonly ResourceCollection ObjectIdResources = new(
AutoGeneratedHeader,
LoadEmbeddedResource("StronglyTypedIds.Templates.ObjectId.ObjectId_Base.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.ObjectId.ObjectId_NewtonsoftJsonConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.ObjectId.ObjectId_SystemTextJsonConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.ObjectId.ObjectId_TypeConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.ObjectId.ObjectId_EfCoreValueConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.ObjectId.ObjectId_DapperTypeHandler.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.ObjectId.ObjectId_IComparable.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.ObjectId.ObjectId_MongoSerializer.cs"),
false
);

internal const string TypeConverterAttributeSource = " [System.ComponentModel.TypeConverter(typeof(TESTIDTypeConverter))]";
internal const string NewtonsoftJsonAttributeSource = " [Newtonsoft.Json.JsonConverter(typeof(TESTIDNewtonsoftJsonConverter))]";
internal const string SystemTextJsonAttributeSource = " [System.Text.Json.Serialization.JsonConverter(typeof(TESTIDSystemTextJsonConverter))]";
internal const string MongoSerializerAttributeSource = " [MongoDB.Bson.Serialization.Attributes.BsonSerializer(typeof(TESTIDMongoSerializer))]";

internal static string LoadEmbeddedResource(string resourceName)
{
Expand All @@ -116,6 +136,7 @@ public readonly struct ResourceCollection
public string TypeConverter { get; }
public string EfCoreValueConverter { get; }
public string DapperTypeHandler { get; }
public string Mongo { get; }
public string Comparable { get; }

public ResourceCollection(
Expand All @@ -127,6 +148,7 @@ public ResourceCollection(
string efCoreValueConverter,
string dapperTypeHandler,
string comparable,
string mongo,
bool nullableEnable)
{
BaseId = baseId;
Expand All @@ -137,6 +159,7 @@ public ResourceCollection(
DapperTypeHandler = dapperTypeHandler;
Comparable = comparable;
NullableEnable = nullableEnable;
Mongo = mongo;
Header = header;
}
}
Expand Down
12 changes: 12 additions & 0 deletions src/StronglyTypedIds/SourceGenerationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public static string CreateId(
StronglyTypedIdBackingType.String => EmbeddedSources.StringResources,
StronglyTypedIdBackingType.NullableString => EmbeddedSources.NullableStringResources,
StronglyTypedIdBackingType.MassTransitNewId => EmbeddedSources.NewIdResources,
StronglyTypedIdBackingType.ObjectId => EmbeddedSources.ObjectIdResources,
_ => throw new ArgumentException("Unknown backing type: " + backingType, nameof(backingType)),
};

Expand Down Expand Up @@ -69,6 +70,7 @@ static string CreateId(
var useSystemTextJson = converters.IsSet(StronglyTypedIdConverter.SystemTextJson);
var useEfCoreValueConverter = converters.IsSet(StronglyTypedIdConverter.EfCoreValueConverter);
var useDapperTypeHandler = converters.IsSet(StronglyTypedIdConverter.DapperTypeHandler);
var useMongoSerializer = converters.IsSet(StronglyTypedIdConverter.MongoSerializer);

var useIEquatable = implementations.IsSet(StronglyTypedIdImplementations.IEquatable);
var useIComparable = implementations.IsSet(StronglyTypedIdImplementations.IComparable);
Expand Down Expand Up @@ -121,6 +123,11 @@ static string CreateId(
{
sb.AppendLine(EmbeddedSources.TypeConverterAttributeSource);
}

if (useMongoSerializer)
{
sb.AppendLine(EmbeddedSources.MongoSerializerAttributeSource);
}

sb.Append(resources.BaseId);
ReplaceInterfaces(sb, useIEquatable, useIComparable);
Expand Down Expand Up @@ -156,6 +163,11 @@ static string CreateId(
{
sb.AppendLine(resources.SystemTextJson);
}

if (useMongoSerializer)
{
sb.AppendLine(resources.Mongo);
}

sb.Replace("TESTID", idName);
sb.AppendLine(@" }");
Expand Down
12 changes: 12 additions & 0 deletions src/StronglyTypedIds/Templates/Guid/Guid_MongoSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
 class TESTIDMongoSerializer : MongoDB.Bson.Serialization.Serializers.SerializerBase<TESTID>
{
public override TESTID Deserialize(MongoDB.Bson.Serialization.BsonDeserializationContext context, MongoDB.Bson.Serialization.BsonDeserializationArgs args)
{
return new TESTID(new System.Guid(context.Reader.ReadString()));
}

public override void Serialize(MongoDB.Bson.Serialization.BsonSerializationContext context, MongoDB.Bson.Serialization.BsonSerializationArgs args, TESTID value)
{
context.Writer.WriteString(value.Value.ToString());
}
}
12 changes: 12 additions & 0 deletions src/StronglyTypedIds/Templates/Int/Int_MongoSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
 class TESTIDMongoSerializer : MongoDB.Bson.Serialization.Serializers.SerializerBase<TESTID>
{
public override TESTID Deserialize(MongoDB.Bson.Serialization.BsonDeserializationContext context, MongoDB.Bson.Serialization.BsonDeserializationArgs args)
{
return new TESTID(context.Reader.ReadInt32());
}

public override void Serialize(MongoDB.Bson.Serialization.BsonSerializationContext context, MongoDB.Bson.Serialization.BsonSerializationArgs args, TESTID value)
{
context.Writer.WriteInt32(value.Value);
}
}
12 changes: 12 additions & 0 deletions src/StronglyTypedIds/Templates/Long/Long_MongoSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
 class TESTIDMongoSerializer : MongoDB.Bson.Serialization.Serializers.SerializerBase<TESTID>
{
public override TESTID Deserialize(MongoDB.Bson.Serialization.BsonDeserializationContext context, MongoDB.Bson.Serialization.BsonDeserializationArgs args)
{
return new TESTID(context.Reader.ReadInt64());
}

public override void Serialize(MongoDB.Bson.Serialization.BsonSerializationContext context, MongoDB.Bson.Serialization.BsonSerializationArgs args, TESTID value)
{
context.Writer.WriteInt64(value.Value);
}
}
12 changes: 12 additions & 0 deletions src/StronglyTypedIds/Templates/NewId/NewId_MongoSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
 class TESTIDMongoSerializer : MongoDB.Bson.Serialization.Serializers.SerializerBase<TESTID>
{
public override TESTID Deserialize(MongoDB.Bson.Serialization.BsonDeserializationContext context, MongoDB.Bson.Serialization.BsonDeserializationArgs args)
{
return new TESTID(MassTransit.NewId.FromGuid(new System.Guid(context.Reader.ReadString())));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to go through Guid here? You could use new NewId(context.Reader.ReadString()) I think 🙂 (similar for Serialize())

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have right :) I simplified it

}

public override void Serialize(MongoDB.Bson.Serialization.BsonSerializationContext context, MongoDB.Bson.Serialization.BsonSerializationArgs args, TESTID value)
{
context.Writer.WriteString(value.Value.ToGuid().ToString());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
 class TESTIDMongoSerializer : MongoDB.Bson.Serialization.Serializers.SerializerBase<TESTID>
{
public override TESTID Deserialize(MongoDB.Bson.Serialization.BsonDeserializationContext context, MongoDB.Bson.Serialization.BsonDeserializationArgs args)
{
return new TESTID(context.Reader.ReadString());
}

public override void Serialize(MongoDB.Bson.Serialization.BsonSerializationContext context, MongoDB.Bson.Serialization.BsonSerializationArgs args, TESTID value)
{
if (value.Value is null)
{
context.Writer.WriteNull();
}
else
{
context.Writer.WriteString(value.Value);
}
}
}
24 changes: 24 additions & 0 deletions src/StronglyTypedIds/Templates/ObjectId/ObjectId_Base.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
 readonly partial struct TESTID : INTERFACES
{
public MongoDB.Bson.ObjectId Value { get; }

public TESTID(MongoDB.Bson.ObjectId value)
{
Value = value;
}

public static TESTID New() => new TESTID(MongoDB.Bson.ObjectId.GenerateNewId());
public static readonly TESTID Empty = new TESTID(MongoDB.Bson.ObjectId.Empty);

public bool Equals(TESTID other) => this.Value.Equals(other.Value);
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
return obj is TESTID other && Equals(other);
}

public override int GetHashCode() => Value.GetHashCode();

public override string ToString() => Value.ToString();
public static bool operator ==(TESTID a, TESTID b) => a.Equals(b);
public static bool operator !=(TESTID a, TESTID b) => !(a == b);
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

public class DapperTypeHandler : Dapper.SqlMapper.TypeHandler<TESTID>
{
public override void SetValue(System.Data.IDbDataParameter parameter, TESTID value)
{
parameter.Value = value.Value.ToString();
}

public override TESTID Parse(object value)
{
return value switch
{
string stringValue when !string.IsNullOrEmpty(stringValue) => new TESTID(new MongoDB.Bson.ObjectId(stringValue)),
_ => throw new System.InvalidCastException($"Unable to cast object of type {value.GetType()} to TESTID"),
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

public class EfCoreValueConverter : Microsoft.EntityFrameworkCore.Storage.ValueConversion.ValueConverter<TESTID, string>
{
public EfCoreValueConverter() : this(null) { }
public EfCoreValueConverter(Microsoft.EntityFrameworkCore.Storage.ValueConversion.ConverterMappingHints mappingHints = null)
: base(
id => id.Value.ToString(),
value => new TESTID(new MongoDB.Bson.ObjectId(value)),
mappingHints
) { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
 public int CompareTo(TESTID other) => Value.CompareTo(other.Value);
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
 class TESTIDMongoSerializer : MongoDB.Bson.Serialization.Serializers.SerializerBase<TESTID>
{
public override TESTID Deserialize(MongoDB.Bson.Serialization.BsonDeserializationContext context, MongoDB.Bson.Serialization.BsonDeserializationArgs args)
{
return new TESTID(context.Reader.ReadObjectId());
}

public override void Serialize(MongoDB.Bson.Serialization.BsonSerializationContext context, MongoDB.Bson.Serialization.BsonSerializationArgs args, TESTID value)
{
context.Writer.WriteObjectId(value.Value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

class TESTIDNewtonsoftJsonConverter : Newtonsoft.Json.JsonConverter
{
public override bool CanConvert(System.Type objectType)
{
return objectType == typeof(TESTID);
}

public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
{
var id = (TESTID)value;
serializer.Serialize(writer, id.Value.ToString());
}

public override object ReadJson(Newtonsoft.Json.JsonReader reader, System.Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
{
return new TESTID(new MongoDB.Bson.ObjectId(serializer.Deserialize<string>(reader)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

class TESTIDSystemTextJsonConverter : System.Text.Json.Serialization.JsonConverter<TESTID>
{
public override TESTID Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options)
{
return new TESTID(new MongoDB.Bson.ObjectId(reader.GetString()));
}

public override void Write(System.Text.Json.Utf8JsonWriter writer, TESTID value, System.Text.Json.JsonSerializerOptions options)
{
writer.WriteStringValue(value.Value.ToString());
}
}
42 changes: 42 additions & 0 deletions src/StronglyTypedIds/Templates/ObjectId/ObjectId_TypeConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

class TESTIDTypeConverter : System.ComponentModel.TypeConverter
{
public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType)
{
return sourceType == typeof(MongoDB.Bson.ObjectId) || sourceType == typeof(string) || base.CanConvertFrom
(context, sourceType);
}

public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
return value switch
{
MongoDB.Bson.ObjectId objectIdValue => new TESTID(objectIdValue),
string stringValue when !string.IsNullOrEmpty(stringValue) => new TESTID(new MongoDB.Bson.ObjectId(stringValue)),
_ => base.ConvertFrom(context, culture, value),
};
}

public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType)
{
return sourceType == typeof(MongoDB.Bson.ObjectId) || sourceType == typeof(string) || base.CanConvertTo(context, sourceType);
}

public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType)
{
if (value is TESTID idValue)
{
if (destinationType == typeof(MongoDB.Bson.ObjectId))
{
return idValue.Value;
}

if (destinationType == typeof(string))
{
return idValue.Value.ToString();
}
}

return base.ConvertTo(context, culture, value, destinationType);
}
}
12 changes: 12 additions & 0 deletions src/StronglyTypedIds/Templates/String/String_MongoSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
 class TESTIDMongoSerializer : MongoDB.Bson.Serialization.Serializers.SerializerBase<TESTID>
{
public override TESTID Deserialize(MongoDB.Bson.Serialization.BsonDeserializationContext context, MongoDB.Bson.Serialization.BsonDeserializationArgs args)
{
return new TESTID(context.Reader.ReadString());
}

public override void Serialize(MongoDB.Bson.Serialization.BsonSerializationContext context, MongoDB.Bson.Serialization.BsonSerializationArgs args, TESTID value)
{
context.Writer.WriteString(value.Value);
}
}
Loading