I have a big project and I'm using the Model pattern for my objects, so I have something like this:
public class Test
{
public int TestID { get; set; }
public int StudentID { get; set; }
public Student Student { get; set; }
public IList<Result> Results { get; set; }
public bool StartTest()
{
//Logic and rules for starting a test here
}
public bool FinishTest()
{
//Save the results in the DB
}
}
When a student's about to start or finish a test, I have to consume a service depending on the city/state he's in, and apply some specific rules by city/state, if any.
public bool FinishTest()
{
switch(Address.City.Code)
{
case "TO": //My country's state codes
{
State_TO state = new State_TO();
bool status = state.AttemptFinishTest(this);
//Sending this Test class to the City/State object so it can fetch any information about this and/or set it's rules, if any.
//Check the return, proceed
}
}
}
//Somewhere else
public class State_TO
{
public bool AttemptFinishTest(Test testObject)
{
//external access
}
}
The problem starts here, I want to separate the main Test project and each state/city classes so it's like this:
//Solution Explorer
Project.Models //where the models/logic are
Project.State.TO //a state
Project.State.RO //another state
Project.State.SI //etc
This is because the states are still coming up and implementations are still on progress, and to separate the logic of each state from the models as it's much more likely the state rules to change than the model logic (our process shouldn't never change - how we save and manage tests) so we don't have to recompile the DLL whenever any state change.
This way, I hope to get a simple change in a state rule to simply recompile the state's DLL and deploy without changing anything else.
The circular dependency happens because I need to access the Models from the State code because I don't know what kind of information they'll require or operations they'll perform with the tests, and I need the Models to have a reference to the States so they can call the appropriate state code for a test.
One solution I was going to try is to create an interface for the Models, and have the States reference it:
Models Interface
/ \
Models---------->States
Then I could call from the Models:
public class Test : ITest
{
public bool FinishTest()
{
State state = GetState(Address.City.Code);
bool status = state.AttemptFinishTest(this);
}
}
//And in the State code
public class State_TO
{
public bool AttemptFinishTest(ITest testInterface);
{
//I can access everything through the interface
}
}
The problem of this solution is that the Models are really big and have a bunch of subclasses, such as Student/Instructor and these have their own subclasses (Addresses, Licenses, etc) and so on, meaning I'd need to create interfaces for the entire project and it'll come with the inconvenience to always change in both places, the Model and the Interface, whenever something changes.
Is there a better, more elegant solution than this? I only need to figure a way to call the proper State class (from an interface maybe), other than that, nothing else is required from the Models project. Is there any way I can do this?