gpt4 book ai didi

c# - 这是控制反转的例子吗?

转载 作者:太空狗 更新时间:2023-10-30 00:59:22 24 4
gpt4 key购买 nike

我刚读完 James Kovac 的 article on Inversion of Control and Dependency Injection然后使用我学到的知识在下面制作我自己的 IoC/DI 示例。

我对这个例子很满意,因为它:

  • 满足 IoC 的可测试性 方面,因为它通过同时传递 Repository 和 MockRepository 来实例化 Customers
  • 授权服务也是分离的,这样您就可以编写另一个具有不同规则的授权服务,然后您可以根据其他条件轻松地将它们替换掉

然而,从这里往前看,有些事情似乎很奇怪:

  • 我好像没有“容器”。从这个意义上说,我的 Customer 类是否“充当容器”?
  • 如果我要将其移植到 WPF,模块(就 Prism 而言)将适合此示例的什么位置(例如,AuthorizationService 和 Repository 将是模块吗?)
  • 如果我要将其移植到 WPF,MVVM 适合什么地方?是否通过依赖注入(inject)拥有 MVVM 的一部分,或者 MVVM 是完全独立的东西。

感谢您就此提供的任何指导。

基于注释的新代码:

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 对象并将其返回给调用者。

我希望得到更像的东西:

Customer customer = repository.GetCustomer(3);

关于c# - 这是控制反转的例子吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/615641/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com