通用接口依赖注入到工厂中

3

我正在尝试使用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。这段代码只是在展示我实际上想要做什么。


可能是我漏看了什么,但为什么不是 OrderCreator : ICreateOrders<IOrderRequest, IOrderResponse> 呢? - jbl
1
或者 ICreateOrders 可以是 ICreateOrders<out TOrderRequest, out TOrderResponse>。 Create 的空实现和 this.createOrders.First() 有些模糊了你想要实现的目标。 - jbl
jbl - 这是具体类型,因为这是实现。会有许多这样的类型,由实现者定义实现IOrderRequest和IOrderResponse接口的请求/响应类。 - MacGyver
1
参见使用DI和Ioc的工厂方法 - NightOwl888
@jbl - 输出参数解决了它!现在让Ninject绑定它们。发布答案 :) - MacGyver
1个回答

4

如评论所建议,您可以尝试将ICreateOrders指定为

ICreateOrders<out TOrderRequest, out TOrderResponse>

你应该能够成功编写和解决以下问题:
kernel.Bind(typeof(ICreateOrders<,>)).To(typeof(OrderCreator))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接