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

时间:2016-04-29 14:22:04

标签: c# dependency-injection circular-dependency

我有三个实现其界面的类。

订单

public interface IOrderService
{
   //SomeOrderFunction()
}

public class OrderService: IOrderService
{
    //SomeOrderFunction();
}

驱动

public interface IDriverService
{
   //SomeDriverFunction()
}

public class DriverService: IDriverService
{
    //SomeDriverFunction();
}

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

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();
}

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

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

Breaking Dependency Cycles

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

3 个答案:

答案 0 :(得分:6)

通过活动。

创建一个事件处理程序接口:

public interface IEventSubscriber<TEvent>
{
    void Handle(TEvent evt);
}

然后定义一个事件:

public class PlanCreated
{
    public int PlanId { get; set; }
    //and other properties.
}

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

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

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

public interface IEventPublisher
{
    void Publish<TEvent>(TEvent evt);
}

可以从您的班级调用:

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

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

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

    }
}

..因此,你得到了类之间的低耦合。

答案 1 :(得分:1)

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

其次,如果你仍然坚持循环依赖,你可以通过让依赖服务负责设置后向依赖来减少它,例如。

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

....

public class PlanService: IPlanService
{
   private readonly IOrderService _orderService;

   public PlanService(IOrderService orderService)
   {
      _orderService = orderService;
      _orderService.planService = this;
   }
}

答案 2 :(得分:1)

Func<IPlanService>而不是IPlanService注入IOrderServiceIDriverService。这个&#39;打破&#39;容器必须创建的实例链。

public class OrderService {
    public OrderService(Func<IPlanService> planServiceFactory) {
        _planServiceFactory = planServiceFactory;
    }

    private readonly Func<IPlanService> _planServiceFactory;

    public void SomeOrderFunction() {
        _planServiceFactory().Notify(...);
    }
}