Why should I create interfaces for my concrete DataProvider classes
Tag : chash , By : John Q.
Date : March 29 2020, 07:55 AM
may help you . You should create interfaces in order to make testing code that depends on your data easier. Having interfaces and coding to these interfaces means you can inject mocks and stubs in your tests.
|
Concrete classes vs interfaces: When to use?
Date : March 29 2020, 07:55 AM
seems to work fine In your IConnection example you're basically describing an abstract Connect() method, since each class will have to implement its own version. Usually (always?) abstract methods can only be defined with the same parameters, so Connect(username, password) and Connect(key) couldn't be implementations of the same Connect() method from an interface. Now, at this point, you could define it as IConnection::Connect(SomeConnectionData) and derive UsernamePasswordConnectionData and KeyConnectionData, etc., etc. from that SomeConnectionData class but all this would be so hard to explain and implement that its pretty good clue that interfaces and inheritance aren't helping the situation.
|
How to deserialize collection of interfaces when concrete classes contains other interfaces
Tag : chash , By : alchemist
Date : March 29 2020, 07:55 AM
hope this fix your issue Your basic problem is that your ConcreteConverter is designed to deserialize something declared as an interface as a concrete type -- e.g. IItemModel as Item -- but you are not using it in that way. You are using it to deserialize a concrete list of interfaces as a concrete list of concrete types, e.g.:[JsonProperty( "items" )]
[JsonConverter( typeof( ConcreteConverter<List<IItemModel>, List<Item>>) )]
public List<IItemModel> Items { get; set; }
public class ThumbnailJobModel : IJobModel
{
[JsonProperty("items", ItemConverterType = typeof(ConcreteConverter<IItemModel, Item>))]
public List<IItemModel> Items { get; set; }
public class Item : IItemModel
{
[JsonProperty("shoots", ItemConverterType = typeof(ConcreteConverter<ICamSettings, ShootSettings>))]
public List<ICamSettings> CamSettings { get; set; }
public class StrictStringEnumConverter : StringEnumConverter
{
public StrictStringEnumConverter() { this.AllowIntegerValues = false; }
}
public class ConcreteConverter<IInterface, TConcrete> : JsonConverter where TConcrete : IInterface
{
}
public override bool CanConvert( Type objectType )
{
return objectType == typeof( string );
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ExportType);
}
public interface IJobModel
{
string ClientBaseURL { get; set; }
string UserEmail { get; set; }
ExportType Type { get; set; }
List<IItemModel> Items { get; set; }
}
public interface IItemModel
{
string Id { get; set; }
string ImageSize { get; set; }
string ImagePpi { get; set; }
List<ICamSettings> CamSettings { get; set; }
}
public interface ICamSettings
{
string FileName { get; set; }
}
public enum ExportType
{
Thumbnails,
}
public class ThumbnailJobModel : IJobModel
{
[JsonProperty("clientBaseURL")]
public string ClientBaseURL { get; set; }
[JsonProperty("userEmail")]
public string UserEmail { get; set; }
[JsonProperty("type")]
[JsonConverter(typeof(ExportTypeConverter))]
public ExportType Type { get; set; }
[JsonProperty("items", ItemConverterType = typeof(ConcreteConverter<IItemModel, Item>))]
public List<IItemModel> Items { get; set; }
public ThumbnailJobModel()
{
Type = ExportType.Thumbnails;
Items = new List<IItemModel>();
}
public class Item : IItemModel
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("imageSize")]
public string ImageSize { get; set; }
[JsonProperty("imagePpi")]
public string ImagePpi { get; set; }
[JsonProperty("shoots", ItemConverterType = typeof(ConcreteConverter<ICamSettings, ShootSettings>))]
public List<ICamSettings> CamSettings { get; set; }
public Item()
{
CamSettings = new List<ICamSettings>();
}
}
public class ShootSettings : ICamSettings
{
[JsonProperty("orientation")]
[JsonConverter(typeof(StrictStringEnumConverter))]
public Orientation Orientation { get; set; }
[JsonProperty("clothShape")]
[JsonConverter(typeof(StrictStringEnumConverter))]
public Shape Shape { get; set; }
[JsonProperty("fileName")]
public string FileName { get; set; }
public ShootSettings()
{
Orientation = Orientation.Perspective;
Shape = Shape.Folded;
FileName = null;
}
}
public enum Orientation
{
Perspective = 0,
Oblique = 1,
Front = 2,
Back = 3,
Left = 4,
Right = 5,
Up = 6,
Down = 7
}
public enum Shape
{
Folded = 0,
Hanger = 1,
Mannequin = 2
}
public class ConcreteConverter<IInterface, TConcrete> : JsonConverter where TConcrete : IInterface
{
public override bool CanConvert(Type objectType)
{
return typeof(IInterface) == objectType;
}
public override object ReadJson(JsonReader reader,
Type objectType, object existingValue, JsonSerializer serializer)
{
return serializer.Deserialize<TConcrete>(reader);
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
public class ExportTypeConverter : StringEnumConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
reader.Skip(); // Skip anything at the current reader's position.
return ExportType.Thumbnails;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ExportType);
}
}
public class StrictStringEnumConverter : StringEnumConverter
{
public StrictStringEnumConverter() { this.AllowIntegerValues = false; }
}
public static void HandleDeserializationError(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs errorArgs)
{
errorArgs.ErrorContext.Handled = true;
var currentObj = errorArgs.CurrentObject as ShootSettings;
if (currentObj == null) return;
currentObj.Orientation = Orientation.Perspective;
currentObj.Shape = Shape.Folded;
}
}
|
Interfaces exposing properties and Kotlin data classes
Date : December 24 2020, 04:01 AM
hop of those help? Here's how I'd define these in kotlin, just using a name property (no need for a getName() method) and being sure to use the override keyword: interface HasName {
val name: String
}
data class Image(override val name: String, val url: URL): HasName
|
Mapping Interfaces to concrete classes
Tag : chash , By : FriendL
Date : March 29 2020, 07:55 AM
|