Reputation: 193282
I just finished James Kovac's article on Inversion of Control and Dependency Injection and then used what I learned to make my own IoC/DI example below.
I'm quite satisified with this example since it:
However, looking toward progressing from here, some things seem odd:
Thanks for any direction you can provide on this.
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
}
}
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
}
}
Upvotes: 4
Views: 1010
Reputation: 5641
usage of Switch statements in most cases violate SRP. Do check this out for ways to eliminate switch statements in your code. The challenge & beauty of writing loosely coupled code is to eliminate if, if else & switch statements.
Upvotes: 1
Reputation: 28312
Your code violates the single responsibility principal in a pretty serious way.
http://en.wikipedia.org/wiki/Single_responsibility_principle
Your Customer object shouldn't be loading itself from a repository, the repository should be loading the Customer object and handing it back to the caller.
I would expect something more like:
Customer customer = repository.GetCustomer(3);
Upvotes: 5