views:

540

answers:

4

Consider a normal customer-orders application based on MVC pattern using WinForms. The view part has grown too much (over 4000 files) and it needs to be split into smaller ones.


For this example we are going to use 3 projects for the view part:

  • Main - has dependencies to the other 2 projects. Instantiates the forms with the lists.
  • Customers - has 2 forms - customers list and customer details.
  • Orders - has 2 forms - orders list and order details.


On the customer details form there is also a list of orders for that customer. The list is received from the OrdersController so it's no problem getting it. When the user selects an order, the list will get it's guid and pass it as reference to the Order Details form.

This would mean that we need to have a reference to Orders Project in the Customers Project. (1)

But also on the order details form there is a link to the customer that made that order. When clicked, it should open the Customer Details form.

This would mean that we need to have a reference to Customers Project in the Orders Project. (2)

From (1) and (2) we'll have cyclic dependencies between the Orders and Customers projects.


How can this be avoided? Some kind of plug-in architecture? The project is already developed and the best solution would involve as little code change as possible.

+2  A: 

If they are that tightly coupled maybe they should not be split.

Leah
A: 

Extract interfaces and put them in separate assembly. Since you're using MVC architecture, it shouldn't be hard. Take a look at Microsoft Composite UI Applications block for examples and good practices.

aku
+3  A: 

Change at least one of the types to an interface.

For example have a ICustomer interface and a Customer type that implements this interface. Now add the ICustomer to the orders project and from the customers project set a reference to the Orders project so you can implement the interface. The Order type can now work against the ICustomer type without knowing the actual implementation.

And for a better solution :-) Create both an ICustomer and an IOrder interface and add them to a third library project. And reference this project from the other two and only work with the interfaces, never with the implemenation.

Maurice
How do you solve this: Orders need to instantiate Customers, Customers need to instantiate Orders?
Martin Haluza
A: 

I think that your main problem is not the architecture of your application. You need to understand the boundaries and how to divide the functionality among them. The division like yours is quite artificial, you try to split the application based on the domain objects. Try using user roles or functional themes do to that and the problem might go away.

From the technical point of view I don't understand why your views should be aware of each other existence - that sounds a little bit odd to me. You are not going to split your data and your business logic and at the end of the day a GUID is just a sting you could easily pass across using different methods.

Ilya Kochetov