使用依赖注入解决循环依赖关系

Kel*_*reu 2 c# dependency-injection circular-dependency

我有三个实现其接口的类.

命令

public interface IOrderService
{
   //SomeOrderFunction()
}

public class OrderService: IOrderService
{
    //SomeOrderFunction();
}
Run Code Online (Sandbox Code Playgroud)

驱动程序

public interface IDriverService
{
   //SomeDriverFunction()
}

public class DriverService: IDriverService
{
    //SomeDriverFunction();
}
Run Code Online (Sandbox Code Playgroud)

计划 - 使用驱动程序和计划服务

public interface IPlanService
{
   //SomePlanFunction()
}

public class PlanService: IPlanService
{
    private readonly IOrderService _orderService;
    private readonly IDriverService _driverService;

    public PlanService(IDriverService driverService, IOrderService orderService)
    {
      _orderService = orderService;
      _driverService = driverService;
    }

    //PlanFunctionsThatUseServices();
}
Run Code Online (Sandbox Code Playgroud)

我现在遇到的问题是订单和驱动程序服务需要在订单或驱动程序更改时与计划服务进行对话,如何在没有循环依赖的情况下执行此操作?

编辑:具体来说,我一直在寻找创建第四个管理所有其他服务的服务,例如本文中解释的服务.

打破依赖循环

让我对这个实现感到困惑的是我的Plan类,我的计划类是否同时实现了新类和IPlan接口?

jga*_*fin 6

通过活动.

创建事件处理程序接口:

public interface IEventSubscriber<TEvent>
{
    void Handle(TEvent evt);
}
Run Code Online (Sandbox Code Playgroud)

然后定义一个事件:

public class PlanCreated
{
    public int PlanId { get; set; }
    //and other properties.
}
Run Code Online (Sandbox Code Playgroud)

现在让其他类之一实现它:

public class DriverService : IDriverService, IEventSubscriber<PlanCreated>
{
    public void Handle(PlanCreated evt)
    {
        //handle it here.
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,为了能够发布您需要另一个界面的事件:

public interface IEventPublisher
{
    void Publish<TEvent>(TEvent evt);
}
Run Code Online (Sandbox Code Playgroud)

哪个可以从你的班级调用:

public class PlanService: IPlanService
{
    private readonly IOrderService _orderService;
    private readonly IDriverService _driverService;

    public PlanService(IDriverService driverService, IOrderService orderService, IEventPublisher publisher)
    {
      _orderService = orderService;
      _driverService = driverService;
    }

    public void PlanFunctionsThatUseServices()
    {

       //business code....


      _publisher.Publish(new PlanCreated(){ Id = plan.Id } );
}
Run Code Online (Sandbox Code Playgroud)

..要调用它我们可以使用服务位置(实现细节):

public class EventPublisher : IEventPublisher
{

    public EventPublisher(YourFavoriteContainer container)
    {
    }


    public void Publish<TEvent>(TEvent evt)
    {
        using (var scope = _container.BeginLifetimeScope())
        {
            var handlers = scope.ResolveAll<IEventSubscriber<TEvent>>();
            foreach (var handler in handlers)
            {
                //TODO: Handle exceptions=
                handler.Handle(evt);
            }
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

..结果你得到了类之间的低耦合.

  • 我不这么认为.Event Aggregator用于将来自多个对象***的事件传递到单个对象***,以简化客户端的注册.该模式更多地涉及处理同一对象类型的多个实例的事件. (2认同)

Wik*_*hla 1

首先,重新考虑你的方法。

其次,如果您仍然坚持具有循环依赖关系,则可以通过让依赖服务负责设置向后依赖关系来使其不那么明确,例如

public interface IOrderService
{
   //SomeOrderFunction()
   IPlanService planService;
}

....

public class PlanService: IPlanService
{
   private readonly IOrderService _orderService;

   public PlanService(IOrderService orderService)
   {
      _orderService = orderService;
      _orderService.planService = this;
   }
}
Run Code Online (Sandbox Code Playgroud)