I have a soft spot in my heart for rust and a passionate distrust (that has slowly turned into hatred) for interpreted, loosely typed languages, but it’s hard to deny the convenience of being able to bang out a bash script you can literally just write and run without having to deal with the edit-compile-run loop, let alone create a new project, worry about whether or not you’re going to check it into version control, and everything else that somehow tends to go hand-in-hand with modern strongly typed languages.
A nifty but scarcely known rust feature is that the language parser will ignore a shebang at the start of the source code file, meaning you can install an interpreter that will compile and run your rust code when you execute the
.rs file – without losing the ability to compile it normally. cargo-script is one such interpreter, meaning you can
cargo install cargo-script then execute your source code (after making it executable,
:! chmod +x %) with something like this:
It’s been a while since we first released our SecureStore.NET library for C# and ASP.NET developers back in 2017, as a solution for developers looking for an uncomplicated way of safely and securely storing secrets without needing to build and maintain an entire infrastructure catering to that end. Originally built way back in 2015 to support secrets storage in legacy ASP.NET applications, SecureStore.NET has been since updated for ASP.NET Core and UWP desktop application development, and now we’re proud to announce the release of SecureStore 1.0 with multi-platform and cross-framework support, with an updated schema making a few more features possible and official implementations in C#/.NET and Rust.
Microsoft’s official documentation on adding custom model binding providers to convert between (typically) a string and a custom type for complex model binding in ASP.NET Core as of .NET Core 3.1 goes something like this:
- Create an
IModelBinder for your class and use
[ModelBinder(BinderType = typeof(MyModelEntityBinder)] to decorate each and every binding site, e.g.
public async Task<IActionResult> OnPost([ModelBinder(BinderType = typeof(MyModelEntityBinder)]) MyModel model), which provides the runtime with the type information it needs to instantiate the model binding provider and convert the input to a model.
- Optionally create an
IModelBinderProvider class and register it with the ASP.NET Core host to provide the type information ahead-of-time (once and for all), so that you can instead use the barebones and much shorter decoration at each model binding site instead:
public async Task<IActionResult> OnPost([ModelBinder] MyModel model)
The latter is significantly easier on the eyes and far less error prone… but where does the type registration take place? Per the linked documentation, the recommendation is the following in
One of the nicest things about ASP.NET Core is the availability of certain singleton models that greatly simplify some very common developer needs. Given that (depending on who you ask) one of the two hardest problems in computing is caching1, it’s extremely helpful that ASP.NET Core ships with several models for caching data, chief of which are
IDistributedCache, added to an ASP.NET Core application via dependency injection and then available to both the framework and the application itself. Although these two expose almost identical APIs, they differ rather significantly in semantics.2
Have you ever needed to compare the contents of two files (or other streams), and it mattered how quickly you got it done? To be frank, it doesn’t normally come up in the list of things you may need on a daily code-crunching basis, but that rather depends on what kind of programs you tend to write. In our world, let’s just say it’s not an uncommon task.
At a first blush, it would seem to be no harder than comparing two arrays. A pointer reading from each file, compare bytes as you come across them, and bail when things differ. And it would be that easy if you were to use memory-mapped files and let the OS map a file on disk to a range in memory, but that has some drawbacks that may not always be OK depending on what you’re trying to do with the files (or streams) in question. It also requires having a physical path on the filesystem that you can pass in to the kernel, and it unduly burdens the kernel with some not insignificant workloads that aren’t (in practice) subject to the same scheduling and fairness guarantees that user code would be, and they can tend to slow down older machines significantly1.
Just a quick heads-up: Easy Window Switcher 1.2.2 has just been released and it brings correct hotkey support for the following keyboard layouts:
- German Swiss (QWERTZ)
- International Spanish
NeoSmart.Collections release announcement, we had need of an updated logo for Microsoft’s .NET, and were unable to find something corresponding to .NET Standard.
For those of us that were around when C# was first introduced, this is probably the logo that most represents the .NET Framework:1
NeoSmart Technologies’ Easy Window Switcher, a nifty utility which brings macOS-like switching between windows of the same application with Alt–`, has been updated to version 1.2.0; the biggest feature in this release is support for Windows 10’s virtual desktops.
Rust, both by design and by convention, has a fairly strongly defined model for strict error handling, designed to force developers to deal with errors up front rather than assume they don’t exist. If you stick to a few conventions and principles for best practice, error handling becomes fairly straight-forward (although what you ultimately do with the errors is a different question) if you are living in an all-rust world. The problems start when you step foot outside of the comfortable world of crates and
Results, such as when dealing with FFI to interface with C libraries or using rust in an embedded context.
The typical approach for dealing with errors in rust in 2018 is to have any function that can encounter a scenario wherein it is unable to return a valid value declare a return type of
Result<T, E> where
T is the expected result type in normal cases and
E is a type covering possible errors that can arise during execution. When calling from one such function into other functions with non-guaranteed success, the typical control flow in the event of an error is almost always “early out”:
One of the unique characteristics of Rust (both the language and the community that has evolved around it) is a strong acknowledgement of multithreading, synchronization, and concurrency, as witnessed in the design of the core language (which acknowledges OS concepts of threads with
send) and the presence of various structures in the standard library aimed at simplifying development of correct, multithreaded code.
rsevents is a new crate that should be immediately familiar to anyone that has done multithreaded programming under Windows: it exposes a synchronization primitive, namely, an
event for use where
Mutex – intended to exclusively marshall access to a variable or region of code – either does not convey the correct semantics or is not the right tool for the job. For those that didn’t come fleeing to rust from a Win32 background, in Windows an
event is the lowest-level kernel synchronization primitive, which can be thought of as a “waitable
bool” – it is either
reset (on or off, true or false) and if it isn’t set, you can wait on it until it becomes set.