Properly Refactoring to avoid a Circular Dependency

394 views Asked by At

I am having a problem with a circular dependency. Similar question have been asked and I have read a lot of answers. Most deal with a work-around but I would like to refactor so what I have it correct and I would like some input on where I have gone wrong. I can change what I am doing but not the entire project architecture.

I am using VB.Net in Visual Studio 2012.

I have two class libraries:

  1. DataLayer for accessing the database.
  2. DataObject which contains classes that represents my business objects.

My Presentation Layer calls methods in the DataLayer which returns objects from the DataObject class library.
(I have simplified somewhat – I actually have a controller layer but it needs references to the two class libraries above. This is an existing architecture that is from before my time.)

In the DataObject class library I have an abstract class that represents a file. It has properties such as filename, userID, etc. It also has a method, GetFile(), that I code in the derived classes because there are different ways of getting the file. A DataLayer method returns a collection of these file objects, but I don't want to get the actual file until it's needed.


So far, I have a derived class that calls a webService (using properties from the baseClass) and a derived class that accesses the fileSystem. Both return a byte array representing the file. The calling class does not need to know how the file is retrieved.

Now I have a new requirement to build the file on the fly using data from the database. I can get all the data I need using the properties in the base class.

My issue is that my GetFile() method will need to access my DataLayer class library to pull data from the database which causes a circular dependency. The DataLayer class library has a reference to DataObject since that is what it returns. But now I need to call the DataLayer from a class in DataObjects.

  • I could call the DataLayer from presentation and pass the result to my DataObject’s GetFile() method, but then my presentation layer needs to do something special for this derived class. My goal is that the derived class handles GetFile without presentation knowing about the implementation.
  • I could create a new class library for this DataLayer code but I don't like a special case.
  • I could access the DB directly in the DataObject class but that circumvents the layered architecture.

I can’t change our architecture, but I can change my approach.

Any opinions?

1

There are 1 answers

0
Don Chambers On

I think I have the answer.

In my concrete class, when I am loading the data initially (in the DataLayer), I will get all the data I need to create the file. I'll store it in a new property in my concrete class which my GetFile() method will use to build the file.

This has a little more overhead - I make DB calls and put all this data in memory when it may not be needed. I'll give it a try and see how performance is.

Any critiques of this approach?