An Opinionated Usage of Interface

Every C# developer knows what interface is. From the code perspective it is interface ISomething. There is no requirement for the I in the interface name. But that is just the naming convention. And it is good to know it is an interface by looking at the name. A more interesting question is when do we use interface?. And I guess each developer might have their own answer and reasons behind them.

Back in time, about 10 years ago, I started to use interface a lot. Back then the obvious reason was mocking and unit testing. And then the dependency injection came to my developer life. I read somewhere that you should inject interfaces instead of concrete implementations.

Have you ever heard of these?

  • Depend on interfaces instead of concrete implementations
  • It is easier for you to change the implementation later
  • It helps you mocked the implementation in the unit test
  • Your code looks clean and professional

In some codebases, I ended up with interfaces everywhere. The unit test was a bunch of mocks and mocks, everywhere. It looked good in the beginning. However, after a while, it was a pain.

  • It was hard to do the refactoring. For example, when I did not want to move a piece of code from this class to another class without changing the outcome behavior, the unit test failed. Because the expected interface was no longer there. The unit test knew too much about the implementation detail. I have the habit of refactoring code quite often. And I expect the unit test to catch my mistake if I accidentally change the outcome behavior. With mocking, I failed to archive that
  • Had to test at every layer. Basically, there were behavior test with mocking and there were tests for actual implementation. There were too much test code to maintain. Well, that was a waste of time and effort and error prone in the test
  • The chances of actually changing an implementation was rare

Ok, so is interface useful? Of course yes it is. And here are my opinions when to use it.

Code Contract

The interface tells the consumers the functionalities it supports. A class might have 10 methods. But not all consumers use or care 10 methods. They might be interested in 2 or 3 methods. It is fine to inject the class. However, the consumer is confused and might misuse.

Let take an example of an imagination log service. Here is the concrete implementation

public class SimpleLogService
{
    public void WriteLog(string logMessage)
    {

    }

    public IList<string> GetLogs()
    {
        return new List<string>();
    }
}

// API Controller to read the log
public class LogController : Controller
{
    private readonly SimpleLogService _logService;
    public LogController(SimpleLogService logService)
    {
        _logService = logService;
    }

    public IActionResult Get()
    {
        return OK(_logService.GetLogs());
    }
}

There is nothing wrong with the above code. However, I do not want the LogController to see/use the WriteLog method. That method is used by another controllers or services. And the SimpleLogService class might grow in size over the time. More and more methods are developed.

To solve that problem, I want to create a contract to tell LogController what it can use.

public interface ILogReaderService
{
    public IList<string> GetLogs();
}

public class SimpleLogService : ILogReaderService
{
    public void WriteLog(string logMessage)
    {

    }

    public IList<string> GetLogs()
    {
        return new List<string>();
    }
}

// API Controller to read the log
public class LogController : Controller
{
    private readonly ILogReaderService _logService;
    public LogController(ILogReaderService logService)
    {
        _logService = logService;
    }

    public IActionResult Get()
    {
        return OK(_logService.GetLogs());
    }
}

And I can do the same for the WriteLog part if necessary.

Decouple Implementation Dependency

In many projects, there is data involve. There are databases. And then comes the concept of Repository. And if the repository implementation is easy and that the database is ready. A developer can write a complete feature from API layer down to database layer. But I am doubt that is the reality. So the situation might look like this

  • One developer takes care of front end development
  • One developer takes care of the API (controller) implementation
  • One developer takes care of designing database, writing the repository. This might be the same developer that implements the API

The API layer depends on the Repository. However, we also want to see the flow and speed up the development. Let’s see some code

public class UserController : Controller
{
    private readonly IUserRepository _repository;

    public UserController(IUserRepository repository)
    {
        _repository = repository;
    }

    public async Task<IActionResult> GetUsers()
    {
        var users = await _repository.GetAllUsers();

        return Ok(user);
    }
}

The IUserRepository is the Code Contract between API and the repository implementation. To unlock the development flow, a simple in memory repository implementation is introduced

public class InMemoryUserRepository : IUserRepository
{
    public async Task<IList<User>> GetAllUsers()
    {
        await Task.CompletedTask();

        return new List<User>{
            new User("Elsa"),
            new User("John"),
            new User("Anna")
        };
    }
}

And the API can function. This releases the dependency on the actual repository implementation. When such an implementation is ready, switch to use it.

However, do not overuse it. Otherwise, you end up with interfaces everywhere and each developer gives their own temporary implementations. Choosing the right dependencies is an art and context matters a lot.

Conclusion

I rarely create interfaces with the purpose of unit testing in mind. Rather, it is the outcome of writing code, refactoring from a concrete implementation and then extracting into interfaces where they make the most sense. When I do, I pay close attention to its meaning. If I can avoid an interface, I will do it.

Code Contract and Decouple Implementation Dependency are the 2 big benefits from having proper interfaces. There are other reasons to use interfaces. They are all valid depending on the context. Sometime, it is the way the project architect wants it.

What are yours?

C# Extend with Extension Method

Many C# developers know the existence of Extension Methods. It gives developers the ability to extend functionalities of the existing API without modifying the original source code.

A simple example is to check if a string is a numeric value. There are more than one solution to solve that problem. And one of them is that we want to write code like this:


string houseNumber = "123";
bool isNumber = houseNumber.IsNumeric();

The IsNumeric is not a built-in method on the string type. With the extension method, we could implement the IsNumeric easily.

public static bool IsNumeric(this string input)
{
    return Regex.IsMatch(input, "^[0-9]+$");
}

That is the basic concept. LINQ is the main consumer of the benefit. Or we might say that LINQ was the reason why the extension method concept was born. Of course, we do not have to know it to use LINQ.

So what is this post about? We could take advantages of the extension method to improve our design and implementation even when the code is under development, which means we are free to change our code.

Take a look at this simple interface

public interface IDocumentRepository
{
    /// <summary>
    /// Get a document of given type <T> by id. Return null if not found
    /// </summary>
    T GetDocument<T>(Guid id);
}

A simple, generic repository. The detail implementation does not matter here.

Later in the development, there are many places having this kind of logic (code)

var document = _repository.GetDocument<Product>(id);

if(document == null)
    throw new ObjectNotFoundException();

// Do something with the document here

Just some checking. It is not a big deal, except the fact that we need to do it in many places. So we want the ability to write this code

var document = _repository.GetOrThrow<Product>(id);

So what are options?

Modify the interface and implementation

One could go with this approach

public interface IDocumentRepository
{
    /// <summary>
    /// Get a document of given type <T> by id. Return null if not found
    /// </summary>
    T GetDocument<T>(Guid id);

    T GetOrThrow<T>(Guid id);
}

And implement the method in all derived classes. The approach works but I do not like it much for a couple of reasons

  1. That logic does not fit there naturally. It is a logic added on the existing functionality
  2. All the implemented classes are modified. In the best case, there is only one implemented class
  3. And what about later we need other kind of that functionalities? Will we keep expanding the interface?
  4. Usually the interface is at the infrastructure, but the extended functions are in the service or small bounded contexts. Some functions do not make any sense in other boundaries

Extend by extension methods

We could keep the interface clean as it was designed and extend the function by using extension methods as shown

public static class DocumentRepositoryExtensions
{
    public static T GetOrThrow<T>(this IDocumentRepository repository, Guid id)
    {
        var document = repository.GetDocument<Product>(id);

        if(document == null)
            throw new ObjectNotFoundException();

        return document;
    }
}

And we are free to place this code in the place that uses it. If it is required in many layers, assemblies, consider to put it in a separate assembly.

However, be reasonable otherwise you end up with extension methods everywhere. It is about placing the responsibilities in the right place.

I have been using this approach in my recent projects. And I am glad I have done it!

C# 7 Tuple Better Test Assertion

Recently I read C# In Depth 4.0 where I met the new Tuple design in C# 7. It is really a cool feature. Beside the syntax sugar, it offers capacities that developers can leverage.

At the time of reading it, I was tasked with writing unit tests in my job. It triggered my memory about Semantic Comparison with Likeness. The main idea of semantic comparison is to compare 2 objects with certain properties. It allows developers to define what equality means. The tuple supports the equality by default. So maybe I should be able to use the tuple to accomplish the same thing as Likeness.

In this post, I will write a simple unit test without Likeness or tuple, then refactors it with Likeness, finally uses Tuple. Let’s explore some code.

public class Product
{
    public Guid Id { get; set;}
    public string Name { get; set;}
    public double Price { get; set;}
    public string Description { get; set;}
}

[TestFixture]
public class ProductTests
{
    [Test]
    public void Test_Are_Products_Same()
    {
        var expectedProduct = new Product
        {
            Name = "C#",
            Price = 10,
            Description = "For the purpose of demoing test"
        };

        var reality = new Product
        {
            Name = "C#",
            Price = 10,
            Description = "For the purpose of demoing test"
        };

        // Assert that 2 products are the same. Id is ignored
    }
}

The task is simple. How are we going to assert the 2 products?

Old Fashion

Very simple. We simply assert property by property.

[TestFixture]
public class ProductTests
{
    [Test]
    public void Test_Are_Products_Same()
    {
        var expectedProduct = new Product
        {
            Name = "C#",
            Price = 10,
            Description = "For the purpose of demoing test"
        };

        var reality = new Product
        {
            Name = "C#",
            Price = 10,
            Description = "For the purpose of demoing test"
        };

        Assert.AreEqual(expectedProduct.Name, reality.Name);
        Assert.AreEqual(expectedProduct.Price, reality.Price);
        Assert.AreEqual(expectedProduct.Description, reality.Description);
    }
}

Some might think that we should override the Equals method in the Product class. I do not think it is a good idea. The definition of equality between production and unit test are tremendously different. Be careful before overriding equality.

The product class has 3 properties (except the Id property). So the code still looks readable. Think about the situation where there are 10 properties.

Likeness – Semantic Comparison

There is a blog post explaining it in the detail. In this demo, we can rewrite our simple test.

[TestFixture]
public class ProductTests
{
    [Test]
    public void Test_Are_Products_Same()
    {
        var expectedProduct = new Product
        {
            Name = "C#",
            Price = 10,
            Description = "For the purpose of demoing test"
        }.AsSource()
        .OfLikeness<Product>();

        var reality = new Product
        {
            Name = "C#",
            Price = 10,
            Description = "For the purpose of demoing test"
        };

        Assert.AreEqual(expectedProduct, reality);
    }
}

Likeness is a powerful tool in your testing toolbox. Check it out if you are interested in.

Tuple – Customized

The idea is that we can produce a tuple containing asserted properties and compare them. This allows us to flatten the structure if wished.

[TestFixture]
public class ProductTests
{
    [Test]
    public void Test_Are_Products_Same()
    {
        var expectedProduct = (Name = "C#", Price = 10, Description = "For the purpose of demoing test");

        var reality = new Product
        {
            Name = "C#",
            Price = 10,
            Description = "For the purpose of demoing test"
        };

        Assert.AreEqual(expectedProduct, (reality.Name, reality.Price, reality.Description));
    }
}

It might not look different from the Likeness approach. And I do not say which approach is better. It is just another way of doing things.

Summary

So which approach is better? None of them. Each has their own advantages and disadvantages. They are options in your toolbox. How they are used depends on you, developers. Definitely I will take advantages of the new Tuple in both production and unit test code.

Async Await and Parallelism

In C#, async and await was first introduced in C# 5  detail explanation in MS Docs. You should go ahead and read those full articles. Starting from MVC 4, the async controller was introduced with async/await. Since then developers have been using async/await whenever possible.

What if a senior developer being asked: Hey explain async/await for juniors. We think we know something is just step 1. And that understanding might be wrong until we can explain to someone else.

Some believe that having asynchronous operations will make the system faster because more threads are used. Some say async will not block the main thread allowing better responsiveness of Windows Applications, or serving more requests in a Web Application.

How could we explain them? Not so many people have deep knowledge to dig deep in the low level implementation. Given that someone can (yes there are many of them), it is not easy to explain to others. Where is the balance? How about mapping the complex concept with something familiar?

I am not discussing the performance part, or will it be faster than sync. That is a complex topic and depending on many factors. Let’s analyze the serving more requests in a Web Application part.

Here is the truth, if you are in doubt ask Google

Async controller actions will allow a web application serves more requests.

Welcome to the Visa Department! You are here to get your Visa to US. There are 3 people in the department: Bob, John, and Lisa. Everyday there are hundreds of citizens come.

An applicant comes, Bob takes it. He does all the steps defined in the process. He might finish and come back 3 hours later. An applicant is solved and returned to the client.

When Bob is busy, John and Lisa take the next applicants and the process repeats. If Bob, John, and Lisa have not finished their applicants, there are just 3 applicants served. The rest has to wait.

There are 3 applicants served. The rest has to wait.

That is ASP.NET MVC synchronous controller in action. It blocks the processing pipeline.

The three decide to make a change. They organize their work and responsibilities

  1. Bob: Take incoming applicants. Put them on the boxes (labeled Requests Box) on tables next to him.
  2. John, Lisa: Take applicants in the boxes, proceed them. When an applicant is proceeded, put it in other boxes (labeled Responses Box) in the department.
  3. Whenever there is an applicant in the Responses Box, whoever (Bob, John, or Lisa) is free, take the applicant and return to the client.

What have changed in this model?

  1. Bob can take as many applicants as he can. Many clients are served.They can return to their seat, take a coffee and wait for the result.
  2. John and Lisa can coordinate or utilize the resources they have to finish the job.
  3. Anyone can return the result. Bob receives the applicant but maybe Lisa returns the result.

Is it faster to proceed one applicant? We do not know.

Can we serve many clients (applicants) in a day? Yes, definitely!

That is the ASP.NET MVC async controller in action.

Concept mapping

  1. Citizen (visa application): Request
  2. Visa Department: Web Server hosts the application.
  3. Bob, John, and Lisa: Thread
  4. Proceed an applicant: Application domain logic.
  5. Accept an applicant: Controller Action.

 

Ok Cool! Let’s see some code.

    public class ThreadModel
    {
        public int Id { get; set; }
        public string Message { get; set; }
    }
    public class ThreadTestController : Controller
    {
        [HttpGet]
        public async Task<ActionResult> Info()
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            var model = new List<ThreadModel>();
            model.Add(new ThreadModel
            {
                Id = Thread.CurrentThread.ManagedThreadId,
                Message = "Bob receives a visa applicant"
            });
            await Task.Delay(TimeSpan.FromSeconds(30));
            stopwatch.Stop();
            model.Add(new ThreadModel
            {
                Id = Thread.CurrentThread.ManagedThreadId,
                Message = $"Lisa returns the applicant after: {stopwatch.Elapsed}"
            });
            return Json(model);
        }
    }

And the outcome

[{"id":3,"message":"Bob receives a visa applicant"},
{"id":25,"message":"Lisa returns the applicant after: 00:00:30.0024240"}]

The request is handled at the thread 3 (Bob). And the response is handled at the thread 25 (Lisa). The elapsed time is 30 seconds.

Ok, then let’s see how long would it take if we await twice

    public class ThreadModel
    {
        public int Id { get; set; }
        public string Message { get; set; }
    }
    public class ThreadTestController : Controller
    {
        [HttpGet]
        public async Task<ActionResult> Info()
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            var model = new List<ThreadModel>();
            model.Add(new ThreadModel
            {
                Id = Thread.CurrentThread.ManagedThreadId,
                Message = "Bob receives a visa applicant"
            });
            await Task.Delay(TimeSpan.FromSeconds(30));
            await Task.Delay(TimeSpan.FromSeconds(30));
            stopwatch.Stop();
            model.Add(new ThreadModel
            {
                Id = Thread.CurrentThread.ManagedThreadId,
                Message = $"Lisa returns the applicant after: {stopwatch.Elapsed}"
            });
            return Json(model);
        }
    }

And the result

[{"id":29,"message":"Bob receives a visa applicant"},
{"id":32,"message":"Lisa returns the applicant after: 00:01:00.0099118"}]

It is 1 minute. Can we make it faster? How about this?

   public class ThreadTestController : Controller
    {
        [HttpGet]
        public async Task<ActionResult> Info()
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            var model = new List<ThreadModel>();
            model.Add(new ThreadModel
            {
                Id = Thread.CurrentThread.ManagedThreadId,
                Message = "Bob receives a visa applicant"
            });
            var t1 = Task.Delay(TimeSpan.FromSeconds(30));
            var t2 = Task.Delay(TimeSpan.FromSeconds(30));
            await Task.WhenAll(t1, t2);
            stopwatch.Stop();
            model.Add(new ThreadModel
            {
                Id = Thread.CurrentThread.ManagedThreadId,
                Message = $"Lisa returns the applicant after: {stopwatch.Elapsed}"
            });
            return Json(model);
        }
    }

Hey, look

[{"id":4,"message":"Bob receives a visa applicant"},
{"id":27,"message":"Lisa returns the applicant after: 00:00:30.0134799"}]

It is 30 seconds.

 

Asynchronous programming is a hard job. A proper understanding is very important. You do not understand unless you can explain.

C# Delegate

When was the last time you write code using delegate in C#? Hmm do you know what it means? To be honest, I have not used delegate keyword for years. Long time ago, when I wrote I had to google for the syntax. With the evolving of C#, we have not seen it being used in production code. But, it is important, or at least is nice, to know what it is.

Years ago, when I read about it, I did not understand at all. I could not wrap it up in my head. Therefore, I avoided to use it. Maybe because I did not understand the why behind the keyword.

Time flies. I am reading C# fundamentals again. Luckily, with 10 years of experience, I can understand the delegate keyword, not that bad.

Here is the official document from MS Doc. However, I would suggest you to read from Jon Skeet.

Such a definition might cause confusion and hard to understand. One way to understand a new concept is to map it with what we have known. I hope you can have your own mapping.

Let’s explore some examples to understand delegate. Imagine a context where there is a team which has a team leader and some developers. There are some bugs need to fixed in a week. The team leader has the responsibility of leading the team to finish the mission.

The example might confuse you because, well, it is an imaginary context. In the real life, or real project modeling, things are so much complicated. The main point is a playground to write some code with delegate, forget about all new fancy stuffs such as Action, Func, inline method, or expression.

Wire up a very simple .NET Core project using VS Code, here the first version I got (after some failing builds with first time using VS Code on Mac)

using System;
using System.Collections.Generic;
namespace funApp
{
    
    delegate void KillBug(Bug bug);
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello Team Leader");
            var tl = new TeamLeader();
            tl.StartSprint(new List<Bug>{
                new Bug("Fix homepage layout"),
                new Bug("Timeout exception when searching")
            });
            tl.RunSprint(new KillBug(SayBugName));
            
            Console.Read();
        }
        private static void SayBugName(Bug bug)
        {
            Console.WriteLine($"Hi {bug.Name}, how are you today?");
        }
        
    }
    class TeamLeader
    {
        private IList<Bug> _bugs = new List<Bug>();
        public void StartSprint(IList<Bug> bugsFromBacklog)
        {
            foreach (var bug in bugsFromBacklog)
            {
                _bugs.Add(bug);
            }
        }
        public void RunSprint(KillBug knowHowToKillBug)
        {
            foreach (var bug in _bugs)
            {
                knowHowToKillBug(bug);
            }
        }
    }
    class Bug
    {
        public string Name { get; set; }
        
        public Bug(string name)
        {
            Name = name;
        }
    }
}

It works.

The example demonstrates a very important concept in programming: Separation of Concern. Looking at the RunSprint method for a moment. A team leader usually does not know how to kill a bug, I know many team leaders are great developers, but they cannot kill all bugs themselves. They usually use ones who know how to kill a bug, which is usually a developer in his/her team. Or he can outsource to others, as far as they know how to kill a bug. That “know how to kill a bug” is modeled via a delegate “KillBug”.

In later version of C# (2, 3,..) and .NET, there are more options to rewrite the code to get rid of KillBug delegate declaration. But the concept remains.

       public void RunSprint(Action<Bug> knowHowToKillBug)
        {
            foreach (var bug in _bugs)
            {
                knowHowToKillBug(bug);
            }
        }

That method will produce the same outcome.

Do I need to know delegate to write C# code, to finish my job? No. You don’t.

Do I need to understand it? Yes. You should. Understanding the why behind the delegate concept is very important to make a proper design. Every feature has a good reason. We, developers, must understand that reason to make the best use.

%d bloggers like this: