-
Notifications
You must be signed in to change notification settings - Fork 16
Abstract Away From The Serialisation/Deserialisation Implementation. #94
Comments
Yes, I agree. The architecture around the conversion part needs to be improved. I'm really happy this issue was raised! I was thinking recently on the same lines, and this harks back to chats with @jmirtsch from almost one year ago. What you suggest is sound. Here's me saying it back to you, so we see if we agree, albeit i'll flow it differently + I'm after a day long of meetings, so my head isn't fully clear, but i did my best below :) The When an object/list of objects gets passed in for (de)serialisation, the core If some are found, it picks the first one and goes forward. If none are found, it falls back on the existing abstract routines to try and make sense of it via all that stuff (I know a few shops are relying on this feature rather hard). Another alternative would have the If these converters are somehow dynamically injectable via the end user (ie, use the Curiosity bites: what's the use case that made you raise this issue? |
I think we’re on the same page! A stack of converters can be employed for converting different types. A developer could then inject the core converter with say, standard Speckle converters (the fall back converter you mentioned, maybe one for primitive types?), and also inject some custom converters fairly easily. This core converter can then be passed around and used wherever a conversion is needed in a client. For convenience a helper method could be used to serve up a converter pre-loaded with standard converters. I think an issue with the second option is although a converter can be injected and preferred for conversion, standard routines for conversions are still somewhat hidden. Whereas with the first option, the standard converters being used can be exposed. They are then present in some capacity to some consumer of the api. That’s interesting. A issue would be serving up valid converters for the stream on the end user side. Different clients will have dependencies on their respective software, so not all converters would be usable. There was actually no real use case in this instance, I was just trying to understand the general usage of the |
We'll need to map out the changes first in more detail, as it might be a very extensive change. I'm even mulling, because of the rather large scope, to slap a How would the interface ISpeckleConverter {
// takes an object and speckleises it
public SpeckleObject ToSpeckle(object obj);
// the reverse of the above
public object ToNative(SpeckleObject obj);
// helpers, optional, not sure if needed
public bool CanConvertToSpeckle(Type t)
public bool CanConvertToNative(Type t)
} I would still keep the |
kinda like this #56 ? 😜
👏 |
On a more serious note, have a look at the awesome & automagical way NancyFX does
|
@radumg, there's no facepalm reaction, but yeah - thanks for reminding us about #56, where we conclude we don't want to force dependencies on speckle core by others, hence no interfaces. Meanwhile though, speckle did grow a bit so we could go that way in Nancy is a super perfect good shout actually... and perhaps the way to go forward. I've never seen the similarity between the hacky reflect-o-matic speckle approach and nancy, but will for sure have a look! |
@didimitrie I think the speckle convert could be exactly like that, with one minor change. Introduce generic types instead of concrete public interface ISpeckleConverter<TSpeckle, TNative> where TSpeckle : SpeckleObject
{
TSpeckle ToSpeckle(TNative native);
TNative ToNative(TSpeckle speckle);
} So the standard, generic (fall back) converter would be: public class GenericConverter : ISpeckleConverter<SpeckleObject, object>
{
public SpeckleObject ToSpeckle(object native)
{
// Some conversion logic
}
public object ToNative(SpeckleObject speckle)
{
// Some conversion logic
}
} The generic types allow an implementer to explicitly state their argument and return types and serves as a concise way to distinguish between each implementer via their conversion types. In regard to keeping the As an idea of architecture, when the An simple implementation of the public class ConverterFactory
{
public void RegisterConverter<Tspeckle, TNative>
(ISpeckleConverter<TSpeckle, TNative> speckleConverter) where TSpeckle : SpeckleObject
{
// Register the converter.
}
// This might not be required?
public void UnregisterConverter<Tspeckle, TNative>
(ISpeckleConverter<TSpeckle, TNative> speckleConverter)
{
// Unregister the given converter.
}
public dynamic GetConverter(Type speckleType, Type nativeType)
{
// Get the Converter
}
} A simple implementation of the public class Converter
{
public Converter(ConverterFactory factory)
{
Factory = factory;
}
ConverterFactory Factory { get; }
public dynamic Serialise(dynamic native)
{
// Instruct the factory to return a converter that will serialise from the run-time native type to the speckle type.
// Call ToSpeckle on this speckle converter.
// return the speckle type.
}
public dynamic Deserialise(SpeckleObject speckle)
{
// Instruct the factory to return the converter that will deserialise from the speckle type to a native type.
// Call ToNative on this speckle converter.
// return the native type.
}
} At compile-time the implementer of Configuring the factory and converter doesn’t take a lot of lines of code (the majority is registering converters): // Create a factory and inject it into a core converter. Multiple converters can be registered with the factory.
var factory = new ConverterFactor().RegisterConverter(new GenericConverter());
var converter = new Converter(factory); Once configured, the below call can be made anywhere the core converter is in scope var speckleObject = converter.Serialise(anObject);
var nativeObject = converter.Deserialise(aSpeckleObject); This is easily adapted and would require only a new implementation of a converter that scans for 3rd party extensions to be registered to use something similar to the Nancy approach mentioned. |
Step 0:
Issue
The api for converting between speckle and native types currently hides the dependency on extension methods named ToNative and ToSpeckle that lie in an assembly with Speckle and Converter in its name. Reading the code or documentation is the only way to realise the requirement of this dependency. This doesn’t offer a lot of flexibility in choosing how converters are consumed by the Speckle api.
Impact
Any projects where the current converter is used.
Looking through the repo, this effects:
Solution
Just an idea on how to solve this:
The text was updated successfully, but these errors were encountered: