2017-10-12 221 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))