Shadow.Quack
2.3.0
dotnet add package Shadow.Quack --version 2.3.0
NuGet\Install-Package Shadow.Quack -Version 2.3.0
<PackageReference Include="Shadow.Quack" Version="2.3.0" />
paket add Shadow.Quack --version 2.3.0
#r "nuget: Shadow.Quack, 2.3.0"
// 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 | Versions 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. |
-
.NETFramework 4.5
- System.Reflection.Emit (>= 4.7.0)
- System.ValueTuple (>= 4.5.0)
-
.NETStandard 2.1
- System.Reflection.Emit (>= 4.7.0)
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,596 | 4/5/2022 |
2.2.1 | 739 | 3/23/2022 |
2.2.0 | 983 | 2/10/2022 |
2.1.1 | 1,884 | 1/30/2022 |
2.0.4 | 1,719 | 1/19/2022 |
2.0.3 | 1,269 | 12/5/2021 |
2.0.2 | 1,187 | 9/11/2021 |
2.0.1 | 992 | 9/10/2021 |
2.0.0 | 1,017 | 6/18/2021 |
1.9.0 | 822 | 5/27/2021 |
1.8.0 | 565 | 5/24/2021 |
1.7.0 | 746 | 4/23/2021 |
1.6.0 | 360 | 4/22/2021 |
1.5.0 | 609 | 4/17/2021 |
1.4.0 | 787 | 4/17/2021 |
1.3.0 | 748 | 4/13/2021 |
1.2.0 | 382 | 4/9/2021 |
1.1.0 | 355 | 4/5/2021 |
1.0.0 | 711 | 3/29/2021 |
Fixed : string parse of Timespan "d:H:M:s"