Thursday, 15 October 2015

Inversion of control

Inversion of control is a design pattern that eliminates dependencies by supplying services and delegates to classes instead of defining them in that class. What does that mean? Well the S in SOLID stands for Single responsibility which is one of the goals of modern software development: low coupling and high cohesion which basically means we want our classes to be very specific and independent of each other, if we have an Employee class, that class should only know things about being an employee, not about printing an employee or creating an employee report or anything to do with an employees hours.

before we get started, open your .csproj file, it should look like the following:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>


replace it with 

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <UseWindowsForms>true</UseWindowsForms>
    <TargetFramework>net6.0-windows</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>


notice how we the 'UseWindowsForms' node and set it to true, and we change the 'TargetFramework' to 'net6.0-windows', these changes will let us use the windows forms ui elements inside our 'Console' app, we'll only be interested in the Message box.

Let's stick to our idea of an employee inheriting from a person, but this time let's create a report service first, our report service will have the responsibility of 'printing' the employee or person info, this is a bit contrived, but stick with me.


class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName { get { return $"{FirstName} {LastName}"; } }
    public Person() {
        this.FirstName = "";
        this.LastName = "";
    }
    public Person(string FirstName, string LastName) : this()
    {
        this.FirstName = FirstName;
        this.LastName = LastName;
    }
}

class Employee : Person {
    static int runningID = 0;
    public int Id { get; private set; } = runningID++;

    IReportService<Employee> ReportService;

    public Employee(string fn, string ln, IReportService<Employee> ReportService)
        : base(fn, ln) {
        this.ReportService = ReportService;
    }

    public void Print() {
        if (ReportService == null)
            throw new NullReferenceException("No Report service ");

        ReportService.Output(this);
    }
}


above we are using our standard Employee: Person implementation however with one exception, we pass into the constructor of the Employee an IReportService which we use in the print method, now let's take a look at our IReportService interface.


interface IReportService<T> {
    void Output(T emp);
}


pretty simple, it defines one method, now let's create not one, but two implementations of our interface.


class ConsoleReportService : IReportService<Employee>
{
    public void Output(Employee emp)
    {
        Console.WriteLine(emp.FullName);
    }
}


the first uses the console to output our employee's full name. For the second we're going to use a message box.


class MessageReportService : IReportService<Employee>
{
    public void Output(Employee emp)
    {
        MessageBox.Show(emp.FullName);
    }
}


with those complete let's take a look at our main


class Program
{
    static void Main(string[] args)
    {

        var emp = new Employee("Pawel", "Ciucias", new ConsoleReportService());
        emp.Print();

        var emp2 = new Employee("Tomek", "Ciucias", new MessageReportService());
        emp2.Print();
    }
}


We can see that our employee class really has no clue how our ReportService works, it just knows that there is one and that it has a print method. we can have multiple variations of our Report service and just pass whichever one is appropriate at the time.

to make it easer to copy and paste here's the full code.

namespace pav.ioc;

interface IReportService<T> {
    void Output(T emp);
}

class ConsoleReportService : IReportService<Employee>
{
    public void Output(Employee emp)
    {
        Console.WriteLine(emp.FullName);
    }
}

class MessageReportService : IReportService<Employee>
{
    public void Output(Employee emp)
    {
        MessageBox.Show(emp.FullName);
    }
}

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName { get { return $"{FirstName} {LastName}"; } }
    public Person() {
        this.FirstName = "";
        this.LastName = "";
    }
    public Person(string FirstName, string LastName) : this()
    {
        this.FirstName = FirstName;
        this.LastName = LastName;
    }
}

class Employee : Person {
    static int runningID = 0;
    public int Id { get; private set; } = runningID++;

    IReportService<Employee> ReportService;

    public Employee(string fn, string ln, IReportService<Employee> ReportService)
        : base(fn, ln) {
        this.ReportService = ReportService;
    }

    public void Print() {
        if (ReportService == null)
            throw new NullReferenceException("No Report service ");

        ReportService.Output(this);
    }
}

class Program
{
    static void Main(string[] args)
    {

        var emp = new Employee("Pawel", "Ciucias", new ConsoleReportService());
        emp.Print();

        var emp2 = new Employee("Tomek", "Ciucias", new MessageReportService());
        emp2.Print();
    }
}

Monday, 12 October 2015

Interface programming

By separating our implementation and declaration of what a class should do verses what it does we decouple the logic that our class implements from the contract our interface defines. We spoke about the fact that an interface is basically a schema for a class, it defines the public members that a class must implement. Let's say that we have the following interface.


interface IDataStorage<in Id, T>
{
void Create(T Entity);
T? Read(Id Id);
void Update(T Entity);
void Delete(Id Id);
void ListAll();
}


We're jumping the gun a bit with generics, but for now just trust me that the Id and T represent defined types, think of them as a place holders for either a string or an int or any other defined type. The in keyword for now just think of it as input, so we cannot return a type ID, just receive it as input. 

This Interface simply defines a function and four methods for reading and writing to some sort of data storage, Now let's create an entity class that we can pass to our implementation of IDataStorage. Let's stick to our Person concept.


class Person
{
static int runningID = 0;
public int Id { get; private set; } = runningID++;
public string FirstName { get; set; }
public string LastName { get; set; }
public Person() {
this.FirstName = "";
this.LastName = "";
}
public Person(string FirstName, string LastName) : this()
{
this.FirstName = FirstName;
this.LastName = LastName;
}
public string WriteValue() { return $"{FirstName} {LastName}"; }
}


With our person class ready, we can now create a data storage class that implements our interface


class ListStorage : IDataStorage<int, Person>
{
List<Person> People = new List<Person>();

public void Create(Person Entity)
{
if (!People.Contains(Entity))
People.Add(Entity);
}

public Person? Read(int Id) => People?.FirstOrDefault(p => p.Id == Id) ;

public void Update(Person Entity) => People[People.IndexOf(Entity)] = Entity;

public void Delete(int Id) {
var personToRemove = this.Read(Id);
if(personToRemove is not null)
People.Remove(personToRemove);
}

public void ListAll()
{
foreach (var p in People)
Console.WriteLine(p.WriteValue());
}
}


The idea is that our ListStorage class implements our interface; in a real word application you could use this as a mock data storage item for testing.

Now let's create another class, ArrayStorage that also implements our interface.


class ArrayStorage : IDataStorage<int, Person>
{
Person[] People = new Person[0];
int index = 0;
public void Create(Person Entity)
{
if (People == null)
People = new Person[10];
else if (People.Length == index)
Array.Resize(ref People, People.Length + 10);

for (var i = 0; i < index; i++)
if (People[i].Id == Entity.Id)
return;

People[index++] = Entity;
}

public void Delete(int Id) { throw new NotImplementedException(); }

public void ListAll()
{
for (var i = 0; i < index; i++)
Console.WriteLine(People[i].WriteValue());
}

public Person? Read(int Id)
{
for (var i = 0; i < index; i++)
if (People[i].Id == Id)
return People[i];
return null;
}

public void Update(Person Entity) { throw new NotImplementedException(); }
}


I didn't go to the trouble of implementing all of the members or even bulletproofing the ones I did. The idea is to demonstrate that there's two classes implementing the same interface in two different ways. The important take away is that we have abstracted the implementing of our logic, meaning that for any code that consumes our interface, the logic itself is insignificant, we can use the two repositories interchangeably.


class Program
{
static void Main(string[] args)
{
IDataStorage<int, Person> ListStorage = new ListStorage();
IDataStorage<int, Person> ArrayStorage = new ArrayStorage();

var John = new Person("John", "Smith");
var Mike = new Person("Mike", "Johnson");
var Frank = new Person("Frank", "White");

ListStorage.Create(John);
ListStorage.Create(Mike);

ArrayStorage.Create(John);
ArrayStorage.Create(Mike);
ArrayStorage.Create(Frank);

ListStorage.ListAll();
ArrayStorage.ListAll();
}
}


You can see that the ListStorage and ArrayStorage classes are basically interchangeable, by decoupling the definition of a class from it's implementation we increase the maintainability of our application. For example let's say that instead of a ListStorage class we had a OracleStroage class and our organisation decides to switch to Azure, well in such a case we could create an AzureStorage class that implements our interface, limiting the amount of changes that we would have to make to our application.

and for good measure, the full code code you can copy and paste into a console application.


namespace pav.interfaceBased;
interface IDataStorage<in Id, T>
{
void Create(T Entity);
T? Read(Id Id);
void Update(T Entity);
void Delete(Id Id);
void ListAll();
}

class ListStorage : IDataStorage<int, Person>
{
List<Person> People = new List<Person>();

public void Create(Person Entity)
{
if (!People.Contains(Entity))
People.Add(Entity);
}

public Person? Read(int Id) => People?.FirstOrDefault(p => p.Id == Id);

public void Update(Person Entity) => People[People.IndexOf(Entity)] = Entity;

public void Delete(int Id)
{
var personToRemove = this.Read(Id);
if (personToRemove is not null)
People.Remove(personToRemove);
}

public void ListAll()
{
foreach (var p in People)
Console.WriteLine(p.WriteValue());
}
}

class ArrayStorage : IDataStorage<int, Person>
{
Person[] People = new Person[0];
int index = 0;
public void Create(Person Entity)
{
if (People == null)
People = new Person[10];
else if (People.Length == index)
Array.Resize(ref People, People.Length + 10);

for (var i = 0; i < index; i++)
if (People[i].Id == Entity.Id)
return;

People[index++] = Entity;
}

public void Delete(int Id) { throw new NotImplementedException(); }

public void ListAll()
{
for (var i = 0; i < index; i++)
Console.WriteLine(People[i].WriteValue());
}

public Person? Read(int Id)
{
for (var i = 0; i < index; i++)
if (People[i].Id == Id)
return People[i];
return null;
}

public void Update(Person Entity) { throw new NotImplementedException(); }
}

class Person
{
static int runningID = 0;
public int Id { get; private set; } = runningID++;
public string FirstName { get; set; }
public string LastName { get; set; }

public Person()
{
this.FirstName = "";
this.LastName = "";
}
public Person(string FirstName, string LastName) : this()
{
this.FirstName = FirstName;
this.LastName = LastName;
}

public string WriteValue() { return $"{FirstName} {LastName}"; }
}


class Program
{
static void Main(string[] args)
{
IDataStorage<int, Person> ListStorage = new ListStorage();
IDataStorage<int, Person> ArrayStorage = new ArrayStorage();

var John = new Person("John", "Smith");
var Mike = new Person("Mike", "Johnson");
var Frank = new Person("Frank", "White");

ListStorage.Create(John);
ListStorage.Create(Mike);

ArrayStorage.Create(John);
ArrayStorage.Create(Mike);
ArrayStorage.Create(Frank);

ListStorage.ListAll();
ArrayStorage.ListAll();
}
}

Sunday, 11 October 2015

Faux Inheritance

C# will not allow you to inherit from multiple base classes; you can only inherit from one class, but your class can implement multiple interfaces. Let's take a look at our previous examples of an IStudent interface, Person Class and our Student Class that inherits Person and implements IStudent.


namespace pav.multipleInterfaces;

class Program
{
    interface IStudent
    {
        int StudentNumber { get; }
        IList<decimal> Grades { get; set; }
        decimal CalculateGPA();
    }

    class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime Birthdate { get; set; }
        public string FullName { get { return $"{FirstName} {LastName}"; } }

        public Person() {
            this.FirstName = "";
            this.LastName = "";
        }

        public Person(string FirstName, string LastName) : this() {
            this.FirstName = FirstName;
            this.LastName = LastName;
        }

        public Person(string FirstName, string LastName, DateTime Birthdate)
            : this(FirstName, LastName) {
            this.Birthdate = Birthdate;
        }

        public string WriteValue() { return $"{FullName}"; }
    }

    class Student : Person, IStudent
    {
        static int RunntingStudentNumber = 0;

        public IList<decimal> Grades { get; set; }
        public int StudentNumber { get; } = RunntingStudentNumber++;

        public Student(string FirstName, string LastName, DateTime Birthdate) : base(FirstName, LastName, Birthdate)
        {
            this.Grades = new List<decimal>();
        }

        public Student()
        {
            this.Grades = new List<decimal>();
        }

        public decimal CalculateGPA()
        {
            decimal total = 0;
            foreach (var g in Grades)
                total += g;
            return total / Grades.Count;
        }
    }

    static void Main(string[] args)
    {
        Console.WriteLine("Hello, World!");
    }
}


now let's create an Employee class which inherits from person,


    class Employee : Person
    {
        static int runningId = 0;
        public int Id { get; private set; } = runningId++;
       
        public Employee() : base() { }
        public Employee(string FirstName, string LastName)
            : base(FirstName, LastName) { }
        public Employee(string FirstName, string LastName, DateTime Birthdate)
            : base(FirstName, LastName, Birthdate) { }

        public new string WriteValue() { return $"{Id}: {base.WriteValue()}"; }

    }


and now we're ready to create our TeachingAssistant class, a class that is both an employee and a student. The reason we organized our code in this fashion is because we can have employees, students and teaching assistants, they all inherit from Person, and all teaching assistants are both employees and students, but not all employees are students and vice versa.


    class TeachingAssistant : Employee, IStudent
    {
        static int RunntingStudentNumber = 0;
        public IList<decimal> Grades { get; set; }
        public int StudentNumber { get; } = RunntingStudentNumber++;
        public decimal CalculateGPA()
        {
            decimal total = 0;
            foreach (var g in Grades)
                total += g;
            return total / Grades.Count;
        }
    }


now is this ideal? no it's not because we still had to rewrite the implementation for IStudent inside of the Teaching assistant class, but at least this way we can at least ensure that the public members we expect are present. 

An alternative option is to create an internal instance of a studentLogic class which would implement the IStudent interface, then either instantiate that class within our teaching Assistant and Student classes and expose the logic via the IStudent members of the respective classes. Such an approach could look like the following.

namespace pav.multipleInterfaces;
class Program
{
    public interface IStudent
    {
        int StudentNumber { get; }
        IList<decimal> Grades { get; set; }
        decimal CalculateGPA();
    }

    class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime Birthdate { get; set; }
        public string FullName { get { return $"{FirstName} {LastName}"; } }
        public Person()
        {
            this.FirstName = "";
            this.LastName = "";
        }
        public Person(string FirstName, string LastName) : this()
        {
            this.FirstName = FirstName;
            this.LastName = LastName;
        }
        public Person(string FirstName, string LastName, DateTime Birthdate)
            : this(FirstName, LastName)
        {
            this.Birthdate = Birthdate;
        }

        public string WriteValue() { return $"{FullName}"; }
    }

    internal class StudentLogic : IStudent
    {
        static int RunntingStudentNumber = 0;

        public IList<decimal> Grades { get; set; }
        public int StudentNumber { get; } = RunntingStudentNumber++;

        public StudentLogic()
        {
            this.Grades = new List<decimal>();
        }

        public decimal CalculateGPA()
        {
            decimal total = 0;
            foreach (var g in Grades)
                total += g;
            return total / Grades.Count;
        }
    }

    class Student : Person, IStudent
    {
        private IStudent _student;

        public IList<decimal> Grades
        {
            get
            {
                return _student.Grades;
            }
            set
            {
                _student.Grades = value;
            }
        }

        public int StudentNumber
        {
            get
            {
                return _student.StudentNumber;
            }
        }

        public Student(string FirstName, string LastName, DateTime Birthdate) :  base(FirstName, LastName, Birthdate)
        {
            this._student =  new StudentLogic();
        }

        public decimal CalculateGPA() => _student.CalculateGPA();
    }

    class Employee : Person
    {
        static int runningId = 0;
        public int Id { get; private set; } = runningId++;

        public Employee() : base() { }
        public Employee(string FirstName, string LastName)
            : base(FirstName, LastName) { }
        public Employee(string FirstName, string LastName, DateTime Birthdate)
            : base(FirstName, LastName, Birthdate) { }

        public new string WriteValue() { return $"{Id}: {base.WriteValue()}"; }
    }

    class TeachingAssistant : Employee, IStudent
    {
        private IStudent _student;

        public IList<decimal> Grades
        {
            get
            {
                return _student.Grades;
            }
            set
            {
                _student.Grades = value;
            }
        }

        public int StudentNumber
        {
            get
            {
                return _student.StudentNumber;
            }
        }

        public decimal CalculateGPA() => _student.CalculateGPA();

        public TeachingAssistant(string FirstName, string LastName, DateTime Birthdate) : base(FirstName, LastName, Birthdate)
        {
            this._student = new StudentLogic();
        }
    }

    public static void Main(string[] args)
    {
        var p1 = new Person("John", "Smith", new DateTime(1984, 1, 31));
        var s1 = new Student("Jane", "Smith", new DateTime(1984, 08, 22));
        var t1 = new TeachingAssistant("Jane", "Smith", new DateTime(1984, 08, 22));
    }
}


one thing to note is rather than tightly coupling the implementation of IStudent by instantiating the 'StudentLogic' class within the 'Student' and 'TeachingAssistant' classes, we could pass an implementation of 'StudentLogic' to the classes in their constructors, and thus loosely coupling the implementation of IStudent to the classes that leverage. This loose coupling approach is called Inversion of control which we'll discuss in a future post.

Thursday, 1 October 2015

Interface

An interface defines a schema for a class to implement. It defines methods, properties, and events that a class must have, but does not provide an implementation for them. Interfaces can be used to define a common set of functionality that multiple classes can share, and to create loosely-coupled code. A class that implements an interface must provide an implementation for all of the members defined in the interface. Interfaces can also be inherited by other interfaces, allowing for a hierarchy of interfaces to be created.

For example we can define what properties and functions a student should have.


    interface IStudent
    {
        int StudentNumber { get; }
        IList<decimal> Grades {get; set;}
        decimal CalculateGPA();
    }


The above interface represents a student, notice that it's name starts with an I for IStudent, this is an accepted practice in c#. As you can see there is no implementation for any of its' members, just a definition. Now let's say we have a person class.


    class Person
    {
        private string _firstName;
        public string FirstName
        {
            get { return _firstName; }
            set
            {
                _firstName = CheckName(value);
            }
        }

        private string _lastName;
        public string LastName
        {
            get { return _lastName; }
            set { _lastName = CheckName(value); }
        }

        private string CheckName(string value)
        {
            if (Regex.IsMatch(value, @"^[a-zA-Z]{2,}$"))
                return value;
            throw new FormatException($"{value} is not a valid name");
        }

        public Person() {
            this._firstName = "";
            this._lastName = "";
         }

        public Person(string FirstName, string LastName) : this()
        {
            try
            {
                this.FirstName = FirstName;
                this.LastName = LastName;
            }
            catch (Exception ex)
            {
                throw new FormatException("A custom person exception", ex);
            }
        }
    }
   

we can use a combination of the person class and the IStudnet interface to create a student class.


    class Student : Person, IStudent
    {
        static int RunntingStudentNumber = 0;
        public IList<decimal> Grades { get; set; }
        public int StudentNumber { get; private set; } = RunntingStudentNumber++;

        public Student()
        {
            this.Grades = new List<decimal>();
        }

        public decimal CalculateGPA()
        {
            decimal total = 0;
            foreach (var g in Grades)
                total += g;
            return total / Grades.Count;
        }
    }


now  you may be wondering why did we bother with the interface, well there's multiple benefits from leveraging interfaces, we leveraged the IStudent interface this time because of the first point which we'll talk about further in Faking inheritance.
  • Multiple Inheritance: C# doesn't allow you to inherit from multiple classes but it does let you implement multiple interfaces allowing us to sort of fake it.
  • Interface Based programming: Interface based programming allows us to separate our class implementation from the declaration. This can facilitate that different classes have the same interactive members allowing us to swap one class for another.
  • Inversion of control: is an established pattern, that is facilitated by Interface based declarations, it basically states that if a class needs to do anything other then its main function we should provide that function to the class.
The primary benefit of using interfaces is that they allow for loose coupling of code. Because an interface defines a contract for a class to implement, rather than providing an implementation itself, different classes can implement the same interface in different ways. This allows for more flexibility and reusable code, as a single interface can be implemented by multiple classes, each providing its own unique implementation, and then these classes can be swapped for one another without having to rewrite any code in their consumers.

Additionally, interfaces can be used to create more maintainable and testable code, as they encourage the separation of concerns. Interfaces allow you to define a specific set of functionality that a class must have, without worrying about how that functionality is implemented. This allows for easier modification of individual classes without affecting the rest of the system.



In short interfaces are not class definitions, they can be used to define what to expect, you can think of the interface as building plans, and the building as the actual class.