2017-10-12 220 views
2

我在玩DI和Ninject。對於如何以另一種方式解決這個問題,我很樂意提供建議。我試圖確保ICreateOrders的具體實現可以被替換 - 如果需要的話。也許還有另一種方式或模式?通用接口依賴注入工廠

這樣的解決方案:C# - Ninject, IoC and factory pattern很好,但我希望能夠注入可能的創造者到工廠,並使工廠根據OrderRequest選擇一個。 這不起作用。 kernel.Bind(typeof(ICreateOrders<,>)).To(typeof(OrderCreator))

我可以理解爲什麼不能。但是即使是OrderCreator的另一個簽名OrderCreator <,或者實際上爲通用參數提供接口和/或具體類都不起作用,理想情況下,我不想這樣做,因爲新OrderCreator的實現者應該只是做像這樣

public class HorseOrderCreator : ICreateOrders<HorseOrderRequest, HorseOrderResponse> 
{ 
    public HorseOrderResponse Create() 
    { 
     throw new NotImplementedException(); 
    } 
} 

示例代碼

using System; 
using Ninject; 
using System.Collections.Generic; 
using System.Linq; 

namespace NinjectPlatyGround 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var kernel = new StandardKernel();    
      kernel.Bind(typeof(ICreateOrders<,>)).To(typeof(OrderCreator)); 

      kernel.Bind<IOrderCreatorFactory>().To<OrderCreatorFactory>(); 

      var factory = kernel.Get<IOrderCreatorFactory>(); 

      var orderCreator = factory.GetOrderCreator(new OrderRequest()); 

     } 
    } 
    public class OrderRequest : IOrderRequest 
    { 

    } 
    public class OrderResponse : IOrderResponse 
    { 

    } 
    public class OrderCreator : ICreateOrders<OrderRequest, OrderResponse> 
    { 
     public OrderResponse Create() 
     { 
      throw new NotImplementedException(); 
     } 
    } 
    public class OrderCreatorFactory : IOrderCreatorFactory 
    { 
     private readonly IEnumerable<ICreateOrders<IOrderRequest, IOrderResponse>> createOrders; 
     public OrderCreatorFactory(IEnumerable<ICreateOrders<IOrderRequest, IOrderResponse>> createOrders) 
     { 
      this.createOrders = createOrders; 
     } 

     public ICreateOrders<IOrderRequest, IOrderResponse> GetOrderCreator(IOrderRequest orderRequest) 
     { 
      //Based on orderRequest i find the implementation i need. 
      return this.createOrders.First(); 

     } 
    } 
    public interface ICreateOrders<TOrderRequest, TOrderResponse> where TOrderRequest : IOrderRequest where TOrderResponse : IOrderResponse 
    { 
     TOrderResponse Create(); 
    } 
    public interface IOrderCreatorFactory 
    { 
     ICreateOrders<IOrderRequest, IOrderResponse> GetOrderCreator(IOrderRequest orderRequest); 
    } 
    public interface IOrderRequest 
    { 

    } 
    public interface IOrderResponse 
    { 

    } 
} 

我知道,我需要注入ICreatorOrders的多個具體事例,使Ninject給我一個IEnumerable在工廠。只是指出我實際上想要做的事情。

+0

可能缺少明顯的東西,但爲什麼ISN 't'OrderCreator:ICreateOrders '? – jbl

+1

或'ICreateOrders'可能是ICreateOrders <出TOrderRequest,出TOrderResponse> 空執行Create'and的'了'this.createOrders.First()'somewhate混淆你想達到 – jbl

+0

JBL什麼 - 這是具體的類型,因爲這是實施。將會有很多這些實例,並由實現者定義實現IOrderRequest和IOrderResponse請求/響應類的請求 – MacGyver

回答

2

正如評論所說,你可以嘗試指定ICreateOrders作爲

ICreateOrders<out TOrderRequest, out TOrderResponse> 

然後,您應該能夠編寫併成功解決:

kernel.Bind(typeof(ICreateOrders<,>)).To(typeof(OrderCreator))