简体   繁体   English

通用接口依赖注入工厂

[英]Generic Interface dependency injection into factory

I'm playing around with DI and Ninject.我在玩 DI 和 Ninject。 I'm open for suggestions on how to solve this in another way.我愿意就如何以另一种方式解决这个问题提出建议。 I'm trying to make sure the concrete implementations of ICreateOrders can be replaced - if need be.我试图确保 ICreateOrders 的具体实现可以被替换 - 如果需要的话。 Maybe there's another way or pattern?也许还有另一种方式或模式?

Solutions like this: C# - Ninject, IoC and factory pattern are fine but I was hoping to inject the possible creators into the factory and making the factory pick one based on OrderRequest.像这样的解决方案: C# - Ninject、IoC 和工厂模式都很好,但我希望将可能的创建者注入工厂并让工厂根据 OrderRequest 选择一个。 This doesn't work.这不起作用。 kernel.Bind(typeof(ICreateOrders<,>)).To(typeof(OrderCreator))

I can kind of understand why not.我能理解为什么不。 But even another signature of OrderCreator to OrderCreator<,> or actually providing the Interfaces and/or concrete classes to the generic parameters don't work and ideally, I don't want to do that because the implementor of a new OrderCreator should just do something like this但即使是 OrderCreator 到 OrderCreator<,> 的另一个签名,或者实际上为泛型参数提供接口和/或具体类也不起作用,理想情况下,我不想这样做,因为新 OrderCreator 的实现者应该这样做像这样的东西

public class HorseOrderCreator : ICreateOrders<HorseOrderRequest, HorseOrderResponse>
{
    public HorseOrderResponse Create()
    {
        throw new NotImplementedException();
    }
}   

Sample code示例代码

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
    {

    }
}

I'm aware that I need to inject multiple concrete instances of ICreatorOrders to make Ninject give me an IEnumerable in the factory.我知道我需要注入 ICreatorOrders 的多个具体实例,以使 Ninject 在工厂中给我一个 IEnumerable。 Just pointing out with the code what I'm actually trying to do.只是用代码指出我真正想做的事情。

As suggested in the comments, you may try to specify ICreateOrders as正如评论中所建议的,您可以尝试将ICreateOrders指定为

ICreateOrders<out TOrderRequest, out TOrderResponse>

You should then be able to write and to resolve successfully :然后,您应该能够编写并成功解析:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM