Shadow.Quack 2.3.0

dotnet add package Shadow.Quack --version 2.3.0
NuGet\Install-Package Shadow.Quack -Version 2.3.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Shadow.Quack" Version="2.3.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Shadow.Quack --version 2.3.0
#r "nuget: Shadow.Quack, 2.3.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Shadow.Quack as a Cake Addin
#addin nuget:?package=Shadow.Quack&version=2.3.0

// Install Shadow.Quack as a Cake Tool
#tool nuget:?package=Shadow.Quack&version=2.3.0

Shadow Quack

This package allows the easy population of values directly from an existing object or dynamic to a dynamically implemented immutable interface it also allow the merge of several objects or dynamic retuning a new object.

Though it is possible to use interfaces with both getters and setters the intent is for use with interfaces with get-only properties making the contract immutable.

The combination of these two functions makes an interface the only required data contract. The merge functionality allows for functional operations to return an new object with the values from one or more source. The use of a dynamic in this context allows for the simple overriding of one or more properties. The resulting new object has the new property values set with the remaining properties carrying the values through from the source.

There are also many abstraction applications where being able to Duck Type data to an interface from an object outside of your control turns out to be very useful.

Duck.Implement<T>()

 public interface IData
 {
    int Property1 { get; }
    string Property2 { get; }
 }
 var data = Duck.Implement<IData>(new
 {
     Property1 = 100,
     Property2 = "This"
 });        

Duck.Implement<IEnumerable<T>>() & Duck.Implement<List<T>>()

 var result = Duck.Implement<List<string>>(new[] { 1, 2, 3, 4 });

 var result = Duck.Implement<IEnumerable<string>>(new[] { 1, 2, 3, 4 });

Interfaces can be used value definitions, as required, using the same priciples as any other Duck.Implement<T>() Call.

Duck.Implement<IDicionary<TKey>, <TValue>>() & Duck.Implement<Dicionary<TKey>, <TValue>>()

 var result = Duck.Implement<IDictionary<int, string>>(new[] { new { Key = 1, Value = "value" } });

 var result = Duck.Implement<Dictionary<int, string>>(new[] { new { Key = 1, Value = "value" } });

Interfaces can be used for both key and value definitions, as required, using the same priciples as any other Duck.Implement<T>() Call.

Duck.Merge<T>()

 var data = Duck.Implement<IData>(new
 {
     Property1 = 100,
     Property2 = "This"
 });

 var merged = Duck.Merge<IData>(data, new {Property2 = "That"});

This results in Property1 = 100, and Property2 = "That", this is useful if you want to take an existing object and just update one property, this creates a new object keeping the immutability of the original source. You can merge several objects on a last one wins basis.

 var data = Duck.Implement<IData>(new
 {
     Property1 = 100,
     Property2 = "This"
 });

 var merged = Duck.Merge<IData>(data, 
     new { Property2 = "That" }, 
     new { Property1 = 35 }, 
     new { Property2 = "Other" });

This results in Property1 = 35, and Property2 = "Other"

Cast Extensions

The following extensions are exposed for general use.

.CastStringTo<T>([T default])

Allows casting of a string value to the below set of native types, with an optional default value

  • string
  • char or char?
  • long or long?
  • int or int?
  • byte or byte?
  • short or short?
  • bool or bool?
  • DateTime or DateTime?
  • decimal or decimal?
  • float or float?
  • double or double?
 var stringValue = "123";
 var intValue = stringValue.CastStringTo<int>, -1);

intValue will be 123, passing an empty or null string would return -1.

.CastStringToEnum<T>()

The cast is case insensitive and will interpret a space " " as an underscore "_" e.g. My Enum Value = My_Enum_Value

 public enum MyEnum
 {
    TypeOne = 1,
    TypeThree = 3,
    Type_Four = 4
 }
 ...
 var stringValue = "type four";
 var intValue = stringValue.CastStringToEnum<MyEnum>();

This will cast it to MyEnum.Type_Four.

Merge Extensions

The following extensions give a cleaner usage of the Merge<T>() function

 var config = Duck.Implement<IConfig>(new
 {
    Int64Value = "12345",
    NumericValue = "123"
 });

 var result = config.MergeWithTo<IMergedConfig>(new { NumericValue = "456" });
 var config = Duck.Implement<IConfig>(new
    {
        Int64Value = "12345",
        NumericValue = "123"
    });

 config = config.MergeWith(new { NumericValue = "456" });

Notes

If <T> is not an interface, with the exceprion of the cast extensions, an InterfaceExpectedException will be thrown.

IProxy

Shadow Quack also allows extension via Proxy types, this is done via an IProxy interface and a custom Type and Property classes.

The extensions written already, provided in separate packages, include;

  • Shadow Quack JSON
  • Shadow Quack CSV
  • Shadow Quack XML
  • Shadow Quack Args

There is also a further extension of this ecosystem in Quack API which includes custom implementation of JsonConverter and JsonConvertorFactory, that wrap the JSON proxy, to allow the use of Interfaces as return and parameter types in ASP .Net API calls.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
.NET Framework net45 is compatible.  net451 was computed.  net452 was computed.  net46 was computed.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on Shadow.Quack:

Package Downloads
Shadow.Quack.Json

IProxy implementation to allow JSON as the input to Duck.Implement<T>(T source)

Shadow.Quack.Csv

IProxy implementation to allow CSV as the input to Duck.Implement

Shadow.Quack.Xml

Shadow.Quack IProxy Implementation for initialisation from an XML string

Shadow.Quack.Args

IProxy implementation to allow a Command Line Arguments Array as the input to Duck.Implement<T>(T Source)

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2.3.0 4,450 4/5/2022
2.2.1 703 3/23/2022
2.2.0 941 2/10/2022
2.1.1 1,800 1/30/2022
2.0.4 1,646 1/19/2022
2.0.3 1,124 12/5/2021
2.0.2 1,096 9/11/2021
2.0.1 912 9/10/2021
2.0.0 939 6/18/2021
1.9.0 771 5/27/2021
1.8.0 526 5/24/2021
1.7.0 682 4/23/2021
1.6.0 334 4/22/2021
1.5.0 552 4/17/2021
1.4.0 719 4/17/2021
1.3.0 657 4/13/2021
1.2.0 354 4/9/2021
1.1.0 325 4/5/2021
1.0.0 651 3/29/2021

Fixed : string parse of Timespan "d:H:M:s"