我正在玩DI和Ninject。我打算就如何以另一种方式解决这个问题提出建议。我试图确保可以替换ICreateOrders的具体实现 - 如果需要的话。也许还有另一种方式或模式?
像这样的解决方案:C# - Ninject, IoC and factory pattern很好,但我希望将可能的创建者注入工厂并使工厂根据OrderRequest选择一个。
这不起作用。
kernel.Bind(typeof(ICreateOrders<,>)).To(typeof(OrderCreator))
我可以理解为什么不呢。但是,OrderCreator的另一个签名是OrderCreator&lt;,&gt;或者实际上为通用参数提供接口和/或具体类别是不可行的,理想情况下,我不想这样做,因为新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 :(得分:2)
根据评论中的建议,您可以尝试将ICreateOrders
指定为
ICreateOrders<out TOrderRequest, out TOrderResponse>
然后您应该能够成功编写并解决:
kernel.Bind(typeof(ICreateOrders<,>)).To(typeof(OrderCreator))