这是一个例子反转的控制?
-
03-07-2019 - |
题
我只是完成了詹姆斯*科瓦奇的 条倒置的控制和依赖注射 然后用我学到了什么让我自己的IoC/DI例如下。
我相当或甚至更低与这个示例,因为它:
- 满足可测性 方案 委员会在它实例的客户通过的两个仓库和一个MockRepository
- 还的 授权服务隔离开 这会让你如写的另一个授权的服务有不同的规则,然后你可以很容易地交换它们根据其他条件
然而,寻找向前进,从这里,某些事情看起来很奇:
- 我似乎没有一个"容器".是我的客户类"作为一个集装箱"在这个意义上说?
- 如果我要这个端口,以WPF, 哪里会的模块(在条款的棱镜)适用这一例 (例如会AuthorizationService和存储库以模块?)
- 如果我要这个端口,以WPF, 在那里会适合。?做已经有部分。通过具有依赖注射或是。一些东西分开了。
谢谢你的任何方向可以提供这一点。
新代码的根据的评论:
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
}
}
解决方案
你的代码违反了单一责任主要在一个非常严重的方式。
http://en.wikipedia.org/wiki/Single_responsibility_principle
你的客户对象不应该载入本身从一个储存库,储存库应该载客户对象和交回者。
我希望更多的东西,如:
Customer customer = repository.GetCustomer(3);
其他提示
使用的开关声明在大多数情况下违反SRP。做 看看这个 为方式消除开发言,在你的代码。面临的挑战和美丽写的松散耦合代码,以消除的,如果,如果其他&关的发言。
不隶属于 StackOverflow