簡體   English   中英

如何在沒有條件/上下文DI的情況下將不同的實現注入相同的接口?

[英]How to inject different implementations to same interface without conditional/context DI?

我有以下問題,目前有使用條件依賴注入的解決方案。 我已閱讀,這是一個糟糕的主意,比如這里的SimpleInjector文檔。 我現在已經閱讀了大量文章,並且看到了各種建議使用策略,工廠模式等的內容。我真正要尋找的是一些有關如何進行無條件注入的解決方案的細節(即一些代碼示例)。 我需要更多“使用工廠”。 這是我的代碼的簡化版本。 這在MVC Web應用程序中,因此在控制器中。

public abstract class QAControllerBase : Controller
{
    protected readonly QABusinessLayer _blQA;
    public QAControllerBase(QABusinessLayer bl) 
    {
        _blQA = bl;
    }

    [HttpGet]
    public ActionResult PPR(string accession, string site)
    {
        var m = _blQA.popPPRViewModel(accession);

        return View(m);
    }
}

public class QASouthController : QAControllerBase
{

    public QASouthController([QASouthBinding] QABusinessLayer bl) : base(bl)
    {

    }

    // some actions that are specific to South
}


public class QANorthController : QAControllerBase
{

    public QANorthController([QANorthBinding] QABusinessLayer bl) : base(bl)
    {

    }

    // some actions that are specific to North
}

public abstract class QABusinessLayer
{
    protected readonly IFullBaseRepo _repo;
    public QABusinessLayer(IFullBaseRepo repo)
    {
        _repo = repo;
    }

    public abstract PPRViewModel popPPRViewModel(string accession);

    protected PPRViewModel DoSomeCommonStuff(PPRViewModel model)
    {
        ...
        return model;
    }

}

public class SouthBusinessLayer: QABusinessLayer
{

    public SouthBusinessLayer([QASouthBinding] IFullBaseRepo repo) : base(repo)
    {

    }

    public override PPRViewModel popPPRViewModel(string accession)
    {
        var m = new PPRViewModel();
        // do some stuff that is specific to South
        DoSomeCommonStuff(m);

        return m;
    }
}

public class NorthBusinessLayer : QABusinessLayer
{


    public NorthBusinessLayer([QANorthBinding] IFullBaseRepo repo) : base(repo)
    {

    }
    public override PPRViewModel popPPRViewModel(string accession)
    {
        var m = new PPRViewModel();
        // do some stuff that is specific to North
        DoSomeCommonStuff(m);

        return m;
    }
}

這是相關的Ninject綁定代碼:

            kernel.Bind<QABusinessLayer>()
            .To<SouthBusinessLayer>()
            .WhenTargetHas<QASouthBinding>()
            .InRequestScope();

        kernel.Bind<QABusinessLayer>()
            .To<NorthBusinessLayer>()
            .WhenTargetHas<QANorthBinding>()
            .InRequestScope();

QASouthBinding和QANorthBinding只是簡單的屬性。 我不是在問Ninject的具體例子。 無需像現在這樣使用條件注入或基於上下文注入的任何有關如何處理的代碼示例。

使您的QABusinessLayer類抽象。

將啟動配置更改為:

kernel
    .Bind<SouthBusinessLayer>()
    .To<SouthBusinessLayer>()
    .InRequestScope();

kernel
    .Bind<NorthBusinessLayer>()
    .To<NorthBusinessLayer>()
    .InRequestScope();

更改控制器構造函數以接受具體的業務層類型:

public class QANorthController : QAControllerBase
{
    public QANorthController(NorthBusinessLayer businessLayer) : base(businessLayer)
    {
    }
}

public class QASouthController : QAControllerBase
{
    public QASouthController(SouthBusinessLayer businessLayer) : base(businessLayer)
    {
    }
}

一些事情:

  1. 如果Ninject將具體類型自動綁定為相同類型,則在啟動過程中無需手動配置依賴項。
  2. 您可能要使用接口,而不只是傳遞具體的BusinessLayer類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM