通用接口依赖注入到工厂
Generic Interface dependency injection into factory
我在玩 DI 和 Ninject。我愿意就如何以另一种方式解决这个问题提出建议。我试图确保 ICreateOrders 的具体实现可以被替换——如果需要的话。也许还有另一种方式或模式?
这样的解决方案: 很好,但我希望将可能的创作者注入工厂,并让工厂根据 OrderRequest 选择一个。
这是行不通的。
kernel.Bind(typeof(ICreateOrders<,>)).To(typeof(OrderCreator))
我能理解为什么不。但即使是 OrderCreator 到 OrderCreator<,> 的另一个签名或实际上向通用参数提供接口 and/or 具体 类 也不起作用,理想情况下,我不想这样做,因为实现者一个新的 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。只是用代码指出我实际上想做什么。
根据评论中的建议,您可以尝试将 ICreateOrders
指定为
ICreateOrders<out TOrderRequest, out TOrderResponse>
然后您应该能够成功地写入和解析:
kernel.Bind(typeof(ICreateOrders<,>)).To(typeof(OrderCreator))
我在玩 DI 和 Ninject。我愿意就如何以另一种方式解决这个问题提出建议。我试图确保 ICreateOrders 的具体实现可以被替换——如果需要的话。也许还有另一种方式或模式?
这样的解决方案:kernel.Bind(typeof(ICreateOrders<,>)).To(typeof(OrderCreator))
我能理解为什么不。但即使是 OrderCreator 到 OrderCreator<,> 的另一个签名或实际上向通用参数提供接口 and/or 具体 类 也不起作用,理想情况下,我不想这样做,因为实现者一个新的 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。只是用代码指出我实际上想做什么。
根据评论中的建议,您可以尝试将 ICreateOrders
指定为
ICreateOrders<out TOrderRequest, out TOrderResponse>
然后您应该能够成功地写入和解析:
kernel.Bind(typeof(ICreateOrders<,>)).To(typeof(OrderCreator))