I just finished James Kovac’s article “On Inversion of Control and Dependencies” and then used what I learned to make my IoC / DI example below.
I am quite satisfied with this example, since it:
- satisfies the IoC test aspect by creating client instances, passing both the repository and the MockRepository
- also the authorization service is disabled , which will allow you, for example. write another authorization service with different rules, and then you can easily replace them with other conditions.
However, looking at the progress from here, some things seem strange:
- I don't seem to have a "container" . Is my client class "acting as a container" in this sense?
- if I were to port this to WPF, where would the modules (in terms of Prism) fit into this example (for example, would AuthorizationService and Repository be modules?)
- if I were to port this to WPF , where will the MVVM match ? You have parts of MVVM with dependency injection or even MVVM in general.
Thanks for any direction you can provide on this.
NEW CODE BASED ON COMMENT:
using System; using System.Linq; using System.Collections.Generic; namespace TestSimpleDependencyInjection1 { class Program { static void Main(string[] args) { AuthorizationService authorizationService = new AuthorizationService(); //real example Repository repository = new Repository(authorizationService); for (int id = 1; id <= 3; id++) { Customer customer = repository.GetCustomer(id); customer.Display(); } Console.WriteLine(); //mock test example MockRepository mockRepository = new MockRepository(authorizationService); Customer mockCustomerAdministrator = repository.GetCustomer(1); Customer mockCustomerSalesperson = repository.GetCustomer(2); UnitTester.Assert("Administrators have access", mockCustomerAdministrator.GetAuthorizationMessage(), "Access Granted"); UnitTester.Assert("Salespeople do not have access", mockCustomerAdministrator.GetAuthorizationMessage(), "Access Granted"); Console.ReadLine(); } } public static class UnitTester { public static void Assert(string title, string value, string expectedResult) { Console.WriteLine(value == expectedResult ? String.Format("{0}: test succeeded", title) : String.Format("{0}: TEST FAILED!", title)); } } public class Customer { public int ID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public AccessGroup AccessGroup { get; set; } public AuthorizationService AuthorizationService { get; set; } public string GetAuthorizationMessage() { return this.AuthorizationService.GetAccessMessage(this); } public Customer() { } public void Display() { Console.WriteLine("Customer: {1}, {0} ({2}): {3}", this.FirstName, this.LastName, this.AccessGroup, this.GetAuthorizationMessage()); } } public class AuthorizationService { public string GetAccessMessage(Customer customer) { return customer.AccessGroup == AccessGroup.Administrator ? "Access Granted" : "Access Denied"; } } public class Repository : IRepository { private List<Customer> _customerSet = new List<Customer>(); private AuthorizationService _authorizationService; public Repository(AuthorizationService authorizationService) { _authorizationService = authorizationService; _customerSet.Add(new Customer {AuthorizationService = _authorizationService, ID = 1, FirstName = "Jim", LastName = "Smith", AccessGroup = AccessGroup.Administrator }); _customerSet.Add(new Customer {AuthorizationService = _authorizationService, ID = 2, FirstName = "John", LastName = "Johnson", AccessGroup = AccessGroup.Administrator }); _customerSet.Add(new Customer {AuthorizationService = _authorizationService, ID = 3, FirstName = "Hank", LastName = "Rivers", AccessGroup = AccessGroup.Salesperson }); } public Customer GetCustomer(int id) { return (from c in _customerSet where c.ID == id select c).SingleOrDefault(); } } public class MockRepository : IRepository { private List<Customer> _customerSet = new List<Customer>(); private AuthorizationService _authorizationService; public MockRepository(AuthorizationService authorizationService) { _authorizationService = authorizationService; _customerSet.Add(new Customer { AuthorizationService = _authorizationService, ID = 1, FirstName = "Test1AdministratorFirstName", LastName = "Test1AdministratorLastName", AccessGroup = AccessGroup.Administrator }); _customerSet.Add(new Customer { AuthorizationService = _authorizationService, ID = 2, FirstName = "Test2SalespersonFirstName", LastName = "Test2SalesPersonLastName", AccessGroup = AccessGroup.Salesperson }); } public Customer GetCustomer(int id) { return (from c in _customerSet where c.ID == id select c).SingleOrDefault(); } } public interface IRepository { Customer GetCustomer(int id); } public enum AccessGroup { Administrator, Salesperson } }
AND REQUEST, HERE ORIGINAL CODE:
using System; using System.Collections.Generic; namespace TestSimpleDependencyInjection1 { class Program { static void Main(string[] args) { AuthorizationService authorizationService = new AuthorizationService(); //real example Repository repository = new Repository(); for (int id = 1; id <= 3; id++) { Customer customer = new Customer(id, authorizationService, repository); customer.Display(); } Console.WriteLine(); //mock test example MockRepository mockRepository = new MockRepository(); Customer mockCustomerAdministrator = new Customer(1, authorizationService, mockRepository); Customer mockCustomerSalesperson = new Customer(2, authorizationService, mockRepository); UnitTester.Assert("Administrators have access", mockCustomerAdministrator.GetAuthorizationMessage(), "Access Granted"); UnitTester.Assert("Salespeople do not have access", mockCustomerAdministrator.GetAuthorizationMessage(), "Access Granted"); Console.ReadLine(); } } public static class UnitTester { public static void Assert(string title, string value, string expectedResult) { Console.WriteLine(value == expectedResult ? String.Format("{0}: test succeeded", title) : String.Format("{0}: TEST FAILED!", title)); } } public class Customer { private AuthorizationService authorizationService; private IRepository repository; public int ID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public AccessGroup AccessGroup { get; set; } public string GetAuthorizationMessage() { return authorizationService.GetAccessMessage(this); } public Customer(int id, AuthorizationService authorizationService, IRepository repository) { this.authorizationService = authorizationService; this.repository = repository; CustomerDB customerDB = repository.GetCustomerDB(id); this.ID = customerDB.ID; this.FirstName = customerDB.FirstName; this.LastName = customerDB.LastName; this.AccessGroup = customerDB.AccessGroup; } public void Display() { Console.WriteLine("Customer: {1}, {0} ({2}): {3}", this.FirstName, this.LastName, this.AccessGroup, this.GetAuthorizationMessage()); } } public class AuthorizationService { public string GetAccessMessage(Customer customer) { return customer.AccessGroup == AccessGroup.Administrator ? "Access Granted" : "Access Denied"; } } public class Repository : IRepository { private List<CustomerDB> _customerDBSet = new List<CustomerDB>(); public Repository() { _customerDBSet.Add(new CustomerDB { ID = 1, FirstName = "Jim", LastName = "Smith", AccessGroup = AccessGroup.Administrator }); _customerDBSet.Add(new CustomerDB { ID = 2, FirstName = "John", LastName = "Johnson", AccessGroup = AccessGroup.Administrator }); _customerDBSet.Add(new CustomerDB { ID = 3, FirstName = "Hank", LastName = "Rivers", AccessGroup = AccessGroup.Salesperson }); } public CustomerDB GetCustomerDB(int id) { CustomerDB customerDBchosen = null; //this should be done with LINQ (couldn't get it CustomerDB to implement IEnumerable correctly) foreach (CustomerDB customerDB in _customerDBSet) { if (customerDB.ID == id) { customerDBchosen = customerDB; break; } } return customerDBchosen; } } public class MockRepository : IRepository { public CustomerDB GetCustomerDB(int id) { switch (id) { case 1: return new CustomerDB { ID = 1, FirstName = "Test1AdministratorFirstName", LastName = "Test1AdministratorLastName", AccessGroup = AccessGroup.Administrator }; case 2: return new CustomerDB { ID = 2, FirstName = "Test2SalespersonFirstName", LastName = "Test2SalesPersonLastName", AccessGroup = AccessGroup.Salesperson }; default: return null; } } } public interface IRepository { CustomerDB GetCustomerDB(int id); } public class CustomerDB { public int ID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public AccessGroup AccessGroup { get; set; } } public enum AccessGroup { Administrator, Salesperson } }