System.BadImageFormatException: Index not found. (Exception from HRESULT: 0x80131124)

If you get a

An unhandled exception has occurred while executing the request. 
System.BadImageFormatException: Index not found. (Exception from HRESULT: 0x80131124)

error when publishing your website through Visual Studio, a couple of things to check are:

  • When publishing the application to Azure make sure that the “Remove Additional Files at destination” option is checked.

    image

  • Made sure that all the projects(only one) were being build as “Any CPU” in both “debug” and “release” configuration.
    image
Continue Reading

Send emails using SendGrid Email provider and ASP.Net Core

Sending emails using SendGrid email provider and ASP.Net Core is very straightforward.
Firstly install SendGrid package through Package Manager Console using the following command

install-package SendGrid

Now create a account in Sendgrid.com and add an API key to use the SendGrid provider service.  Add this key to your AppSettings.Json or AppSettings.Development.Json under a new SendGridEmailSettings=>SendGridKey node.

image

AppSettings.Json:

{
"SendGridEmailSettings": {
"SendGridKey": <SendGrid Private API Key>
}
}

StartUp.cs:

public void ConfigureServices(IServiceCollection services)
{
……………………..
services.AddTransient<IEmailSender, EmailSender>();
services.Configure<AuthMessageSenderOptions>(options =>
Configuration.GetSection("SendGridEmailSettings").Bind(options));
}

EmailSender .cs

using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Options;
using SendGrid;
using SendGrid.Helpers.Mail;
using System.Threading.Tasks;

public class AuthMessageSenderOptions
{
public string SendGridUser { get; set; }
public string SendGridKey { get; set; }
}
public class EmailSender : IEmailSender
{
public EmailSender(IOptions optionsAccessor)
{
Options = optionsAccessor.Value;
}
public AuthMessageSenderOptions Options { get; } //set only via Secret Manager
public Task SendEmailAsync(string email, string subject, string message)
{
return Execute(Options.SendGridKey, subject, message, email);
}
public Task Execute(string apiKey, string subject, string message, string email)
{
var sendGridClient = new SendGridClient(apiKey);
var sendGridMessage = new SendGridMessage()
{
From = new EmailAddress("ajitgoel@gmail.com", "Simpler Products-Social Media Scrubber"),
Subject = subject,
PlainTextContent = message,
HtmlContent = message
};
sendGridMessage.AddTo(new EmailAddress(email));
// Disable click tracking.See //sendgrid.com/docs/User_Guide/Settings/tracking.html
sendGridMessage.SetClickTracking(false, false);
return sendGridClient.SendEmailAsync(sendGridMessage);
}
}

If you send an email and you do not receive it in your mailbox check the spam folder. My emails landed in the spam folder when I was testing the application.

Continue Reading

NotSupportedException: No IUserTwoFactorTokenProvider named ‘Default’ is registered.

If you have changed the AddDefaultIdentity in the Startup.cs file to AddIdentity and you receive a

An unhandled exception occurred while processing the request.
NotSupportedException: No IUserTwoFactorTokenProvider<TUser> named ‘Default’ is registered.
Microsoft.AspNetCore.Identity.UserManager<TUser>.GenerateUserTokenAsync(TUser user, string tokenProvider, string purpose)

error when registering a user, there is a easy fix. You need to a add a AddDefaultTokenProviders() when adding identity() to services.

public void ConfigureServices(IServiceCollection services)
  {
  ………………
  services.AddIdentity<User, UserRole>()
   .AddEntityFrameworkStores<ApplicationDbContext>()
   .AddDefaultTokenProviders();
…………………….

Continue Reading

FizzBuzz using C# yield

Yield.
Yield has two great uses,
a. It helps to provide custom iteration without creating temp collections.
b. It helps to do state-full iteration.

[TestClass]
public class FizzBuzzTest
{
    [TestMethod]
    public void Test1()
    {
        var iEnumerableString = new FizzBuzz().GenerateFizzBuzzUpto(100);
        var list = iEnumerableString.ToList();
        Assert.IsTrue(list[0] == "Fizz:3");
        Assert.IsTrue(list[1] == "Buzz:5");
        Assert.IsTrue(list[6] == "FizzBuzz:15");
    }
}
public class FizzBuzz
{
    public IEnumerable<string> GenerateFizzBuzzUpto(int numberUpto)
    {
        for (var counter = 1; counter < numberUpto; counter++)
        {
            if (counter%3 == 0 && counter%5 == 0)
            {
                yield return $"FizzBuzz:{counter}";
            }
            if (counter % 3 == 0)
            {
                yield return $"Fizz:{counter}";
            }
            if (counter % 5 == 0)
            {
                yield return $"Buzz:{counter}";
            }
        }
    }
}
Continue Reading

“Develop something useful in under 100 lines of code” contest-Improved version

My article here was well received. Various people pointing out several flaws in the application. Some of these points that were discussed were:

a. Should the application use decimal instead of double since it is a financial application?
Answer: The application has been changed to use decimals to calculate the monthly payment amount, Interest amount, total interest amount. However based on the article here, “the results when computed in doubles are going to be off by a few billionths of a penny one way or the other”. I therefore believe that I need to find a actual use case where using a decimal produced a result that was more correct than using a decimal.

b. The application will not behave correctly when the “loan Date” is passed with a “DateTime.MaxValue” value.
Answer: This has been fixed and a unit test case added for the same.

c. The application needs to consider business rules related to “loan date” and “Loan Period in years”
Answer: This has been fixed and two unit test cases added for the same.

d. What advantages will the system get if the return type of the Get function is a “IList” instead of a “List”?
Answer: This has been fixed in the application. The advantages that we get is that the AmortizationSchedule.Get and IAmortizationSchedule.Get signature does not need to change when the internals of the AmortizationSchedule.Get method is changed to return a collection that implements a IList (example return a Array instead of a List collection).

e. How will you optimize the creation of a the List class on line 30? Will it make sense to pass the created object from the client application if the creation of the list instance is expensive?
Answer: If the List creation is an expensive operation then we can consider using the Object pooling design pattern in the application.
The Object pool design pattern is a creational design pattern that can improve performance when working with classes that are slow to instantiate. Rather than constructing new objects, reusable objects are retrieved from, and released to, a pool as required.
An example implementation is listed here.

f. Will the application need to take care of multiple processes creating “Amortization Schedule”? If yes then how will you change the application?
Answer: It was decided that the application does not need to change to take care of multiple processes creating the “Amortization Schedule”.

g. Why was the “IAmortizationSchedule” interface created? It is not used anywhere in the application
Answer: This is true, the “IAmortizationSchedule” interface is not used in the application but I always create an interface because it helps later down the road when I need to write unit tests by mock the various parts of the application.

h. Is there a possibility that the “toThePowerOfVariable” variable on line 22 will become 1? What happens on line 23 if the “toThePowerOfVariable” variable becomes 1?
Answer: It was decided that there is no possibility of the “toThePowerOfVariable” variable on line 22 becoming 1. If the “toThePowerOfVariable” variable becomes 1, no “DivideByZeroException or other exception will occur.

Here is the changed application:

public class AmortizationSchedule: IAmortizationSchedule
{
    public IList<AmortizationScheduleRow> Get(double annualPercentageRate, 
        double loanAmount, int loanPeriodInYears, DateTime loanStartDate)
    {
        if (annualPercentageRate <= 0 || 
         loanAmount <= 0 || 
         loanPeriodInYears <= 0 || 
         loanStartDate <= DateTime.MinValue || 
         loanStartDate == DateTime.MaxValue)
        {
            throw new ArgumentException("Invalid arguments");
        }
        //If the code below does not throw an exception then 
        //the "loanStartDate" has been validated against the "loanPeriodInYears"
        DateTime addYears = loanStartDate.AddYears(loanPeriodInYears);
        
        #region Calculate monthly payment rounded to 2 digits
        const int NoOfMonthsInYear = 12;
        var loanPeriodInMonths = loanPeriodInYears * NoOfMonthsInYear;
        var effectiveInterestRateInDouble = annualPercentageRate / (NoOfMonthsInYear * 100);
        var toThePowerOfVariable = Math.Pow(1 + effectiveInterestRateInDouble, -loanPeriodInMonths);
        var monthlyPayment = (decimal) (loanAmount * (effectiveInterestRateInDouble / (1 - toThePowerOfVariable)));
        #endregion

        #region Calculate payment schedule based on monthly payment and loan start date
        //Initialize the collection(for performance) based on the 
        //no of elements that it is supposed to hold
        var amortizationSchedule = 
        new List<AmortizationScheduleRow>(loanPeriodInMonths);
        var currentMonthCounter = loanStartDate.AddMonths(1);
        var currentBalance = (decimal) loanAmount;
        decimal totalInterestAmount = 0;
        for (var counter = 0; counter < loanPeriodInMonths; counter++)
        {
            var interestAmount = (decimal) (effectiveInterestRateInDouble * (double) currentBalance);
            totalInterestAmount = (totalInterestAmount + interestAmount);
            var amortizationScheduleRow = new AmortizationScheduleRow
            {
                Date = currentMonthCounter,
                MonthlyPaymentAmount = monthlyPayment,
                InterestAmount = interestAmount,
                TotalInterestAmount = totalInterestAmount
            };
            amortizationSchedule.Add(amortizationScheduleRow);

            currentBalance = currentBalance - amortizationScheduleRow.GetPrincipalAmount();
            currentMonthCounter = currentMonthCounter.AddMonths(1);
        }
        #endregion
        return amortizationSchedule;
    }
}
public interface IAmortizationSchedule
{
    IList<AmortizationScheduleRow> Get(double annualPercentageRate, double loanAmount, 
        int loanPeriodInYears, DateTime loanStartDate);
}
public class AmortizationScheduleRow
{
    public decimal GetMonthlyPaymentAmount()
    {
        return Math.Round(MonthlyPaymentAmount, 2, MidpointRounding.AwayFromZero);
    }
    public decimal MonthlyPaymentAmount { private get; set; }
    public decimal GetInterestAmount()
    {
        return Math.Round(InterestAmount, 2, MidpointRounding.AwayFromZero);
    }
    public decimal InterestAmount { private get; set; }
    public decimal GetTotalInterestAmount()
    {
        return Math.Round(TotalInterestAmount, 2, MidpointRounding.AwayFromZero);
    }
    public decimal TotalInterestAmount { private get; set; }
    public decimal GetPrincipalAmount()
    {
        var principalAmount = MonthlyPaymentAmount - InterestAmount;
        return Math.Round(principalAmount, 2, MidpointRounding.AwayFromZero);
    }
    public string GetDate()
    {
        return Date.ToString("MMM yyyy");
    }
    public DateTime Date { private get; set; }
}
 [TestClass]
public class AmortizationScheduleTester
{
    const double annualPercentageRate = 3.5;
    const double loanAmount = 300000;
    const int loanPeriodInYears = 15;
    readonly DateTime loanStartDate = new DateTime(2016, 7, 1);
    [TestMethod]
    public void GetAmortizationScheduleExceptionTest()
    {
        const int NoOfMonthsInYear = 12;
        var monthlyPaymentSchedule = new AmortizationSchedule().Get(annualPercentageRate, loanAmount,
            loanPeriodInYears, loanStartDate);
        Assert.IsFalse(monthlyPaymentSchedule == null);
        Assert.IsFalse(monthlyPaymentSchedule.Count > 1);
        var secondMonthPaymentSchedule = monthlyPaymentSchedule[1];
        Assert.AreEqual(monthlyPaymentSchedule.Count, 15 * NoOfMonthsInYear);
        Assert.AreEqual(secondMonthPaymentSchedule.GetMonthlyPaymentAmount(), 
        (decimal) 2144.65);
        Assert.AreEqual(secondMonthPaymentSchedule.GetDate(), "Sep 2016");
        Assert.AreEqual(secondMonthPaymentSchedule.GetInterestAmount(), 
        (decimal) 871.30);
        Assert.AreEqual(secondMonthPaymentSchedule.GetTotalInterestAmount(), 
        (decimal) 1746.30);
        Assert.AreEqual(secondMonthPaymentSchedule.GetPrincipalAmount(), 
        (decimal) 1273.35);
    }
    [ExpectedException(typeof(ArgumentException))]
    [TestMethod]
    public void GetAmortizationScheduleExceptionTest1()
    {
        new AmortizationSchedule().Get(0, loanAmount,
            loanPeriodInYears, loanStartDate);
    }
    [ExpectedException(typeof(ArgumentException))]
    [TestMethod]
    public void GetAmortizationScheduleExceptionTest2()
    {
        new AmortizationSchedule().Get(annualPercentageRate, 0,
            loanPeriodInYears, loanStartDate);
    }
    [ExpectedException(typeof(ArgumentException))]
    [TestMethod]
    public void GetAmortizationScheduleExceptionTest3()
    {
        new AmortizationSchedule().Get(annualPercentageRate, loanAmount, 0, loanStartDate);
    }
    [ExpectedException(typeof(ArgumentException))]
    [TestMethod]
    public void GetAmortizationScheduleExceptionTest4()
    {
        new AmortizationSchedule().Get(annualPercentageRate, loanAmount,
            loanPeriodInYears, DateTime.MinValue);
    }
    [ExpectedException(typeof(ArgumentException))]
    [TestMethod]
    public void GetAmortizationScheduleExceptionTest5()
    {
        new AmortizationSchedule().Get(annualPercentageRate, loanAmount,
            loanPeriodInYears, DateTime.MaxValue);
    }
    [ExpectedException(typeof(ArgumentOutOfRangeException))]
    [TestMethod]
    public void GetAmortizationScheduleExceptionTest6()
    {
        new AmortizationSchedule().Get(annualPercentageRate, loanAmount,
            loanPeriodInYears, DateTime.MaxValue.AddYears(-1));
    }
}

Unit Test Project-Improved

Continue Reading

Concurrent and immutable Collections in C#-Primer

Concurrent(or Threadsafe) collections allow multiple threads to update them simultaneously in a safe way. Concurrent collections are more efficient than implementing a regular collection with a lock.
An immutable collection cannot actually be modified. Instead, to modify an immutable collection, you create a new collection that represents the modified collection.

The .Net framework has several different collection types.
ImmutableList<T> Use this data structure when
a. the collection data does not change very often
b. the collection can be accessed by multiple threads safely.
c. They allow indexing like Lists but they have lower performance than Lists.

ImmutableStack<T> Use this data structure when
a. you need a first-in, first-out data structure
b. the collection data does not change very often
b. the collection can be accessed by multiple threads safely.
c. ImmutableStack have lower performance than Stack data structures.

ImmutableQueue<T> Use this data structure when
a. you need a first-in, last-out data structure
b. the collection data does not change very often
b. the collection can be accessed by multiple threads safely.
c. ImmutableQueue have lower performance than Queue data structures.

ImmutableDictionary<T, TValue> is a key-value collection of items. Use this type when you
a. need a key-value collection of items.
b. the collection data does not change very often
c. can be accessed by multiple threads safely.
d. the items in ImmutableDictionary have an unpredictable order.
Performance of ImmutableDictionary is faster than ImmutableSortedDictionary.

ImmutableSortedDictionary<T, TValue> is a key-value collection of items sorted by key. Use this type when you
a. need a key-value collection of items.
b. the collection data does not change very often
c. can be accessed by multiple threads safely.
d. the items are sorted in the collection.

ImmutableHashSet<T> is just a collection of unique items. Use this type when you
a. do not need to store duplicates
b. the collection data does not change very often
c. can be accessed by multiple threads safely.
d. the items in the ImmutableHashSet have an unpredictable order.
Performance of ImmutableHashSet is faster than ImmutableSortedHashSet.

ImmutableSortedSet<T> is a sorted collection of unique items. Use this type when you
a. do not need to store duplicates
b. the collection data does not change very often
c. can be accessed by multiple threads safely.
d. the items are sorted in the collection.

ConcurrentDictionary<T, TValue> is a key-value collection of items. Use this type when you
a. need a key-value collection of items.
b. can be accessed by multiple threads safely.
Use the ConcurrentDictionary<T, TValue> when you have multiple threads reading and writing to the shared collection. If the updates are more rare then the ImmutableDictionary<T, TValue> is a better choice.

Continue Reading

Encapsulate and vary algorithm from the client that uses it(Strategy Pattern)

Strategy pattern is a software design pattern that enables an algorithm’s behavior to be selected at runtime. It
a. defines a family of algorithms,
b. encapsulates each algorithm, and
c. makes the algorithms interchangeable within that family.

Example:
Strategy Design Pattern

using System.Collections.Generic;

class StrategyDesignPatternClient
{
    static void Main()
    {
        var sortedList = new SortedList();
        sortedList.Add("name 1");
        sortedList.Add("name 2");
        sortedList.Add("name 3");
        //The client passes the "sort strategy" to the SortedList 
        //so the SortedList can use that passed strategy to sort the internal list
        sortedList.SetSortStrategy(new QuickSort());
        sortedList.Sort();
    }
}
public class SortedList
{
    private List<string> list = new List<string>();
    private SortStrategy sortstrategy;
    public void SetSortStrategy(SortStrategy sortstrategy)
    {
        this.sortstrategy = sortstrategy;
    }
    public void Add(string name)
    {
        list.Add(name);
    }
    public void Sort()
    {
        //Ask the "SortStrategy" class to sort the list. 
        sortstrategy.Sort(list);
    }
}
public interface SortStrategy
{
    void Sort(List<string> list);
}
public class QuickSort : SortStrategy
{
    public void Sort(List<string> list)
    {
        // Default is Quicksort
        list.Sort(); 
    }
}
public class ShellSort : SortStrategy
{
    public void Sort(List<string> list)
    {
        // ShellSort the "list" collection here. 
    }
}
public class MergeSort : SortStrategy
{
    public void Sort(List<string> list)
    {
        // MergeSort the "list" collection here. 
    }
}
Continue Reading

Use ProtoBuf.Net to improve serialization performance

Our application relied on data that did not change often. It had therefore implemented a solution that cached this data as xml files. These files were written to the web server on the first request and subsequently read whenever they were needed.
Some of the problems that arose due to this was:
a. Since the application was load balanced, a web server servicing a web request was not guaranteed to serve the next web request. This lead to the data in the various web servers quickly getting out of sync.
b. Our application was very slow. Profiling the application showed that showed that reading and writing(i.e serialization and de-serialization) the XML cache files was one of the biggest bottleneck in the application.
XML serialization is one of the slowest serializationde-serialization formats in the .Net framework. See the excellent article where Maxim Novak compares the various types of serialization in the .Net framework.

We therefore decided to change the serialization format from XML to ProtoBuf.Net. Protobuf-net is a contract based serializer for .NET code, that writes data in the “protocol buffers” serialization format engineered by Google. This framework component is written by Marc Gravell, considered as a .Net guru.
We also decided to change the application to write the cache files to a single file server and create the cache files in a background thread. I will write a separate article for the same in the future.
Changing the application to ProtoBuf.Net protocol was pretty straightforward.
a. Use Nuget to install ProtoBuf.Net framework component.

Install-Package protobuf-net

b. Add [ProtoContract] attribute to each class that needs to be serialized and [ProtoMember] Attribute with a unique integer to identify each member that needs to be serialized.

using ProtoBuf;
[ProtoContract]
class Person 
{
    [ProtoMember(1)]
    public int Id {get;set;}
    [ProtoMember(2)]
    public string Name {get;set:}
}

c. Serialize and deserialize your data

using (var file = File.Create("person.bin")) 
{
    Serializer.Serialize(file, person);
}
Person person;
using (var file = File.OpenRead("person.bin")) 
{
    person = Serializer.Deserialize<Person>(file);
}

As you can see from the charts below, the change from
a. XML to ProtoBuf.Net serialization
b. caching the files in a single file server instead of multiple file servers
c. offloading the work of generating the cache files to a background thread
was a huge success.

ProtoBuf.NetPerformanceImprovement-Part1

 

ProtoBuf.NetPerformanceImprovement-Part2

Using ProtoBuf.Net Serialization: The .Net profiler shows “HotSpots” due to serialization and de-serialization are much reduced. File sizes are also much reduced.

ProtoBufNetSerialization1

ProtoBufNetSerialization2

Using XML Serialization: The .Net profiler shows high CPU usage i.e “HotSpots” due to XML serialization and de-serialization. File sizes are also much larger.

XMLSerialization1

XMLSerialization2

Continue Reading

“Develop something useful in under 100 lines of code” contest.

One of my friends was recently asked to write the coolest/cleverest/most creative application in 100 lines of code or less. Any language could be used. It just needs to be creative, legible and easy enough to understand.

Here is my attempt. The program is a loan payment schedule calculator.
The formula to calculate loan payments is M = P * ( J / (1 – (1 + J) ^ -N)).
where
M = payment amount
P = principal, meaning the amount of money borrowed
J = effective interest rate. This is not the annual interest rate.
N = total number of payments
For more details see here .
I have also written several unit tests since I just do not like writing any code without unit tests. The actual code is just 30 lines and the remaining is all unit tests.
I have used the MidpointRounding.AwayFromZero enumeration to round a double to a number to two decimal points.


using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTestProject
{
    public class AmortizationSchedule : IAmortizationSchedule
    {
        public List<AmortizationScheduleRow> Get(double annualPercentageRate,
             double loanAmount, int loanPeriodInYears, DateTime loanStartDate)
        {
            if (annualPercentageRate <= 0 || loanAmount <= 0 || loanPeriodInYears <= 0 ||
                loanStartDate <= DateTime.MinValue)
            {
                throw new ArgumentException("Invalid arguments");
            }

            #region Calculate monthly payment
            const int NoOfMonthsInYear = 12;
            var loanPeriodInMonths = loanPeriodInYears * NoOfMonthsInYear;
            var effectiveInterestRate = annualPercentageRate / (NoOfMonthsInYear * 100);
            var toThePowerOfVariable = Math.Pow(1 + effectiveInterestRate, -loanPeriodInMonths);
            var monthlyPayment = (loanAmount * (effectiveInterestRate / (1 - toThePowerOfVariable)));
            #endregion

            #region Calculate payment schedule based on monthly payment and loan start date
            var amortizationSchedule = new List<AmortizationScheduleRow>();
            var currentMonthCounter = loanStartDate.AddMonths(1);
            var currentBalance = loanAmount;
            double totalInterestAmount = 0;
            for (var counter = 0; counter < loanPeriodInMonths; counter++)
            {
                var interestAmount = effectiveInterestRate * currentBalance;
                totalInterestAmount = totalInterestAmount + interestAmount;
                var amortizationScheduleRow = new AmortizationScheduleRow
                {
                    Date = currentMonthCounter,
                    MonthlyPaymentAmount = monthlyPayment,
                    InterestAmount = interestAmount,
                    TotalInterestAmount = totalInterestAmount
                };
                amortizationSchedule.Add(amortizationScheduleRow);
                currentBalance = currentBalance - amortizationScheduleRow.GetPrincipalAmount();
                currentMonthCounter = currentMonthCounter.AddMonths(1);
            }
            #endregion
            return amortizationSchedule;
        }
    }
    public interface IAmortizationSchedule
    {
        List<AmortizationScheduleRow> Get(double annualPercentageRate, double loanAmount, int loanPeriodInYears, DateTime loanStartDate);
    }
    public class AmortizationScheduleRow
    {
        public double GetMonthlyPaymentAmount()
        {
            return Math.Round(MonthlyPaymentAmount, 2, MidpointRounding.AwayFromZero);
        }
        public double MonthlyPaymentAmount { private get; set; }
        public double GetInterestAmount()
        {
            return Math.Round(InterestAmount, 2, MidpointRounding.AwayFromZero);
        }
        public double InterestAmount { private get; set; }
        public double GetTotalInterestAmount()
        {
            return Math.Round(TotalInterestAmount, 2, MidpointRounding.AwayFromZero);
        }
        public double TotalInterestAmount { private get; set; }
        public double GetPrincipalAmount()
        {
            var principalAmount = MonthlyPaymentAmount - InterestAmount;
            return Math.Round(principalAmount, 2, MidpointRounding.AwayFromZero);
        }
        public string GetDate()
        {
            return Date.ToString("MMM yyyy");
        }
        public DateTime Date { private get; set; }
    }
    [TestClass]
    public class AmortizationScheduleTester
    {
        const double annualPercentageRate = 3.5;
        const double loanAmount = 300000;
        const int loanPeriodInYears = 15;
        readonly DateTime loanStartDate = new DateTime(2016, 7, 1);
        [TestMethod]
        public void GetAmortizationScheduleExceptionTest()
        {
            const int NoOfMonthsInYear = 12;
            var monthlyPaymentSchedule = new AmortizationSchedule().Get(annualPercentageRate, loanAmount,
                loanPeriodInYears, loanStartDate);
            var secondMonthPaymentSchedule = monthlyPaymentSchedule[1];
            Assert.AreEqual(monthlyPaymentSchedule.Count, 15 * NoOfMonthsInYear);
            Assert.AreEqual(secondMonthPaymentSchedule.GetMonthlyPaymentAmount(), 2144.65);
            Assert.AreEqual(secondMonthPaymentSchedule.GetDate(), "Sep 2016");
            Assert.AreEqual(secondMonthPaymentSchedule.GetInterestAmount(), 871.30);
            Assert.AreEqual(secondMonthPaymentSchedule.GetTotalInterestAmount(), 1746.30);
            Assert.AreEqual(secondMonthPaymentSchedule.GetPrincipalAmount(), 1273.35);
        }
        [ExpectedException(typeof(ArgumentException))]
        [TestMethod]
        public void GetAmortizationScheduleExceptionTest1()
        {
            new AmortizationSchedule().Get(0, loanAmount,
                loanPeriodInYears, loanStartDate);
        }

        [ExpectedException(typeof(ArgumentException))]
        [TestMethod]
        public void GetAmortizationScheduleExceptionTest2()
        {
            new AmortizationSchedule().Get(annualPercentageRate, 0,
                loanPeriodInYears, loanStartDate);
        }
        [ExpectedException(typeof(ArgumentException))]
        [TestMethod]
        public void GetAmortizationScheduleExceptionTest3()
        {
            new AmortizationSchedule().Get(annualPercentageRate, loanAmount, 0, loanStartDate);
        }
        [ExpectedException(typeof(ArgumentException))]
        [TestMethod]
        public void GetAmortizationScheduleExceptionTest4()
        {
            new AmortizationSchedule().Get(annualPercentageRate, loanAmount,
                loanPeriodInYears, DateTime.MinValue);
        }
    }
}

Download Solution

Continue Reading

Exception handling in Async methods

Scenario 1: Take the following method for example:

public async void AsyncTaskWithAPossibleException()
{     
    //code that generates exception
}
public void MethodCallingAsyncTaskMethod()
{
    try
    {
        //Exceptions thrown by the AsyncTaskWithAPossibleException cannot be caught 
        //using the try catch block. It might crash the running process in most 
        //scenarios. 
        AsyncTaskWithAPossibleException();
    }
    catch (Exception)
    {
        // exception won't be caught
    }
}

Scenario 2.a: We can change the code in Scenario 1 to move the exception handling inside the AsyncTaskWithAPossibleException method.

public async void AsyncTaskWithAPossibleException()
{
    try
    {
        //code that generates exception
    }
    catch(Exception)
    {
        // Handle exception
    }
}
public void MethodCallingAsyncTaskMethod()
{
    AsyncTaskWithAPossibleException();
}

Scenario 2.b.: : Instead of handling the exception in the AsyncTaskWithAPossibleException method, we can also change the return type from void to Task(For a Async method, it is recommended to return a Task instead of a void).
Exception raised in the AsyncTaskWithAPossibleException method will be saved in the returning Task instance. When we await the AsyncTaskWithAPossibleException method, the exception saved in the Task will get rethrown with its stack trace preserved.

public async Task AsyncTaskWithAPossibleException()
{
    //code that generates exception
}
public async Task MethodCallingAsyncTaskMethod()
{
    try
    {
        await AsyncTaskWithAPossibleException();
    }
    catch (Exception)
    {
        // exception is caught with stack trace preserved
    }
}

Scenario 3: If for some reason we don’t await the Task, we can define a continuation when the Task ends with the faulted state.

public async Task AsyncTaskWithAPossibleException()
{
    //code that generates exception
}
public void MethodCallingAsyncTaskMethod()
{
    var task = AsyncTaskWithAPossibleException();
    task.ContinueWith(t =>
    {
        //  handle t.Exception
    }, TaskContinuationOptions.OnlyOnFaulted);
}

Scenario 4: If for some reason we don’t await the Task and we do not define a continuation when the Task ends with the faulted state, the exception saved inside the instance will be raised eventually when the GC collects the object. You can catch that silent exception using the TaskScheduler event UnobservedTaskException.

Continue Reading