如何在 C# 中解决此循环依赖项问题
本文关键字:循环 依赖 问题 解决 | 更新日期: 2023-09-27 18:31:17
我有一个大项目,我正在为我的对象使用模型模式,所以我有这样的东西:
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
}
}
这个解决方案的问题在于模型非常大,并且有一堆子类,例如学生/教师,这些子类有自己的子类(地址、许可证等)等等,这意味着我需要为整个项目创建接口,并且总是在两个地方更改会带来不便, 模型和接口,每当有变化时。
有没有比这更好、更优雅的解决方案?我只需要找到一种方法来调用正确的 State 类(也许是从接口),除此之外,模型项目不需要任何其他内容。有什么办法可以做到这一点吗?
在面向服务的体系结构中,必须将服务类与模型类区分开来。
因此,您通常有一个包含模型类所有定义的域库:
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);
}
唯一的依赖项是服务 ->域。
看看 dependency 注射或控制倒置。演示和模式信息。大量的例子和解释。
您可以在核心层中使用和接口定义。
依赖项已定义并传递到该层。另一个项目使用接口定义引用该项目。目标层不引用外层。
因此,外层可以更改实现,并且仍然有效。因为它传入符合接口定义的对象。