NuGet Package of the Week: Microphone registers and discovers Web APIs and REST services with Consul

I’m sitting on a plane on the way back from a lovely time in Europe. I attended and spoke at some great conferences and met some cool people – some of which you’ll hear on the podcast soon. Anyway, one of the things that I heard mentioned by attendees more than once was the issue of (micro) service discovery for RESTful APIs. Now if you lived through the WS*.* years you’ll perhaps feel a lot of this is familiar or repeated territory, but the new stuff definitely fits together more effortlessly than in the past.

Consul is a system that does service discovery, configuration management, and health checking for your services. You can write Web APIs in lots of things, Rails, Python, and ASP.NET with WebAPI or NancyFX.

Microphone is a library by Roger Johansson that plugs into both WebAPI and Nancy and very simply and easily registers your services with Consul. It’s recently been expanded to support CoreOs-ETCD as well, so it’s really a general purpose framework.

I made a little .NET 4.6 console app that self hosts a WebAPI like this.

namespace ConsulSelfHostedWebAPIService
{
class Program
{
static void Main(string[] args)
{
Cluster.Bootstrap(new WebApiProvider(), new ConsulProvider(), "HanselWebApiService", "v1");
Console.ReadLine();
}
}

public class DefaultController : ApiController
{
public string Get()
{
return "Hey it's my personal WebApi Service";
}
}
}

Now my Web API is registered with Consul, and now Consul itself is a RESTful Web API where I can hit http://localhost:8500/v1/agent/services and get a list of registered services. It’s the Discovery Service.

Consul reporting my WebAPI

Then later in a client or perhaps another Web API, I can ask for it by name and I’ll get back the address and port that it’s on, then call it.

var instance = await Cluster.FindServiceInstanceAsync("Heycool");

return String.Format("Look there's a service at {0}:{1}", instance.Address, instance.Port);

Here’s an active debug session showing the address and port in the instance:

Using Microphone.WebAPI and Consul for Service Discovery

It will be interesting to see what will happen with Consul and systems like it if the Azure Service Fabric gains traction. Service Fabric offers a lot more, but I wonder if there is a use case for both, with Service Fabric managing lifecycles and Consul doing discovery.

This is all early days, but it’s interesting. What do you think about these new discovery services for Web APIs?


Sponsor: Big thanks to Infragistics for sponsoring the feed this week. Quickly & effortlessly create advanced, stylish, & high performing UIs for ASP.NET MVC with Ignite UI. Leverage the full power of Infragistics’ JavaScript-based jQuery/HTML5 control suite today.


© 2015 Scott Hanselman. All rights reserved.
     

I'm sitting on a plane on the way back from a lovely time in Europe. I attended and spoke at some great conferences and met some cool people - some of which you'll hear on the podcast soon. Anyway, one of the things that I heard mentioned by attendees more than once was the issue of (micro) service discovery for RESTful APIs. Now if you lived through the WS*.* years you'll perhaps feel a lot of this is familiar or repeated territory, but the new stuff definitely fits together more effortlessly than in the past.

Consul is a system that does service discovery, configuration management, and health checking for your services. You can write Web APIs in lots of things, Rails, Python, and ASP.NET with WebAPI or NancyFX.

Microphone is a library by Roger Johansson that plugs into both WebAPI and Nancy and very simply and easily registers your services with Consul. It's recently been expanded to support CoreOs-ETCD as well, so it's really a general purpose framework.

I made a little .NET 4.6 console app that self hosts a WebAPI like this.

namespace ConsulSelfHostedWebAPIService

{
class Program
{
static void Main(string[] args)
{
Cluster.Bootstrap(new WebApiProvider(), new ConsulProvider(), "HanselWebApiService", "v1");
Console.ReadLine();
}
}

public class DefaultController : ApiController
{
public string Get()
{
return "Hey it's my personal WebApi Service";
}
}
}

Now my Web API is registered with Consul, and now Consul itself is a RESTful Web API where I can hit http://localhost:8500/v1/agent/services and get a list of registered services. It's the Discovery Service.

Consul reporting my WebAPI

Then later in a client or perhaps another Web API, I can ask for it by name and I'll get back the address and port that it's on, then call it.

var instance = await Cluster.FindServiceInstanceAsync("Heycool");


return String.Format("Look there's a service at {0}:{1}", instance.Address, instance.Port);

Here's an active debug session showing the address and port in the instance:

Using Microphone.WebAPI and Consul for Service Discovery

It will be interesting to see what will happen with Consul and systems like it if the Azure Service Fabric gains traction. Service Fabric offers a lot more, but I wonder if there is a use case for both, with Service Fabric managing lifecycles and Consul doing discovery.

This is all early days, but it's interesting. What do you think about these new discovery services for Web APIs?


Sponsor: Big thanks to Infragistics for sponsoring the feed this week. Quickly & effortlessly create advanced, stylish, & high performing UIs for ASP.NET MVC with Ignite UI. Leverage the full power of Infragistics’ JavaScript-based jQuery/HTML5 control suite today.



© 2015 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.