How to host your own NuGet Server and Package Feed

Local NuGet FeedHosting your own NuGet Server, particularly when you’re a company or even a small workgroup is a super useful thing. It’s a great way to ensure that the build artifacts of each team are NuGet Packages and that other teams are consuming those packages, rather than loose DLLs.

A lot of folks (myself included a minute ago) don’t realize that Visual Studio Team Services also offers private NuGet Feeds for your team so that’s pretty sweet. But I wanted to try out was setting up my own quick NuGet Server. I could put it on a web server in my closet or up in Azure.

From the NuGet site:

There are several third-party NuGet Servers available that make remote private feeds easy to configure and set-up, including Visual Studio Team Services, MyGet, Inedo’s ProGet, JFrog’s Artifactory, NuGet Server, and Sonatype’s Nexus. See An Overview of the NuGet Ecosystem to learn more about these options.

File Shares or Directories as NuGet Server

Starting with NuGet 3.3 you can just use a local folder and it can host a hierarchical NuGet feed. So I head out to the command line, and first make sure NuGet is up to date.

C:UsersscottDesktop>nuget update -self
Checking for updates from https://www.nuget.org/api/v2/.
Currently running NuGet.exe 3.3.0.
NuGet.exe is up to date.

Then I’ll make a folder for my “local server” and then go there and run “nuget init source dest” where “source” is a folder I have full of *.nupkg” files.

This command adds all the packages from a flat folder of nupkgs to the destination package source in a hierarchical layout as described below. The following layout has significant performance benefits, when performing a restore or an update against your package source, compared to a folder of nupkg files.

There’s two ways to run a “remote feed” handled by a Web Server, rather than a “local feed” that’s just a file folder or file share. You can use NuGet.Server *or* run your own internal copy of the NuGet Gallery. The gallery is nice for large multi-user setups or enterprises. For small teams or just yourself and your CI (continuous integration) systems, use NuGet.Server.

Making a simple Web-based NuGet.Server

From Visual Studio, make an empty ASP.NET Web Application using the ASP.NET 4.x Empty template.

New Empty ASP.NET Project

Then, go to References | Manage NuGet Packages and find NuGet.Server and install it. You’ll get all the the dependencies you need and your Empty Project will fill up! If you see a warning about overwriting web.config, you DO want the remote web.config so overwrite your local one.

Nuget install NuGet.Server

Next, go into your Web.config and note the packagesPath that you can set. I used C:LocalNuGet. Run the app and you’ll have a NuGet Server!

You are running NuGet.Server v2.10.0

Since my NuGet.Server is pulling from C:LocalNuGet, as mentioned before I can take a folder filled with NuPkg files (flat) and import them with:

nuget init c:source c:localnuget

I can also set an API key in the web.config (or have none if I want to live dangerously) and then have my automated build push NuGet packages into my server like this:

nuget push {package file} -s http://localhost:51217/nuget {apikey}

Again, as a reminder, while you can totally do this and it’s great for some enterprises, there are lots of hosted NuGet servers out there. MyGet runs on Azure, for example, and VSO/TFS also supports creating and hosting NuGet feeds.

The main point is that if you’ve got an automated build system then you really should be creating NuGet packages and publishing them to a feed. If you’re consuming another group’s assemblies, you should be consuming versioned packages from their feeds. Each org makes packages and they flow through the org via a NuGet server.

How do YOU handle NuGet in YOUR organization? Do you have a NuGet server, and if so, which one?


Sponsor: Big thanks to RedGate and my friends on ANTS for sponsoring the feed this week!

How can you find & fix your slowest .NET code? Boost the performance of your .NET application with the ANTS Performance Profiler. Find your bottleneck fast with performance data for code & queries. Try it free


© 2016 Scott Hanselman. All rights reserved.
     

Local NuGet FeedHosting your own NuGet Server, particularly when you're a company or even a small workgroup is a super useful thing. It's a great way to ensure that the build artifacts of each team are NuGet Packages and that other teams are consuming those packages, rather than loose DLLs.

A lot of folks (myself included a minute ago) don't realize that Visual Studio Team Services also offers private NuGet Feeds for your team so that's pretty sweet. But I wanted to try out was setting up my own quick NuGet Server. I could put it on a web server in my closet or up in Azure.

From the NuGet site:

There are several third-party NuGet Servers available that make remote private feeds easy to configure and set-up, including Visual Studio Team Services, MyGet, Inedo's ProGet, JFrog's Artifactory, NuGet Server, and Sonatype's Nexus. See An Overview of the NuGet Ecosystem to learn more about these options.

File Shares or Directories as NuGet Server

Starting with NuGet 3.3 you can just use a local folder and it can host a hierarchical NuGet feed. So I head out to the command line, and first make sure NuGet is up to date.

C:UsersscottDesktop>nuget update -self

Checking for updates from https://www.nuget.org/api/v2/.
Currently running NuGet.exe 3.3.0.
NuGet.exe is up to date.

Then I'll make a folder for my "local server" and then go there and run "nuget init source dest" where "source" is a folder I have full of *.nupkg" files.

This command adds all the packages from a flat folder of nupkgs to the destination package source in a hierarchical layout as described below. The following layout has significant performance benefits, when performing a restore or an update against your package source, compared to a folder of nupkg files.

There's two ways to run a "remote feed" handled by a Web Server, rather than a "local feed" that's just a file folder or file share. You can use NuGet.Server *or* run your own internal copy of the NuGet Gallery. The gallery is nice for large multi-user setups or enterprises. For small teams or just yourself and your CI (continuous integration) systems, use NuGet.Server.

Making a simple Web-based NuGet.Server

From Visual Studio, make an empty ASP.NET Web Application using the ASP.NET 4.x Empty template.

New Empty ASP.NET Project

Then, go to References | Manage NuGet Packages and find NuGet.Server and install it. You'll get all the the dependencies you need and your Empty Project will fill up! If you see a warning about overwriting web.config, you DO want the remote web.config so overwrite your local one.

Nuget install NuGet.Server

Next, go into your Web.config and note the packagesPath that you can set. I used C:LocalNuGet. Run the app and you'll have a NuGet Server!

You are running NuGet.Server v2.10.0

Since my NuGet.Server is pulling from C:LocalNuGet, as mentioned before I can take a folder filled with NuPkg files (flat) and import them with:

nuget init c:source c:localnuget

I can also set an API key in the web.config (or have none if I want to live dangerously) and then have my automated build push NuGet packages into my server like this:

nuget push {package file} -s http://localhost:51217/nuget {apikey}

Again, as a reminder, while you can totally do this and it's great for some enterprises, there are lots of hosted NuGet servers out there. MyGet runs on Azure, for example, and VSO/TFS also supports creating and hosting NuGet feeds.

The main point is that if you've got an automated build system then you really should be creating NuGet packages and publishing them to a feed. If you're consuming another group's assemblies, you should be consuming versioned packages from their feeds. Each org makes packages and they flow through the org via a NuGet server.

How do YOU handle NuGet in YOUR organization? Do you have a NuGet server, and if so, which one?


Sponsor: Big thanks to RedGate and my friends on ANTS for sponsoring the feed this week!

How can you find & fix your slowest .NET code? Boost the performance of your .NET application with the ANTS Performance Profiler. Find your bottleneck fast with performance data for code & queries. Try it free



© 2016 Scott Hanselman. All rights reserved.
     

NuGet Package of the Week: A different take on ASP.NET MVC Forms with ChameleonForms

One of the nice things about any modular system (like ASP.NET) is the ability to swap out the parts you don’t like. As the authors of ChameleonForms state, HTML forms is a pain. It’s repetitive, it’s repetitive, and it’s boring. While ASP.NET MVC’s Form Helpers help a lot, they felt that helper methods like Html.EditorForModel didn’t go far enough or give you enough flexibility. ChameleonForms adds its own templating model and attempts to be as DRY as possible. It also takes a number of issues head on like better handling for drop-down lists and lists of radio buttons, and it even supports Twitter Bootstrap 3 to you can bang out HTML forms ASAP.

ChameleonForms also is a nice example of a tidy and well-run small open source project. They’ve got a public Trello backlog board, excellent documentation, a continuous integration build, a good example project, and of course, they’re on NuGet. Check out the other projects that the folks in the “MRCollective” work on as well, as they’ve got their own GitHub organization.

NuGet Install ChameleonForms

Often ChameleonForms tries to use C# for the whole form, rather than switching back and forth from Div to Html Helper. For example:

@using (var f = Html.BeginChameleonForm()) {
using (var s = f.BeginSection("Signup for an account")) {
@s.FieldFor(m => m.FirstName)
@s.FieldFor(m => m.LastName)
@s.FieldFor(m => m.Mobile).Placeholder("04XX XXX XXX")
@s.FieldFor(m => m.LicenseAgreement).InlineLabel("I agree to the terms and conditions")
}
using (var n = f.BeginNavigation()) {
@n.Submit("Create")
}
}

This is the whole form using usings for scoping, and it’s nice and clean.  How about a comparison example? Here’s standard ASP.NET MVC:

@using (Html.BeginForm())
{
<fieldset>
<legend>A form</legend>
<dl>
<dt>@Html.LabelFor(m => m.RequiredString, "Some string")</dt>
<dd>@Html.TextBoxFor(m => m.RequiredString) @Html.ValidationMessageFor(m => m.RequiredString)</dd>
<dt>@Html.LabelFor(m => m.SomeEnum)</dt>
<dd>@Html.DropDownListFor(m => m.SomeEnum, Enum.GetNames(typeof(SomeEnum)).Select(x => new SelectListItem {Text = ((SomeEnum)Enum.Parse(typeof(SomeEnum), x)).Humanize(), Value = x})) @Html.ValidationMessageFor(m => m.SomeEnum)</dd>
<dt>@Html.LabelFor(m => m.SomeCheckbox)</dt>
<dd>@Html.CheckBoxFor(m => m.SomeCheckbox) @Html.LabelFor(m => m.SomeCheckbox, "Are you sure?") @Html.ValidationMessageFor(m => m.SomeCheckbox)</dd>
</dl>
</fieldset>
<div class="form_navigation">
<input type="submit" value="Submit" />
</div>
}

And here is the same form with ChameleonForms.

@using (var f = Html.BeginChameleonForm()) {
using (var s = f.BeginSection("A form")) {
@s.FieldFor(m => m.RequiredString).Label("Some string")
@s.FieldFor(m => m.SomeEnum)
@s.FieldFor(m => m.SomeCheckbox).InlineLabel("Are you sure?")
}
using (var n = f.BeginNavigation()) {
@n.Submit("Submit")
}
}

But these are basic. How about something more complex? This one has a bunch of variety, a number overloads and customizations, as well as a FileUpload (note that the form is a Multipart form):

@using (var f = Html.BeginChameleonForm(method: FormMethod.Post, enctype: EncType.Multipart))
{
<p>@f.LabelFor(m => m.SomeCheckbox).Label("Are you ready for: ") @f.FieldElementFor(m => m.SomeCheckbox) @f.ValidationMessageFor(m => m.SomeCheckbox)</p>
<p>@f.FieldElementFor(m => m.RequiredStringField).TabIndex(4)</p>
using (var s = f.BeginSection("My Section!", InstructionalText(), [email protected] = "aClass"}.ToHtmlAttributes()))
{
using (var ff = s.BeginFieldFor(m => m.RequiredStringField, Field.Configure().Attr("data-some-attr", "value").TabIndex(3)))
{
@ff.FieldFor(m => m.NestedField).Attr("data-attr1", "value").TabIndex(2)
@ff.FieldFor(m => m.SomeEnum).Attr("data-attr1", "value")
@ff.FieldFor(m => m.SomeEnum).Exclude(SomeEnum.SomeOtherValue)
}
@s.FieldFor(m => m.SomeCheckbox).AsDropDown()
using (var ss = s.BeginSection("Nested section"))
{
@ss.FieldFor(m => m.FileUpload).Attr("data-attr1", "value")
}
@s.FieldFor(m => m.RequiredStringField).OverrideFieldHtml(new MvcHtmlString("Custom html <b>she-yeah</b>!"))
@s.FieldFor(m => m.TextAreaField).Cols(60).Rows(5).Label("Some Label").AutoFocus().TabIndex(1)
@s.FieldFor(m => m.SomeCheckbox).InlineLabel("Some label").WithHint("Format: XXX")
@s.FieldFor(m => m.SomeCheckbox).AsRadioList().WithTrueAs("True").WithFalseAs("False")
@s.FieldFor(m => m.ListId)
@s.FieldFor(m => m.ListId).AsRadioList()
@s.FieldFor(m => m.SomeEnums)
@s.FieldFor(m => m.SomeEnumsList).AsRadioList()
@s.FieldFor(m => m.Decimal)
@s.FieldFor(m => m.Int).AsInputGroup().Append(".00").Prepend("$")
@s.FieldFor(m => m.DecimalWithFormatStringAttribute)
@s.FieldFor(m => m.NullableInt)
@s.FieldFor(m => m.Child.ChildField)
@s.FieldFor(m => m.Child.SomeEnum).AsRadioList()
@s.FieldFor(m => m.RequiredStringField).Disabled()
@s.FieldFor(m => m.RequiredStringField).Readonly()
}
using (var n = f.BeginNavigation())
{
@n.Submit("Submit")
@n.Reset("Reset")
}
}

ChameleonForms also has a special NuGet package if you’re using TwitterBootstrap that changes how forms with the BeginChameleonForm method render.

ChameleonForms also has some convenient extra abilities, like being able to automatically infer/create a [DisplayName] so you don’t have to. If you’re doing Forms in English and your preferred Display Name will end up just being your variable name this can be a useful time saver (although you may have opinions about its purity.)

So instead of the tedium of:

[DisplayName("Email address")]
public string EmailAddress { get; set; }

[DisplayName("First name")]
public string FirstName { get; set; }

You can just say this once, picking just one…this is an example where they use HumanizedLabels.

HumanizedLabels.Register(LetterCasing.AllCaps) => "EMAIL ADDRESS"
HumanizedLabels.Register(LetterCasing.LowerCase) => "email address"
HumanizedLabels.Register(LetterCasing.Sentence) => "Email address"
HumanizedLabels.Register(LetterCasing.Title) => "Email Address"

If you’ve got a lot of Forms to create and they’re just no fun anymore, you should definitely give ChameleonForms a try. If you’re a Twitter Bootstrap shop, doubly so, as that’s where ChameleonForms really shines.

I’ll do a few other posts exploring different ways to for Forms in ASP.NET MVC in the coming weeks. Be sure to explore the NuGet Package of the Week Archives as well!


PLUG: Did you know I have a YouTube channel? Subscribe over here. I’ve got tutorials on how to effectively use Windows 8 and 8.1, Build to Build walkthroughs of the latest versions of Windows 10, and I just started a new series I’m sure you’ll want to share with your family called “How to REALLY use Microsoft Office.” Help me out and spread the word!


© 2015 Scott Hanselman. All rights reserved.
     

One of the nice things about any modular system (like ASP.NET) is the ability to swap out the parts you don't like. As the authors of ChameleonForms state, HTML forms is a pain. It's repetitive, it's repetitive, and it's boring. While ASP.NET MVC's Form Helpers help a lot, they felt that helper methods like Html.EditorForModel didn't go far enough or give you enough flexibility. ChameleonForms adds its own templating model and attempts to be as DRY as possible. It also takes a number of issues head on like better handling for drop-down lists and lists of radio buttons, and it even supports Twitter Bootstrap 3 to you can bang out HTML forms ASAP.

ChameleonForms also is a nice example of a tidy and well-run small open source project. They've got a public Trello backlog board, excellent documentation, a continuous integration build, a good example project, and of course, they're on NuGet. Check out the other projects that the folks in the "MRCollective" work on as well, as they've got their own GitHub organization.

NuGet Install ChameleonForms

Often ChameleonForms tries to use C# for the whole form, rather than switching back and forth from Div to Html Helper. For example:

@using (var f = Html.BeginChameleonForm()) {

using (var s = f.BeginSection("Signup for an account")) {
@s.FieldFor(m => m.FirstName)
@s.FieldFor(m => m.LastName)
@s.FieldFor(m => m.Mobile).Placeholder("04XX XXX XXX")
@s.FieldFor(m => m.LicenseAgreement).InlineLabel("I agree to the terms and conditions")
}
using (var n = f.BeginNavigation()) {
@n.Submit("Create")
}
}

This is the whole form using usings for scoping, and it's nice and clean.  How about a comparison example? Here's standard ASP.NET MVC:

@using (Html.BeginForm())

{
<fieldset>
<legend>A form</legend>
<dl>
<dt>@Html.LabelFor(m => m.RequiredString, "Some string")</dt>
<dd>@Html.TextBoxFor(m => m.RequiredString) @Html.ValidationMessageFor(m => m.RequiredString)</dd>
<dt>@Html.LabelFor(m => m.SomeEnum)</dt>
<dd>@Html.DropDownListFor(m => m.SomeEnum, Enum.GetNames(typeof(SomeEnum)).Select(x => new SelectListItem {Text = ((SomeEnum)Enum.Parse(typeof(SomeEnum), x)).Humanize(), Value = x})) @Html.ValidationMessageFor(m => m.SomeEnum)</dd>
<dt>@Html.LabelFor(m => m.SomeCheckbox)</dt>
<dd>@Html.CheckBoxFor(m => m.SomeCheckbox) @Html.LabelFor(m => m.SomeCheckbox, "Are you sure?") @Html.ValidationMessageFor(m => m.SomeCheckbox)</dd>
</dl>
</fieldset>
<div class="form_navigation">
<input type="submit" value="Submit" />
</div>
}

And here is the same form with ChameleonForms.

@using (var f = Html.BeginChameleonForm()) {

using (var s = f.BeginSection("A form")) {
@s.FieldFor(m => m.RequiredString).Label("Some string")
@s.FieldFor(m => m.SomeEnum)
@s.FieldFor(m => m.SomeCheckbox).InlineLabel("Are you sure?")
}
using (var n = f.BeginNavigation()) {
@n.Submit("Submit")
}
}

But these are basic. How about something more complex? This one has a bunch of variety, a number overloads and customizations, as well as a FileUpload (note that the form is a Multipart form):

@using (var f = Html.BeginChameleonForm(method: FormMethod.Post, enctype: EncType.Multipart))

{
<p>@f.LabelFor(m => m.SomeCheckbox).Label("Are you ready for: ") @f.FieldElementFor(m => m.SomeCheckbox) @f.ValidationMessageFor(m => m.SomeCheckbox)</p>
<p>@f.FieldElementFor(m => m.RequiredStringField).TabIndex(4)</p>
using (var s = f.BeginSection("My Section!", InstructionalText(), [email protected] = "aClass"}.ToHtmlAttributes()))
{
using (var ff = s.BeginFieldFor(m => m.RequiredStringField, Field.Configure().Attr("data-some-attr", "value").TabIndex(3)))
{
@ff.FieldFor(m => m.NestedField).Attr("data-attr1", "value").TabIndex(2)
@ff.FieldFor(m => m.SomeEnum).Attr("data-attr1", "value")
@ff.FieldFor(m => m.SomeEnum).Exclude(SomeEnum.SomeOtherValue)
}
@s.FieldFor(m => m.SomeCheckbox).AsDropDown()
using (var ss = s.BeginSection("Nested section"))
{
@ss.FieldFor(m => m.FileUpload).Attr("data-attr1", "value")
}
@s.FieldFor(m => m.RequiredStringField).OverrideFieldHtml(new MvcHtmlString("Custom html <b>she-yeah</b>!"))
@s.FieldFor(m => m.TextAreaField).Cols(60).Rows(5).Label("Some Label").AutoFocus().TabIndex(1)
@s.FieldFor(m => m.SomeCheckbox).InlineLabel("Some label").WithHint("Format: XXX")
@s.FieldFor(m => m.SomeCheckbox).AsRadioList().WithTrueAs("True").WithFalseAs("False")
@s.FieldFor(m => m.ListId)
@s.FieldFor(m => m.ListId).AsRadioList()
@s.FieldFor(m => m.SomeEnums)
@s.FieldFor(m => m.SomeEnumsList).AsRadioList()
@s.FieldFor(m => m.Decimal)
@s.FieldFor(m => m.Int).AsInputGroup().Append(".00").Prepend("$")
@s.FieldFor(m => m.DecimalWithFormatStringAttribute)
@s.FieldFor(m => m.NullableInt)
@s.FieldFor(m => m.Child.ChildField)
@s.FieldFor(m => m.Child.SomeEnum).AsRadioList()
@s.FieldFor(m => m.RequiredStringField).Disabled()
@s.FieldFor(m => m.RequiredStringField).Readonly()
}
using (var n = f.BeginNavigation())
{
@n.Submit("Submit")
@n.Reset("Reset")
}
}

ChameleonForms also has a special NuGet package if you're using TwitterBootstrap that changes how forms with the BeginChameleonForm method render.

ChameleonForms also has some convenient extra abilities, like being able to automatically infer/create a [DisplayName] so you don't have to. If you're doing Forms in English and your preferred Display Name will end up just being your variable name this can be a useful time saver (although you may have opinions about its purity.)

So instead of the tedium of:

[DisplayName("Email address")]

public string EmailAddress { get; set; }

[DisplayName("First name")]
public string FirstName { get; set; }

You can just say this once, picking just one...this is an example where they use HumanizedLabels.

HumanizedLabels.Register(LetterCasing.AllCaps) => "EMAIL ADDRESS"

HumanizedLabels.Register(LetterCasing.LowerCase) => "email address"
HumanizedLabels.Register(LetterCasing.Sentence) => "Email address"
HumanizedLabels.Register(LetterCasing.Title) => "Email Address"

If you've got a lot of Forms to create and they're just no fun anymore, you should definitely give ChameleonForms a try. If you're a Twitter Bootstrap shop, doubly so, as that's where ChameleonForms really shines.

I'll do a few other posts exploring different ways to for Forms in ASP.NET MVC in the coming weeks. Be sure to explore the NuGet Package of the Week Archives as well!


PLUG: Did you know I have a YouTube channel? Subscribe over here. I've got tutorials on how to effectively use Windows 8 and 8.1, Build to Build walkthroughs of the latest versions of Windows 10, and I just started a new series I'm sure you'll want to share with your family called "How to REALLY use Microsoft Office." Help me out and spread the word!



© 2015 Scott Hanselman. All rights reserved.
     

NuGet Package of the Week: Polly wanna fluently express transient exception handling policies in .NET?

LOL at my own post title. Pardon me.

Install-Package Polly

Michael Wolfenden has a very clever open source library called Polly. Polly is a .NET 3.5 / 4.0 / 4.5 / PCL library that allows developers to express transient exception handling policies such as Retry, Retry Forever, Wait and Retry or Circuit Breaker in a fluent manner.

Handling exceptions can be a hassle sometimes. Not just setting the try/catches up, but deciding on the policy for the catch can make the exception management code more complex than the method itself!

Polly has a fluent interface to make expressing rules like that much easier. For example:

// Single exception type
Policy
.Handle<DivideByZeroException>()

// Single exception type with condition
Policy
.Handle<SqlException>(ex => ex.Number == 1205)

// Multiple exception types
Policy
.Handle<DivideByZeroException>()
.Or<ArgumentException>()

// Multiple exception types with condition
Policy
.Handle<SqlException>(ex => ex.Number == 1205)
.Or<ArgumentException>(ex => x.ParamName == "example")

Then you can add Retry() logic, which is fantastic.

// Retry multiple times, calling an action on each retry 
// with the current exception and retry count
Policy
.Handle<DivideByZeroException>()
.Retry(3, (exception, retryCount) =>
{
// do something
});

Even do retries with multiplicative back off!

// Retry a specified number of times, using a function to 
// calculate the duration to wait between retries based on
// the current retry attempt, calling an action on each retry
// with the current exception, duration and context provided
// to Execute()
Policy
.Handle<DivideByZeroException>()
.WaitAndRetry(
5,
retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
(exception, timeSpan, context) => {
// do something
}
);

Once you have set up a policy, you execute on it.

Policy
.Handle<SqlException>(ex => ex.Number == 1205)
.Or<ArgumentException>(ex => ex.ParamName == "example")
.Retry()
.Execute(() => DoSomething());

Polly also supports the more sophisticated “Circuit Breaker” policy. For more information on the Circuit Breaker pattern see:

Circuit breaker tries and then “Trips the circuit breaker” so you’ll get a BrokenCircuitException for some amount of time. This is a great way to give an external system to chill for a minute if it’s down. It also externalizes the concept so that you could theoretically handle a down database the same as you handle a down external web API.

// Break the circuit after the specified number of exceptions
// and keep circuit broken for the specified duration
Policy
.Handle<DivideByZeroException>()
.CircuitBreaker(2, TimeSpan.FromMinutes(1))

You can explore the code, of course, up on Github in the Polly repository. Go give the Polly project a star. They’ve recently added async support for .NET 4.5 as well!


Sponsor: Welcome this week’s feed sponsor, Stackify! – The only developer-friendly solution that fully integrates .NET error & log management with application monitoring. Easily isolate issues and focus your efforts – Support less, Code more. Free trial


© 2014 Scott Hanselman. All rights reserved.
     

LOL at my own post title. Pardon me.

Install-Package Polly

Michael Wolfenden has a very clever open source library called Polly. Polly is a .NET 3.5 / 4.0 / 4.5 / PCL library that allows developers to express transient exception handling policies such as Retry, Retry Forever, Wait and Retry or Circuit Breaker in a fluent manner.

Handling exceptions can be a hassle sometimes. Not just setting the try/catches up, but deciding on the policy for the catch can make the exception management code more complex than the method itself!

Polly has a fluent interface to make expressing rules like that much easier. For example:

// Single exception type

Policy
.Handle<DivideByZeroException>()

// Single exception type with condition
Policy
.Handle<SqlException>(ex => ex.Number == 1205)

// Multiple exception types
Policy
.Handle<DivideByZeroException>()
.Or<ArgumentException>()

// Multiple exception types with condition
Policy
.Handle<SqlException>(ex => ex.Number == 1205)
.Or<ArgumentException>(ex => x.ParamName == "example")

Then you can add Retry() logic, which is fantastic.

// Retry multiple times, calling an action on each retry 

// with the current exception and retry count
Policy
.Handle<DivideByZeroException>()
.Retry(3, (exception, retryCount) =>
{
// do something
});

Even do retries with multiplicative back off!

// Retry a specified number of times, using a function to 

// calculate the duration to wait between retries based on
// the current retry attempt, calling an action on each retry
// with the current exception, duration and context provided
// to Execute()
Policy
.Handle<DivideByZeroException>()
.WaitAndRetry(
5,
retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
(exception, timeSpan, context) => {
// do something
}
);

Once you have set up a policy, you execute on it.

Policy

.Handle<SqlException>(ex => ex.Number == 1205)
.Or<ArgumentException>(ex => ex.ParamName == "example")
.Retry()
.Execute(() => DoSomething());

Polly also supports the more sophisticated "Circuit Breaker" policy. For more information on the Circuit Breaker pattern see:

Circuit breaker tries and then "Trips the circuit breaker" so you'll get a BrokenCircuitException for some amount of time. This is a great way to give an external system to chill for a minute if it's down. It also externalizes the concept so that you could theoretically handle a down database the same as you handle a down external web API.

// Break the circuit after the specified number of exceptions

// and keep circuit broken for the specified duration
Policy
.Handle<DivideByZeroException>()
.CircuitBreaker(2, TimeSpan.FromMinutes(1))

You can explore the code, of course, up on Github in the Polly repository. Go give the Polly project a star. They've recently added async support for .NET 4.5 as well!


Sponsor: Welcome this week's feed sponsor, Stackify! - The only developer-friendly solution that fully integrates .NET error & log management with application monitoring. Easily isolate issues and focus your efforts – Support less, Code more. Free trial



© 2014 Scott Hanselman. All rights reserved.