FrameworkContainers 4.1.0
See the version list below for details.
dotnet add package FrameworkContainers --version 4.1.0
NuGet\Install-Package FrameworkContainers -Version 4.1.0
<PackageReference Include="FrameworkContainers" Version="4.1.0" />
paket add FrameworkContainers --version 4.1.0
#r "nuget: FrameworkContainers, 4.1.0"
// Install FrameworkContainers as a Cake Addin #addin nuget:?package=FrameworkContainers&version=4.1.0 // Install FrameworkContainers as a Cake Tool #tool nuget:?package=FrameworkContainers&version=4.1.0
FrameworkContainers
Useful parts of Frameworks wrapped into single types.
PM> Install-Package FrameworkContainers
TL;DR
Replace what would normally be a whole service, with a single type.
Instead of creating some HttpService
file everytime you start a new project, use the Http
type instead.
Types are created with sensible defaults, sync, async, and error handled versions are also provided.
Works with dependency injection frameworks, types are low allocation; preferring to be static
under the hood.
var response = await Http.PostJsonAsync<TRequest, TResponse>(request, url, headers);
Intro
This library contains snippets of code I find myself adding over, and over again to new projects.
The code is reusable, as it's not domain specific, though it is influenced by the way I code.
The components are not that complex, you could recreate them in a few hours, to similar effect.
That said, it's rather the point; I want those few hours back for each new project (and I'm sick of copy-pasting!).
Components
Each component has a static
core, from here the methods can be accessed easily inline; as a standard type
(i.e. no dependency injection required).
If dependency injection is needed, then each component also has a Client type
, with an accompanying interface
.
The components have been designed to handle most use cases, with the true aim to be simple to use.
If you find some component does not meet your needs, then drop it and write custom code instead of fighting the framework.
The components are built to be performant, and have the best defaults set; they are hard to use in a wrong way.
There are three distinct ways to use a component (excluding the static / client options mentioned above).
You can use the raw type T
, which will throw any encountered exceptions.
You can use Response<T>
, which will internally log any exceptions (when you set a logger), and only return a value of T
when it can.
You can use Maybe<T>
, which will return either T
, or the error type Exception
.
If you would like to know more about types: Response
, and Maybe
; please visit their repo ContainerExpressions.
Http Component
Send, and receive all the things over the network.
This component has support for get
, post
, put
, and delete
; with both sync
, and async
APIs.
The sync
APIs are built on top of System.Net.WebRequest
.
The async
APIs are built on top of System.Net.Http.HttpClient
.
[Things we do for you]
- Set a default timeout of 15 seconds.
- Set the content type, and content length.
- Write in UTF-8.
- Read error responses, adding them to the generated
HttpException
. - Renew DNS (for the domain(s) you are calling).
- Disable insecure ciphers, only leaving up to date ones active.
- Enable fast header read.
- Async JSON uses
System.Net.Http.Json
, to serialize models viaSystem.IO.Pipelines
for best performance.
[Examples]
Get http body T
:
string body = Http.Get("/api/weather");
Get http body Response<T>
:
Response<string> body = Http.Response.Get("/api/weather");
Get http body Maybe<T>
:
Maybe<string> body = Http.Maybe.Get("/api/weather");
Get http body IHttpClient
:
IHttpClient http = new HttpClient();
string body = http.Get("/api/weather");
Create a new User
from an Onboard
request object using JSON
, and the async
API:
User user = await Http.PostJsonAsync<User, Onboard>(request);
Json Component
Serialize, and deserialize JSON to, and from domain models.
This component's APIs are built on top of System.Text.Json.JsonSerializer
.
[Things we do for you]
- Two serializer categories: Performant, and Permissive; one for speed, and one that "just works".
- JSON converters for standard types to "just work", they include:
bool
,DateTime
,Enum
,Float
,Guid
,Int
, andLong
.
[Examples]
Json to model:
string json = "{\"name\": \"John Smith\"}";
User user = Json.ToModel<User>(json);
Model to json:
User user = new User { Name = "John Smith" };
string json = Json.FromModel(user);
Setting the JSON options:
User user = Json.ToModel<User>(json, JsonOptions.Performant);
Using a JSON converter (strings are converted to ints, nulls are converetd to 0, invalid values still throw errors):
[JsonConverter(typeof(DefaultIntConverter))]
public int Age { get; set; }
using Response<T>
:
Response<User> user = Json.Response.ToModel<User>(json);
Using Maybe<T>
:
Maybe<User> user = Json.Maybe.ToModel<User>(json);
Using IJsonClient
:
IJsonClient json = new JsonClient();
User user = json.ToModel<User>(json);
Xml Component
Serialize, and deserialize XML to, and from domain models.
This component's APIs are built on top of System.Xml.Serialization.XmlSerializer
.
[Things we do for you]
- Remove default namespaces, and omit the XML declaration.
- Allow custom character encodings.
- Protection against malicious exceptions.
- Optimized stream for the XML deserializer, reducing string allocation.
[Examples]
XML to model:
User user = Xml.ToModel<User>(xml);
Model to XML:
string xml = Xml.FromModel(user);
Setting the XML options:
string xml = Xml.FromModel(user, new XmlOptions(true, true, null));
using Response<T>
:
Response<User> user = Xml.Response.ToModel<User>(json);
Using Maybe<T>
:
Maybe<User> user = Xml.Maybe.ToModel<User>(json);
Using IXmlClient
:
IXmlClient xml = new XmlClient();
User user = xml.ToModel<User>(json);
Sql Component
Insert, update, select, and delete your way though the database (via stored procedures).
This component's APIs are built on top of System.Data.SqlClient.SqlConnection
.
[Things we do for you]
- Provide both
sync
, andasync
APIs for:ExecuteReader
,ExecuteNonQuery
, andBulkInsert
. - Allow easy access to values with the
Get<T>
extension method.
[Examples]
Setting the global connection string:
Sql.ConnectionString = connectionString;
ExecuteNonQuery:
int rows = Sql.ExecuteNonQuery("usp_insert_user", new SqlParameter("@name", "John Smith"));
ExecuteNonQuery, overriding the global connection string:
int rows = Sql.ExecuteNonQuery("usp_insert_user", connectionString, new SqlParameter("@name", "John Smith"));
Async ExecuteReader using Get<T>
:
IEnumerable<User> Read(IDataReader dr)
{
List<User> results = new List<User>();
while (dr.Read())
{
results.Add(new User
{
name = dr.Get<string>("Name")
});
}
return results;
}
IEnumerable<User> users = await Sql.ExecuteReaderAsync(Read, "usp_select_users");
BulkInsert:
DataTable table = new DataTable();
table.Columns.Add("Name");
foreach (User user in users)
{
var row = table.NewRow();
row["Name"] = user.Name;
table.Rows.Add(row);
}
table.AcceptChanges();
Sql.BulkInsert("tblUsers", table);
using Response<T>
:
Response<int> rows = Sql.Response.ExecuteNonQuery("usp_insert_user", new SqlParameter("@name", "John Smith"));
Using Maybe<T>
:
Maybe<int> rows = Sql.Maybe.ExecuteNonQuery("usp_insert_user", new SqlParameter("@name", "John Smith"));
Using ISqlClient
:
ISqlClient sql = new SqlClient();
int rows = sql.ExecuteNonQuery("usp_insert_user", new SqlParameter("@name", "John Smith"));
Dependency Injection Component
Adds types to your DI framework of choice.
You provide a mapper, and DependencyInjection
will provide the types.
Types are added by a naming convention: interface IService
will match implementation Service
.
There is a "sandbox mode", for cases when you'd like to provide different implementations.
When enabled any implementation of ServiceSandbox
, will override Service
.
[Things we do for you]
- Scan assemblies, find all exported types, and match IService, to Service.
- Provide a "sandbox mode", so services can be swapped out.
[Examples]
Using ASP.NET CORE's IServiceCollection
:
public void ConfigureServices(IServiceCollection services)
{
DependencyInjection.AddServicesByConvention((x, y) => services.AddSingleton(x, y));
}
Credits
- Icon made by Vitaly Gorbachev from Flaticon.
Changelog
2.0.0
- Started a changelog - reset the project.
- Added
Sql
forExecuteReader
,ExecuteNonQuery
, andBulkInsert
database operations. - Added
Http
forGet
,Post
,Put
, andDelete
network operations. - Added
Json
forSerialize
, andDeserialize
model operations. - Added
Xml
forSerialize
, andDeserialize
model operations. - Updated nuget pack settings, to make the project easier to deploy.
2.1.0
- Added a Dependency Injection helper, to add types from assemblies by naming convention (IService ⇒ Service).
2.2.0
- Removed the "Standalone" option for from
DependencyInjection
, as it was not needed when we already have "Sandbox" options.
3.0.0
- Added a maximum to the recursive depth for the XML, and JSON serializers; providing protection against malicious stackoverflow exceptions.
- Optimized the XML deserializer, to reduce string allocation when writing to a stream; adding seperate read, and write
XmlOptions
. - Added JSON options to the HTTP options model.
- Generally aligned the interfaces between the clients.
4.0.0
- Replaced raw http string responses with a type:
HttpBody
. - Added a new method to
Http
: Post245, a general way to cover 200, 400, and 500 http responses individually. - Simplifed
Xml
, removing it'sXmlOptions
type. - Added new
WebClientOptions
toHttpOptions
for customHttpClient
configuration, and cancellation tokens.
4.1.0
- Added new awaitable http verb types allowing:
var response = await new Get("https://example.com");
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 | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | 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 | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- ContainerExpressions (>= 10.0.0)
- System.Data.SqlClient (>= 4.8.6)
- System.Net.Http.Json (>= 8.0.0)
- System.Text.Encodings.Web (>= 8.0.0)
- System.Text.Json (>= 8.0.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Updated nuget package dependencies to the latest versions.