Closed dest-all closed 1 year ago
Thanks for the suggestion. I can't really imagine its usefulness, so it would be great if you could show me some pseudo code.
Thanks for the suggestion. I can't really imagine its usefulness, so it would be great if you could show me some pseudo code.
Here you are.
All the idea will work only in .net 7+.
class CacheManager // Ability to have something like this class is the main goal of the suggested feature
void PutToCache(byte[] info) => /*implementation*/
byte[] GetByKey(object key) => /*implementation*/
public void Put<T>(object key, T item) where T : IPackable // for super-efficient outer-service cache storage this service should accept only MemoryPackable types - and alas we cannot set the requirement like 'HasAttribute<MemoryPackable>'
{
var infoCached = item.ToByteArray();
PutToCache(infoCached);
}
public T Get<T>(object key) where T : IPackable<T>
{
var infoCached = GetByKey(key);
return T.FromByteArray(infoCached);
}
/*
The two public methods demostrate how elegantly we do the type guessing logic at compile type + have to write less code for it.
*/
[PackCascade]
partial interface IPackable // Interface name here is arbitrary - it will a parameter on the source generation step
// With creating different interfaces we allow ourselves to create different scopes for deserialization.
// For example, here we introduced IPackable and created logic around its types. If we add, say, ISendable the logic will be separate and ISendable and IPackable won't cross.
partial abstract class Entity : IPackable // now we treat the class and its heirs as if they had "[MemoryPackable]" above it.
public long Id { get; }
partial class PersonInfo : Entity
public string FirstName { get; set; }
public string LastName { get; set; }
partial class EmployeeInfo : PersonInfo
public long[] ResponsibleForOrders { get; set; }
partial class Order : Entity
public long ResponsibleEmployeeId { get; set; }
Generated code.
partial interface IPackable
byte[] ToByteArray();
partial interface IPackable<TSelf> : IPackable // new interface with awareness of the implementing type - for deserizliation purposes
static abstract TSelf FromByteArray(byte[] bytes);
partial abstract class Entity
public abstract byte[] ToByteArray(); // if class is abstract then interface implementation has to be abstract too.
byte[] IPackable.ToByteArray() => ToByteArray();
// Generate the standard code for MemoryPackSerializer for PersonInfo here
partial class PersonInfo : IPackable<PersonInfo>
public static PersonInfo FromByteArray(byte[] bytes) => MemoryPackSerializer.Deserialize<PersonInfo>(bytes);
public override byte[] ToByteArray() => MemoryPackSerializer.Serialize(this);
// Generate the standard code for MemoryPackSerializer for EmployeeInfo here
partial class EmployeeInfo : IPackable<PersonInfo>
public static EmployeeInfo FromByteArray(byte[] bytes) => MemoryPackSerializer.Deserialize<EmployeeInfo>(bytes);
public override byte[] ToByteArray() => MemoryPackSerializer.Serialize(this);
// Generate the standard code for MemoryPackSerializer for Order here
partial class Order : IPackable<PersonInfo>
public static EmployeeInfo FromByteArray(byte[] bytes) => MemoryPackSerializer.Deserialize<EmployeeInfo>(bytes);
public override byte[] ToByteArray() => MemoryPackSerializer.Serialize(this);`
Thanks for the suggestion. I can't really imagine its usefulness, so it would be great if you could show me some pseudo code.
Have you made any decision on this one?
I have a feeling that this is within the scope of what you can devise on your application side.
If you prefer generics, there is IMemoryPackable<T>
.
Additional to marking class for MemoryPack source generation, it may be handy to do the same with interface implementation or other class inheritance. We mark a class/interface with a, for example, "PackCascade" attribute and then all its heir/implementing types will be treated as though they are marked with the "MemoryPack" attribute. The reasoning for usefulness of this feature is that:
I could help making the thing, but I'm new to community coding, so any guide on how to deliver the code changes to this specific project I'd much appreciate.