我正在从事一项复杂业务的项目。 考虑两个类:AccountService和SchoolService
我使用Unity和Web API的依赖项解析器在构造函数中实现依赖注入。
学校服务在某些方法中使用帐户服务,帐户服务也使用学校服务。所有这些都是项目业务所必需的。这将导致循环依赖,并且无法将方法从一个类移动到另一个类。
您能否就如何解决这个问题提出任何意见?
以下是一个例子:
public class SchoolBLC : ISchoolBLC
{
public School GetSchool(int schoolId)
{
...
}
public bool RenewRegistration(int accountId)
{
bool result = true;
IAccountBLC accountBLC = new AccountBLC();
// check some properties related to the account to decide if the account can be renewed
// ex : the account should not be 5 years old
// check the account created date and do renewal
return result;
}
}
public class AccountBLC : IAccountBLC
{
public void ResetAccount(int accountId)
{
ISchoolBLC schoolBLC = new SchoolBLC();
School accountSchool = schoolBLC
// get the school related to the account to send a notification
// and tell the school that the user has reset his account
// reset account and call the school notification service
}
public Account GetAccount(int accountId)
{
...
}
}
这两个类是相互引用的,这是项目中70%的BLC的情况。
答案 0 :(得分:0)
如果您必须这样做,您可以拥有一个执行IoC逻辑的接口,并将其解析为包含Unity解析的实现,例如
public interface ITypeResolver
{
T Resolve<T>();
}
然后,您可以将该接口传递给构造函数中的两个服务,并在构造函数之外使用它来延迟解析其他服务。
这样,当两个服务都被初始化时,它们不会直接依赖于其他服务,只能在ITypeResolver
答案 1 :(得分:0)
我会按照@KMoussa的建议做,但做了一些修改:
该项目正在使用贫血模型,因此我将使用上下文模式来延迟加载并创建任何服务,并将上下文作为参数传递给服务构造函数。
public class SDPContext : ISDPContext
{
private ITypeResolver _typeResolver;
public Account CurrentUser { get; set; }
public IAccountService AccountService
{
get
{
// lazy load the account service
}
}
public ISchoolService SchoolService
{
get
{
// lazy load the schoolservice
}
}
public SDPContext(ITypeResolver typeResolver)
{
this._typeResolver = typeResolver;
}
}
public class ServiceBase
{
public ISDPContext CurrentContext { get; set; }
public ServiceBase(ISDPContext context)
{
this.CurrentContext = context;
}
}
public class AccountService : ServiceBase, IAccountService
{
public AccountService(ISDPContext context) : base(context)
{
}
public bool ResetAccount(int accountId)
{
// use base.Context.SchoolService to access the school business
}
}
public class SchoolService : ServiceBase, ISchoolService
{
public SchoolService(ISDPContext context) : base(context)
{
//this._accountService = accountService;
}
public void RenewRegistration(int accountId)
{
// use the base.Context.Account service to access the account service
}
}