簡體   English   中英

如何指定與特定MVC控制器一起使用的接口注冊?

[英]How do I specify which registration of an interface to use with a particular mvc controller?

我有一個接口的兩種實現,在普通的老式C#中將像這樣實例化:

var useCache = bool.Parse(ConfigurationManager.AppSettings["useCache"]);
var oven = useCache
  ? new CachedCookieOven(new CookieOven())
  : new CookieOven();
var controller = new CookieController(oven); // MVC Controller

這是接口和類:

public interface ICookieOven {
  IEnumerable<Cookie> Bake();
}

public class CookieOven : ICookieOven {
  public IEnumerable<Cookie> Bake() {
    var list = new List<Cookie>();
    // bake cookies and return them
    return list;
  }
}

public class CachedCookieOven : ICookieOven {
  readonly ICookieOven _oven;

  public CachedCookieOven(ICookieOven oven) { _oven = oven; }

  public IEnumerable<Cookie> Bake() {
    var cookies = GetFromPlate();
    return cookies ?? _oven.Bake();
  }
}

我的MVC控制器具有以下構造函數

public class CookieController : Controller {

  readonly ICookieOven _oven;

  public CookieController(ICookieOven oven) { _oven = oven; }

  public ActionResult ViewCookies() {
    var bakedCookies = _oven.Bake();
    return View(bakedCookies);
  }
}

創建的Bootstrapper類在注釋中說,我不需要注冊我的mvc控制器類。

public static class Bootstrapper
{
    public static IUnityContainer Initialise()
    {
        var container = BuildUnityContainer();

        DependencyResolver.SetResolver(new UnityDependencyResolver(container));

        return container;
    }

    private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer();

        // register all your components with the container here
        // it is NOT necessary to register your controllers

        // e.g. container.RegisterType<ITestService, TestService>();    
        RegisterTypes(container);

        return container;
    }

    public static void RegisterTypes(IUnityContainer container)
    {

    }
}

在Unity中,我已經注冊了兩個實例。 可能有更好的方法,如果可以,請告訴我。

public static class Bootstrapper {
  // ...
  private static IUnityContainer BuildUnityContainer() {
    var container = new UnityContainer();
    var useCache = bool.Parse(ConfigurationManager.AppSettings["useCache"]);
    // register
    container.RegisterType<ICookieOven, CookieOven>("oven");
    if (useCache) {
      container.RegisterType<ICookieOven, CachedCookieOven>("cachedOven",
        new InjectionConstructor(container.Resolve<ICookieOven>("oven"));
    }

  }
}

如何確保將正確的ICookieOven實例發送到CookieController mvc控制器的構造函數?

在沒有名稱的Unity中注冊類型會使其成為默認類型。 如果要注冊多個類型,則必須提供一個名稱。 以下是在Bootstrapper類中注冊我的類型的正確方法:

public static void RegisterTypes(IUnityContainer container)
{
  var useCache = bool.Parse(ConfigurationManager.AppSettings["useCache"]);
  if (useCache) { 
    // named, this is not the default
    container.RegisterType<ICookieOven,CookieOven>("oven");
    // this one is not named and is the default
    container.RegisterType<ICookieOven,CachedCookieOven>(new InjectionConstructor(
      container.Resolve<ICookieOven>("oven")); 
  } else {
    // notice it is not named, it is the default
    container.RegisterType<ICookieOven,CookieOven>();
  }
}

您想創建一個對象,但是哪個對象取決於僅在運行時才知道的值。 您需要的是一個工廠( 這里有幾個示例)。

為了實現這一點,一種方法可能是這樣的:您的控制器可能依賴於IOvenFactory ,注入到控制器的構造函數中。 當您需要烤箱時,可以調用_ovenFactory.Create()

IOvenFactory實現中,您可以根據配置值掌握如何創建的邏輯。

暫無
暫無

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

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