如何在C#中解决这个循环依赖问题?

时间:2014-11-20 15:04:54

标签: c# circular-dependency

我有一个大项目,我正在为我的对象使用Model模式,所以我有这样的东西:

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            
    }
}

当学生即将开始或完成测试时,我必须根据他所在的城市/州来消费服务,并根据城市/州(如果有的话)应用一些特定的规则。

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
    }
}

问题从这里开始,我想将主要的测试项目和每个州/城市类分开,所以就像这样:

//Solution Explorer 
Project.Models //where the models/logic are
Project.State.TO //a state
Project.State.RO //another state
Project.State.SI //etc

这是因为状态仍然存在并且实现仍在进行中,并且将每个状态的逻辑与模型分开,因为状态规则更可能比模型逻辑更改(我们的过程不应该永远不会改变 - 我们如何保存和管理测试)所以我们不必在任何状态改变时重新编译DLL。

这样,我希望在状态规则中进行简单的更改,只需重新编译状态的DLL并在不改变任何其他内容的情况下进行部署。

循环依赖发生是因为我需要从状态代码访问模型,因为我不知道他们需要什么样的信息或他们将对测试执行的操作,我需要模型有一个引用各州,以便他们可以调用适当的州代码进行测试。

我要尝试的一个解决方案是为模型创建一个接口,让各州引用它:

   Models Interface
    /            \
Models---------->States

然后我可以从模特打来电话:

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
    }
}

这个解决方案的问题是模型非常大并且有一堆子类,例如Student / Instructor,这些子类有自己的子类(地址,许可证等),等等,这意味着我需要为整个项目创建接口,无论何时发生变化,它都会带来不便在两个地方(模型和接口)发生变化的不便。

有比这更好,更优雅的解决方案吗? 我只想找到一种方法来调用正确的State类(可能来自一个接口),除此之外,Models项目不需要任何其他东西。我有什么方法可以做到这一点吗?

2 个答案:

答案 0 :(得分:1)

Service Oriented Architecture中,您必须区分模型类的服务类。

所以你通常有一个域库,包含所有模型类定义:

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 class TestService : ITestService 
{
    public bool StartTest(int testId)
    {
        //Logic and rules for starting a test here
    }

    public bool FinishTest(int testId)
    {
        //Save the results in the DB            
    }
} 

您的服务接口也可以在您的域库中定义

interface  ITestService
{
  Test GetById(int testId);
  bool StartTest(int testId);
  bool FinishTest(int testId);
}

唯一的依赖是服务 - &gt;域。

答案 1 :(得分:0)

查看d 依赖注入控制反转。演示和模式信息。 大量的例子和解释。

您在核心层使用和接口定义。

定义依赖关系并将其传递到该层。 另一个项目使用接口定义引用项目。 目标图层不引用外层。

所以外层可以改变实现,所有仍然有效。因为它传入符合接口定义的对象。