简体   繁体   English

C#中的类设计结构

[英]Class designing structure in C#

Entity Class: 实体类:

public class Customer {
        public int CustomerId { get; set; }
        public string Name { get; set; }
}

public class Invoice {
        public int InvoiceId { get; set; }
        public int CustomerId { get; set; }
        public string InvoiceNo { get; set; }
}

Interface: 接口:

public interface ICustomerService {
    Customer GetCustomerById(int customerId);
    void DeleteCustomer(int customerId);
}

public interface IInvoiceService {
    Invoice GetInvoiceById(int invoiceId);
    void DeleteInvoice(int invoiceId);
    List<Invoice> GetAllInvoiceByCustomer(int customerId);
    Customer GetInvoiceCustomer(int invoiceId);
}

Class: 类:

public class CustomerService : ICustomerService {

    private readonly IInvoiceService _invoiceService = new InvoiceService();

    public Customer GetCustomerById(int customerId) {
        //return customer from db
        return new Customer();
    }

    public void DeleteCustomer(int customerId) {
        var invoiceList = _invoiceService.GetAllInvoiceByCustomer(customerId);
        foreach (var invoice in invoiceList) {
            _invoiceService.DeleteInvoice(invoice.InvoiceId);
        }

        //delete customer from db

    }
}

public class InvoiceService : IInvoiceService {

    private readonly ICustomerService _customerService = new CustomerService();

    public Invoice GetInvoiceById(int invoiceId) {
        //return invoice from db
        return new Invoice();
    }

    public void DeleteInvoice(int invoiceId) {
        //delete invoice from db
    }

    public List<Invoice> GetAllInvoiceByCustomer(int customerId) {
        //get all invoice by customer id
        return new List<Invoice>();
    }

    public Customer GetInvoiceCustomer(int invoiceId) {
        Invoice invoice = GetInvoiceById(invoiceId);
        return _customerService.GetCustomerById(invoice.CustomerId);
    }

}

When I create a new instance for "CustomerService". 当我为“CustomerService”创建一个新实例时。 It will return an error: 它将返回错误:

An unhandled exception of type 'System.StackOverflowException' occurred

Because when I create new instance for "CustomerService", "CustomerService" will create a new instance for "InvoiceService", "InvoiceServer" also create a new instance of "CustomerServer". 因为当我为“CustomerService”创建新实例时,“CustomerService”将为“InvoiceService”创建一个新实例,“InvoiceServer”也会创建一个“CustomerServer”的新实例。

1) Should I set all the methods to static? 1)我应该将所有方法设置为静态吗?

2) "InvoiceService" will have call methods from "CustomerService", and "CustomerService" will call methods from "InvoiceSercie" too. 2)“InvoiceService”将具有来自“CustomerService”的调用方法,而“CustomerService”也将调用来自“InvoiceSercie”的方法。 How can I write the classes? 我怎么写这些课程? If I set all the method to static, problem will be fixed, but I guess it is not a good solution. 如果我将所有方法设置为静态,问题将得到解决,但我想这不是一个好的解决方案。

Thank you very much! 非常感谢你!

You have to choose one of the classes to pass itself as a reference to the other. 您必须选择其中一个类作为对另一个的引用。 Let's say it's customer service: 让我们说它是客户服务:

public class CustomerService : ICustomerService {

  private readonly IInvoiceService _invoiceService = new InvoiceService(this);

  ...
}

public class InvoiceService : IInvoiceService {

  private readonly ICustomerService _customerService;

  public class InvoiceService(ICustomerService customerService) {
    _customerService = customerService;
  }

}

Now the cycle is broken... 现在循环被打破了......

Another option is to use a dependency injection framework, like StructureMap or Ninject. 另一个选择是使用依赖注入框架,如StructureMap或Ninject。

In general, I would recommend having less coupling between the classes. 一般来说,我建议在类之间减少耦合。 Each class should do one thing (Customer and Invoice) and then create a third class which uses both. 每个类应该做一件事(Customer和Invoice),然后创建一个使用两者的第三个类。 For example, you could create a class called "CustomerInvoicer" which takes the two interfaces in its constructor and move the method "GetInvoiceCustomer" to that new class. 例如,您可以创建一个名为“CustomerInvoicer”的类,该类在其构造函数中接受两个接口,并将方法“GetInvoiceCustomer”移动到该新类。 In my experience, that will make it a lot more maintainable in the long run, as each class has a single responsibility, and your ultimate consumer only needs to use the one main class (which may have more advanced logic). 根据我的经验,从长远来看,这将使其更易于维护,因为每个类都有一个责任,而您的最终消费者只需要使用一个主类(可能有更高级的逻辑)。

public class CustomerInvoicer {

    private readonly ICustomerService _customerService;
    private readonly IInvoiceService _invoiceService;

    public CustomerInvoicer(ICustomerService cust, IInvoiceService inv) {
        _invoiceService = inv;
        _customerService = cust;
    }


    public Customer GetInvoiceCustomer(int invoiceId) {
        Invoice invoice = _invoiceService.GetInvoiceById(invoiceId);
        return _customerService.GetCustomerById(invoice.CustomerId);
    }
}

Also, I would recommend using a Dependency Injection library with this approach. 此外,我建议使用这种方法的依赖注入库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM