Assembly Loader Error

System.IO.FileLoadException: Could not load file or assembly ‘NLog, Version=2.1.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c’ or one of its dependencies. The located assembly’s manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Jika suatu saat anda mendapat error seperti di atas, artinya assembly loader tidak menemukan assembly yang di reference. Ternyata untuk kasus saya, di app.config ternyata mereference assembly version yang berbeda.

<dependentAssembly>
    <assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
 </dependentAssembly>

Ada 2 cara untuk menyelesaikan issue ini.

  1. hapus configurasi tersebut di app.config
  2. Kita paksa untuk semua version tertentu dalam kasus ini versi .4.0.0.0 di redirect ke version 2.1.0.0.
<dependentAssembly>
     <assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" />
     <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="2.1.0.0" />
</dependentAssembly>

 

Mocking Unit Test Object Menggunakan NSubtitute

NSubtitute

http://nsubstitute.github.io/

Nsubtitute adalah salah satu mocking library untuk .NET yang memiliki configurasi yang sederhana sehingga mudah digunakan. NSubtitute di design untuk testing dengan pendekatan Arrange-Act-Assert (AAA), sehingga kita hanya butuh untuk mengatur bagaimana harusnya dia bekerja dan kemudian membuat pemanggilan Assertion.

Kita bisa menginstall NSubtitute lewat Packet Manager Console pada Visual Studio.

install-nsubtitute.png

Sebagai contoh kita akan membuat abstraksi operasi pada Calculator menggunakan interface.

public interface ICalculator
{
   int Add(int number1, int number2);
}

Kemudian kita mempunyai sebuah class yang menyediakan service untuk menampilkan hasil kalkulasi tersebut. Prinsip dasar unit test adalah melakukan test pada unit terkecil dari kode program kita dan mengisolasi extenal class yang ada.

Karena kita akan membuat unit test untuk class CalculatorService, sehingga external class berupa class implentasi dari ICalculator kita buatkan mockup nya saja.

public class CalculatorService
   {
       private ICalculator _calculator;
       public CalculatorService(ICalculator calculator)
       {
           _calculator = calculator;
       }
       public int Add(int number1, int number2)
       {
           if (number2 == 0)
           {
               throw new Exception("Dived by Zero Exception, please input number2 != 0");
           }
           var result = _calculator.Add(number1, number2);
           return result;
       }
   }

Setiap class Unit Test haruslah ditandai dengan attribute [TestClass] dan Unit Test Method dengan attribute [TestMethod].

[TestClass]
public class CalculatorServiceTest
{
    [TestMethod]
    public void Add_ReturnValidResult()
    {
    }
}

Jika kita menginginkan suatu proses tertentu yang harus dilakukan sebelum unit test method dijalankan seperti proses inisialisasi data, kita bisa membuat method dengan attribute [TestInitialize] dan sebalikanya jika kita menginginkan sebuah proses yang dieksekusi setiap sebuah unit test method di jalankan kita bisa membuta method dengan attribute [TestCleanup].

[TestInitialize]
public void Setup()
{

}
[TestCleanup]
public void Cleanup()
{
}

Jika Kita melakukan test terhadap expection yang mungkin ada, tambahkan attribute [ExpectedException].

[TestMethod]
[ExpectedException(typeof(Exception))]
public void Add_WhenNumber2IsZeroReturnException()
{
}

Untuk melakukan mockup object, cukup dengan menulis kode seperti ini. Usahakan implementasi yang kita buat selalu berawal dari abstraksi sehingga memudahkan menulis kode mockup objectnya.
csharp _calculator = Substitute.For();

Selanjutnya kita akan memockup method Add pada ICalculator seperti ini.
csharp _calculator.Add(1, 2).Returns(3);

Bentuk class unit test selengkapnya sepert ini.

[TestClass]
    public class CalculatorServiceTest
    {
        private ICalculator _calculator;
        private CalculatorService _calculatorService;

        [TestInitialize]
        public void Setup()
        {
            _calculator = Substitute.For<ICalculator>();
            _calculatorService = new CalculatorService(_calculator);
        }
        [TestCleanup]
        public void Cleanup()
        {
            _calculator = null;
            _calculatorService = null;
        }

        [TestMethod]
        public void Add_ReturnValidResult()
        {
            var expectedResult = 3;
            ///arrange
            _calculator.Add(1, 2).Returns(expectedResult);
            ///act
            var actualResult = _calculatorService.Add(1, 2);
            ///assert
            Assert.AreEqual(expectedResult, actualResult);
        }
        [TestMethod]
        [ExpectedException(typeof(Exception))]
        public void Add_WhenNumber2IsZeroReturnException()
        {
            try
            {
                _calculatorService.Add(1, 0);
                Assert.Fail();
            }
            catch(Exception ex)
            {
                Assert.IsInstanceOfType(ex, typeof(Exception));
                Assert.AreEqual("Dived by Zero Exception, please input number2 != 0", ex.Message);
                throw ex;

            }
           
        }
    }

 

Mari kita jalankan class unit test kita.

pass-unit-test

Query menggunakan kondisi selisih DateTime pada Entity Framework

Tidak semua query pada Linq di support oleh Entity Framework, termasuk pengurangan 2 nilai datetime.

public List<Price> GetExpiredPrice()
{
   return _priceRepo.Get(x=>x.EndDate.Value.Subtract(DateTime.Now).Days == Core.Constants.PriceReminderDays).ToList();
}

Query di atas akan menghasilkan error

cannot be converted to SQL.

Gunakan DbFunctions dari  assembly System.Data.Entity

public List<Price> GetExpiredPrice()
{
    return _priceRepo.Get(x=>DbFunctions.DiffDays(DateTime.Now, x.EndDate) == Core.Constants.PriceReminderDays).ToList();
}

 

 

Perbedaan Asosiasi, Agregasi dan Komposisi pada Object Oriented Programming

Ketika kita membaca atau membuat diagram class UML, kita tidak pernah lepas dari relasi antar class. Seringkali membingungkan adalah bagaimana implementasi relasi tersebut dalam bentuk kode program.

Ada beberapa teknik yang digunakan jika berbicara mengenai relasi antar class yaitu:

Assosiation (Assosiasi)

Assosiasi adalah hubungan antara object. Relasi assosiasi biasa disebut is “a” relationship. Assosiasi berarti bahwa sebuah object “menggunakan” object yang lain. Assosiasi adalah sebuah relasi dimana semua object memiliki lifecycle nya sendiri dan tidak ada yang bertindak sebagai owner.

Contoh Teacher dan Student. Banyak Student dapat berasosiasi dengan satu Teacher dan satu Student   dapat berasosiasi dengan banyak Teacher. Object keduanya bisa dibuat dan dihancurkan secara mandiri tanpa berpengaruh pada eksistensi object lain.

Aggregation (Agregasi)

Agregasi adalah bentuk hubungan yang lebih khusus dari Assosiasi dimana sebuah object memiliki lifecycle nya sendiri tapi dengan kepemilikan dan class child tidak dapat memiliki class parentnya. Relasinya biasa di sebut relasi “has-a”.

Sebagai contoh, Department dan Teacher. Satu Teacher tidak dapat memiliki banyak Department, tapi jika kita menghapus object Department, object Teacher tidak akan ikut terhapus. Contoh:

public class Department
    {
        private string _name;

        public Department(string name)
        {
            _name = name;
            _teachers = new List<Teacher>();
        }
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        public List<Teacher> _teachers;
    }

 

public class Teacher
    {
        private string _name;
        public Teacher(string name)
        {
            _name = name;
        }
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
    }

 

public class ClientTester
    {
        public void AggregationTest()
        {
            var department = new Department("Electrical Engineering");

            var teacher1 = new Teacher("Teacher 1");
            var teacher2 = new Teacher("Teacher 2");

            department._teachers.Add(teacher1);
            department._teachers.Add(teacher2);

        }
    }

Karena object teacher di buat di luar object department, sehingga jika object department dihancurkan maka object teacher tetap exist. Object department bisa memiliki banyak object teacher yang berasosiasi dengannya, tapi tidak sebaliknya. Sehingga dalam relasi ini object department adalah owner dari object teacher.

Relasi Agregasi disebut juga Weak Assosiation dan dalam UML disimbolkan seperti ini

agregasi

 

Composition (Komposisi)

Komposisi sama dengan relasi Agregasi, tapi lebih spesfic lagi yaitu lifecycle object bergantung pada object ownernya.

public class University
    {
        private string _name;
        private List<Department> _departments;
        public University(string name)
        {
            _name = name;
        }

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        private void GenerateDepartment()
        {
            var electricalDepartment = new Department("Electrical Engineering");
            var biologyDepartment = new Department("Biology");
            _departments = new List<Department>
                {
                    electricalDepartment,
                    biologyDepartment
                };

        }
    }

 

public class ClientTester
{
  public void CompositionTest()
  {
      var university = new University("Diponegoro University");

   }

 }

Pada contoh ini class University bertindak sebagai object owner seperti pada relasi Agregasi di atas. Karena object electricalDepartment dan biologyDepartment di buat di dalam object univerty sehingga jika object university dihancurkan, maka object electricalDepartment dan biologyDepartment akan tidak exist lagi. Relasi Komposisi disebut juga Strong Association atau Death Relationship dan disimbolkan dalam UML seperti ini

komposisi

 

 

 

Sarung

Menurut catatan sejarah, sarung berasal dari Yaman. Di negeri itu sarung biasa disebut futah. Sarung juga dikenal dengan nama izaar, wazaar atau ma’awis.Masyarakat di negara Oman menyebut sarung dengan nama wizaar. Orang Arab Saudi mengenalnya dengan nama izaar.

Penggunaan sarung telah meluas, tak hanya di Semenanjung Arab, namun juga mencapai Asia Selatan, Asia Tenggara, Afrika, hingga Amerika dan Eropa. Sarung pertama kali masuk ke Indonesia pada abad ke 14, dibawa oleh para saudagar Arab dan Gujarat. Dalam perkembangan berikutnya, sarung di Indonesia identik dengan kebudayaan Islam.

Saya sangat suka menggunakan sarung, kain yang mampu menghangatkan dari udara dingin tapi tidak bikin gerah dikala panas.

Di kampung saya di Mandar sana kami punya banyak stok sarung untuk  bermacam keperluan. Sejak kami lahir kami sudah dibungkus pakai sarung, ayunan bayi pun menggunakan sarung. Mandi sebagai pengganti handuk, kami pakai menggunakan sarung walaupun jadinya lebih lama kering di banding handuk. Apalagi buat tidur, ampuh untuk melindungi dari nyamuk dan dinginnya malam.  Ke masjid tak afdhol kalau tidak pakai sarung. Ke acara yang formal seperti ke kondangan pun pakai sarung. Bahkan orang meninggal dialasi sarung sembari didoakan oleh orang yang datang melayat.

Diterbitkan di Life

Interface, penting tapi sering diabaikan

Beberapa kali saya melakukan interview untuk kandidat programmer di kantor, seringkali untuk pertanyaan paling dasar mengenai Object Oriented Progamming adalah pertanyaan apa itu Interface? sebagian candidat biasanya menjawab pernah menggunakan tapi tidak bisa mengungkapkan dalam secara verbal. Bahkan ada yang menjawab bahwa itu adalah antarmuka (hmm, mungkin dikiranya User Interface).

Walaupun ada teman yang menganalogikan interface adalah template, tapi bagi saya analogi interface yang paling mendekati adalah bahwa interface itu semacam contract yang mengikat semua child class (semua class yang mengimplementasikan interface tersebut).

Di dalam sebuah interface bisa jadi berisi sekumpulan method dan property. Ingat, sebuah interface tidak bisa memiliki implementasi di dalamnya, berbeda dengan abstract class. Dengan menggunakan interface, memudahkan kita membuat mockup object dalam unit test misalnya. Terutama jika kita menggunakan IoC container. Interface ini adalah salah satu feature dalam OOP yang digunakan untuk prinsip polymorphisme.

Contoh:

interface IFlyObject
        {
            void Fly();
        }

Selanjutnya kita buat class Bird dan Plane yang akan mengimplementasi IFlyObject.

interface

Akan ada muncul compiler error jika interface member dari IFlyObject yaitu Fly() tidak di implementasikan. Mari kita modifikasi class di atas.

public class Bird : IFlyingObject
        {
            public void Fly()
            {
                Console.WriteLine("Terbang dengan Sayap Bulu");
            }
        }

        public class Plane : IFlyingObject
        {
            public void Fly()
            {
                Console.WriteLine("Terbang dengan mesin jet");
            }
        }

Salah satu prinsip OOP adalah Polymorphisme. Polymorphisme artinya kita memproses object-object yang berbeda berdasarkan tipe datanya. Dengan kata lain sebuah method yang memiliki implementasi berbeda-beda, implementasinya dapat dipilih saat runtime bergantung pada kondisi tertentu. Dari Polymorphisme kita mendapatkan keuntungan berupa flexsibilitas dalam memilih class implementasi.

static void Main(string[] args)
        {
            Console.Write("Pilih (A) Bird (B) Plane : ");
            var input = Console.ReadLine();
            IFlyingObject flyObject;
            if (input.ToUpper() == "A")
            {
                flyObject = new Bird();

            }
            else if (input.ToUpper() == "B")
            {
                flyObject = new Plane();

            }
            else
            {
                throw new Exception("Pilih A atau B");
            }
            flyObject.Fly();
            Console.ReadKey();
        }

Lebih jelas penggunaanya nanti kita akan bahas pada tulisan mengenai SOLID Pattern

Generic Repository Entity Framework Part II

lanjutan dari Generic Repository Entity Framework Part I

Unit Of Work

Unit Of Work memastikan bahwa banyak repository hanya akan menshare satu database contex yang sama sehingga membuat transaksi menjadi atomic. Artinya jika satu gagal, semuanya gagal untuk menjaga konsistensi data.

Seperti biasa, kita buat interfacenya dulu.

public interface IUnitOfWork : IDisposable
     {
         IGenericRepository GetGenericRepository()
           where T : class;

         void SaveChanges();
     }

Kemudian kita membuat konkrit classnya.

public class EFUnitOfWork : IUnitOfWork
     {
         private BookStoreEntities _context = new BookStoreEntities();
         private bool _disposed;



         /// <summary>
         /// Gets the generic repository.
         /// </summary>
         /// <typeparam name="T"></typeparam>
         /// <returns></returns>
         public IGenericRepository<T> GetGenericRepository<T>() where T : class
         {
             return new EFGenericRepository<T>(_context);
         }


         /// <summary>
         /// Saves the changes.
         /// </summary>
         public void SaveChanges()
         {
             try
             {
                 _context.SaveChanges();
             }
             catch (DbEntityValidationException e)
             {
                 throw;
             }
         }

         /// <summary>
         /// Releases unmanaged and - optionally - managed resources.
         /// the dispose method is called automatically by the injector depending on the lifestyle
         /// </summary>
         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
         protected virtual void Dispose(bool disposing)
         {
             if (!this._disposed)
             {
                 if (disposing)
                 {
                     _context.Dispose();
                 }
             }
             this._disposed = true;
         }

         public void Dispose()
         {
             Dispose(true);
             GC.SuppressFinalize(this);
         }
     }

 

Nantinya kita akan membuat instance dari Generic Repository di atas dengan melewatkan class entities sebagai paramater dan menggunakan method GetGenericRepository

public class BookBLL : IBookBLL
        {
            private readonly IUnitOfWork _unitOfWork;
            private readonly IGenericRepository _bookRepo;
            public BookBLL(IUnitOfWork unitOfWork)
            {
                _unitOfWork = unitOfWork;
                _bookRepo = _unitOfWork.GetGenericRepository();
            }

Generic Repository Entity Framework Part I

Generic mengacau pada teknik menulis kode untuk sebuah class tanpa menentukan tipe datanya. Dengan menggunakan Generic class kita tidak perlu menulis implementasi repository untuk semua class yang ada. Intinya adalah memaksimalkan code reuse.

C# juga menyediakan feature pada generic untuk membatasi tipe apa saja yang bisa menjadi parameter class, sebagai contoh parameter T pada interface IGenericRepository dibatasi pada tipe class saja.

Pertama kita akan buat interface, ya usahakan selalu membuat abstraksi sebelum membuat implementasi class untuk memudahkan unit test dan mengurangi tingkat depency antar class.

public interface IGenericRepository where TEntity : class
        {
            IEnumerable Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable, System.Linq.IOrderedQueryable> orderBy = null, string includeProperties = "");

            TEntity GetById(object id);

            TEntity GetById(params object[] keyValues);

            void Insert(TEntity entity);

            void Update(TEntity entityToUpdate);

            void InsertOrUpdate(TEntity entity);

            void Delete(object id);

            void Delete(TEntity entityToDelete);

            bool Exists(TEntity entity);

            long Count(Expression<Func<TEntity, bool>> filter = null);
        }

Selanjutnya kita buat class konkrit untuk implentasi dari IGenericRepository ini. Kita menggunakan Entity Framework. Jika kita menggunakan provider lain buat implementasi yang berbeda.

public class EFGenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
     {
         internal BookStoreEntities Context;
         internal DbSet<TEntity> Entities;

         public EFGenericRepository(BookStoreEntities dbContext)
         {
             Context = dbContext;
             Entities = dbContext.Set<TEntity>();
         }

         /// <summary>
         /// Gets the specified filter.
         /// </summary>
         /// <param name="filter">The filter.</param>
         /// <param name="orderBy">The order by.</param>
         /// <param name="includeProperties">The include properties.</param>
         /// <returns></returns>
         public IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "")
         {
             IQueryable<TEntity> query = Entities;

             if (filter != null)
             {
                 query = query.Where(filter);
             }

             foreach (var includeProperty in includeProperties.Split
                 (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
             {
                 query = query.Include(includeProperty);
             }

             if (orderBy != null)
             {
                 return orderBy(query).ToList();
             }

             return query.ToList();
         }

         /// <summary>
         /// Get entity the by identifier.
         /// </summary>
         /// <param name="id">The identifier.</param>
         /// <returns></returns>
         public TEntity GetById(object id)
         {
             return Entities.Find(id);
         }

         /// <summary>
         /// Get entity by identifiers.
         /// </summary>
         /// <param name="keyValues">The key values.</param>
         /// <returns></returns>
         public TEntity GetById(params object[] keyValues)
         {
             return Entities.Find(keyValues);
         }

         /// <summary>
         /// Inserts the specified entity.
         /// </summary>
         /// <param name="entity">The entity.</param>
         public void Insert(TEntity entity)
         {
             Entities.Add(entity);
         }

         /// <summary>
         /// Updates the specified entity.
         /// </summary>
         /// <param name="entityToUpdate">The entity to update.</param>
         public void Update(TEntity entityToUpdate)
         {
             Context.Entry(entityToUpdate).State = EntityState.Modified;
         }

         /// <summary>
         /// Inserts the entity if not exist or update the entity if exist.
         /// </summary>
         /// <param name="entity">The entity.</param>
         public void InsertOrUpdate(TEntity entity)
         {
             if (!Exists(entity))
                 Insert(entity);
             else
                 Update(entity);
         }

         /// <summary>
         /// Deletes entity by identifier.
         /// </summary>
         /// <param name="id">The identifier.</param>
         public void Delete(object id)
         {
             var entityToDelete = Entities.Find(id);
             Entities.Remove(entityToDelete);
         }

         /// <summary>
         /// Deletes the specified entity.
         /// </summary>
         /// <param name="entityToDelete">The entity to delete.</param>
         public void Delete(TEntity entityToDelete)
         {
             if (Context.Entry(entityToDelete).State == EntityState.Detached)
             {
                 Entities.Attach(entityToDelete);
             }
             Entities.Remove(entityToDelete);
         }

         /// <summary>
         /// Check if the entity exist.
         /// </summary>
         /// <param name="entity">The entity.</param>
         /// <returns></returns>
         public bool Exists(TEntity entity)
         {
             var objContext = ((IObjectContextAdapter)Context).ObjectContext;
             var objSet = objContext.CreateObjectSet<TEntity>();
             var entityKey = objContext.CreateEntityKey(objSet.EntitySet.Name, entity);

             Object foundEntity;
             var exists = objContext.TryGetObjectByKey(entityKey, out foundEntity);
             return (exists);
         }

         /// <summary>
         /// Counts the specified filter.
         /// </summary>
         /// <param name="filter">The filter.</param>
         /// <returns></returns>
         public long Count(Expression<Func<TEntity, bool>> filter = null)
         {
             IQueryable<TEntity> query = Entities;

             if (filter != null)
             {
                 query = query.Where(filter);
             }
             return query.Count();
         }
     }

 

Untuk jaminan proses transaksi database atomic (satu gagal, gagal semua). Kita akan membuat class UnitOfWork yang bertanggung jawab menangani proses transaksi di tulisan yang lain.

Func dan Expression C#

Perhatikan senarai kode program di bawah ini.

Expression<Func<TEntity, bool>> filter

Func adalah sebuah generic delegate – delegate adalah method yang di lewatkan sebagai parameter dalam  method yang lain. Func tersebut memiliki parameter TEntity dan nilai kembali bertipe bool.  Contoh:

func

Sedangkan Expression<Func> menghasilkan tree data struktur untuk lamba expression. Karena kembalian Func adalah bool, kita bisa gunakan expression tersebut sebagai Lamba Expression pada Linq .Where

exp

Clean Code – Function Part II

Kondisi

Sebuah fungsi bisa jadi memiliki banyak pengecekan kondisi di dalamnya. Kita bisa memastikan bahwa tiap kondisi dilakukan pada low-level class yaitu dengan menggunakan polymorphisme dan inheritance.

public abstract class Employee
        {
            public double BasicSalary;
            public abstract double CalculatePayment();
        }

Dari potongan kode program di atas, semakin banyak tipe customer dan semakin kompleks kalkulasi payment tiap tipe customer, akan semakin panjang kode program pada fungsi CalculatePay() sehingga melanggar prinsip bahwa sebuah fungsi haruslah kecil. Mari kita refactor menjadi beberapa implementasi pada low-level class seperti ini.

Kita bisa menggunakan interface ataupun class abstract. Selanjutnya kita buat 2 konkrit class yaitu class Sales dan Manager, masing-masing mengimplementasikan operasi CalculatePay() secara berbeda.

public class Sales : Employee
       {
           private const double COMMISION_PERCENTAGE = 0.2;

           public override double CalculatePayment()
           {
               return BasicSalary + (COMMISION_PERCENTAGE * BasicSalary);
           }
       }

       public class Manager : Employee
       {

           private const double BONUS_PERCENTAGE = 0.5;

           public override double CalculatePayment()
           {
               return BasicSalary + (BONUS_PERCENTAGE * BasicSalary);
           }
       }

Untuk menentukan class mana yang sesuai, kita bisa menggunakan Factory Pattern. Melalui Factory Pattern sebuah kelas mendelagasikan tanggung jawab pembuatan objectnya.

public class EmployeeFactory
        {
            public Employee MakeEmployee(EmployeeType employeeType)
            {
                switch (employeeType)
                {
                    case EmployeeType.Sales:
                        return new Sales();
                    case EmployeeType.Manager:
                        return new Manager();
                    default:
                        throw new Exception("Incorrect Employee");
                }
            }
        }

Bentuk akhir dari class PayrollService jadinya seperti ini.

public class PayrollService
        {
            private Employee _employee;
            public PayrollService(EmployeeType employeeType)
            {
                _employee = new EmployeeFactory().MakeEmployee(employeeType);
            }
            public double GetEmployeeSalary(double basicSalary)
            {
                _employee.BasicSalary = basicSalary;
                return _employee.CalculatePayment();
            }
        }