最初的警告: :长篇文章,我可能还是完全错误的:

给定以下课程,这是客户汇总的开始:

public class Customer : KeyedObject
{

   public Customer(int customerId)
   {
      _customerRepository.Load(this);
   }

   private ICustomerRepository _customerRepository = IoC.Resolve(..);  
   private ICustomerTypeRepository = _customerTypeRepository = IoC.Resolve(..);

   public virtual string CustomerName {get;set;}
   public virtual int CustomerTypeId [get;set;}

   public virtual string CustomerType
   {
      get
      {
         return _customerTypeRepository.Get(CustomerTypeId);
      }
   }

}

自定义类型由一个值对象表示:

public class CustomerType : ValueObject
{
   public virtual int CustomerTypeId {get;set;}
   public virtual string Description {get;set;}
}

这一切都很好,非常适合当我拥有带有自定型的客户对象时。但是,当我想在我的MVC视图中填充一个下拉列表时,我正在为如何正确获取从iCustomertypeperpostory获取自定义类型值列表的概念。

ICustomerTypeRepository 很简单:

public interface ICustomerTypeRepository
{
   public CustomerType Get(int customerTypeId);
   public IEnumerable<CustomerType> GetList();
}

基本上,我想要的是能够打电话 ICustomerTypeRepository 从我的控制器中正确地,我认为最好将DAL(存储库)层与控制器分开。现在,我只是过度复杂化的事情吗?

这就是我的控制器当前的立场:

public class CustomerController : ControllerBase
{ 

    private ICustomerTypeRepository _customerTypeRepository = IoC.Resolve(..);

    public ActionResult Index()
    {
       Customer customer = new Customer(customerId); 
       IEnumerable<CustomerType> customerTypeList = 
          _customerTypeRepository.GetList();

       CustomerFormModel model = new CustomerFormModel(customer);
       model.AddCustomerTypes(customerTypeList );
    }
}

我似乎是错误的,因为我在控制器和客户中都有存储库。对我来说似乎合乎逻辑的是,自定义类型应该有一个分离的访问层。 IE CustomerType.GetList():

public class CustomerType : ValueObject
{
   // ... Previous Code

   private static ICustomerTypeRepository _customerTypeRepository = IoC.Resolve(..);

   public static IEnumerable<CustomerType> GetList()
   {
      _customerTypeRepository.GetList();
   }
}

所以,这就是我的方式 应该 公开 CustomerType 通过 ICustomerTypeRepositoryCustomerController?

有帮助吗?

解决方案

我认为这里有几件事要考虑。

首先,如果您真的有兴趣建模域名,那么您仍需要尝试使域实体本身不受跨切割问题的范围,例如验证,IOC容器和持久性,即使有主动的记录模式。

这意味着 Customer 即使您使用接口和服务定位器,也可能没有任何对存储库的引用。它应该设计为反映目标客户端/用户的角度来反映“客户”的属性或构成的属性。

除了域模型,我对您的使用有点关注 IoC 可变初始化器中的服务定位器。众所周知,您没有机会捕获构造函数的异常和例外的任何机会很难进行调试(这些初始化器在第一个非静态构造函数中的任何代码之前运行)。

使用静态网关/服务定位器代替注入依赖项,也可以使该类几乎无法测试(使用自动化的单元测试方法,也就是说 - 您可以进行集成和手动测试,但是测试失败不太可能指向损坏的测试失败比特很容易 - 与单位测试相反,您确切地知道要测试的一件事,因此什么是损坏的)。

而不是拥有 Customer 对象通过调用数据填充自身 _customerRepository.Load(this) 在构造函数中,应用程序通常会更通常使用存储库来获取实体,因此它从存储库完全填充,包括 CustomerType 财产。在这种情况下,看来这可能发生在 CustomerController.

您指出您希望与 CustomerController 居住,您有效地拥有 - 这是使用存储库接口进来的地方。您注入 一些 该接口的实现(或在这种情况下,从IOC实施中获取实现),但是该存储库的实际实现可以在单独的层中存在(甚至可以是另一个程序集)。这是一种称为分离界面的模式。

就我个人而言,我会重构定制器以这样的样子:

public class CustomerController : ControllerBase
{ 
     private ICustomerTypeRepository _customerTypeRepository;
     private ICustomerRepository _customerRepository;

     public CustomerController(ICustomerRepository customerRepository,
        ICustomerTypeRepository customerTypeRepository)
     {
        _customerRepository = customerRepository;
        _customerTypeRepository = customerTypeRepository;
     }

     public ActionResult Index()
     {
         Customer customer 
             = _customerRepository.GetCustomerWithId(customerId); 
             // from where does customerId come?

         IEnumerable<CustomerType> customerTypeList 
             = _customerTypeRepository.GetTypes();

        . . .

     }
}

…我会从中列出任何对存储库的所有参考 Customer 以及任何其他域实体类。

其他提示

如何更改客户域模型以包括自定义型的属性?这也将停止每次调用CustomErtype时都达到存储库的需求。

public class Customer : KeyedObject
{

   public Customer(int customerId)
   {
      _customerRepository.Load(this);

      ICustomerTypeRepository _customerTypeRepository = IoC.Resolve(..);
      _customerTypes = _customerTypeRepository.GetList();
   }

   private ICustomerRepository _customerRepository = IoC.Resolve(..);  

   public virtual string CustomerName {get;set;}
   public virtual int CustomerTypeId {get;set;}

   public virtual string CustomerType
   {
      get
      {
         return _customerTypes.Find(CustomerTypeId);
      }
   }

   private IEnumerable<CustomerType> _customerTypes;
   public virtual IEnumerable<CustomerType> CustomerTypes
   {
      get
      {
          return _customerTypes
      }
   }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top