通用接口依赖注入工厂

时间:2017-10-12 15:22:02

标签: c# dependency-injection ninject factory

我正在玩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。只是用代码指出我实际上要做的事情。

1 个答案:

答案 0 :(得分:2)

根据评论中的建议,您可以尝试将ICreateOrders指定为

ICreateOrders<out TOrderRequest, out TOrderResponse>

然后您应该能够成功编写并解决:

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