通用接口依赖项注入工厂 [英] Generic Interface dependency injection into factory

查看:102
本文介绍了通用接口依赖项注入工厂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在玩DI和Ninject.我愿意就如何以另一种方式解决此问题提出建议.我试图确保可以替换ICreateOrders的具体实现-如果需要的话.也许还有另一种方式或方式?

I'm playing around with DI and 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. Maybe there's another way or pattern?

像这样的解决方案: C#-Ninject,IoC和工厂模式很好,但我希望将可能的创建者注入工厂,并让工厂根据OrderRequest选择一个. 这是行不通的. kernel.Bind(typeof(ICreateOrders<,>)).To(typeof(OrderCreator))

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. This doesn't work. kernel.Bind(typeof(ICreateOrders<,>)).To(typeof(OrderCreator))

我可以理解为什么不这样做.但是,即使是OrderCreator对OrderCreator的另一个签名,或者实际上为通用参数提供接口和/或具体类也不起作用,理想情况下,我也不想这样做,因为新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

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.只是用代码指出我实际上要做什么.

I'm aware that I need to inject multiple concrete instances of ICreatorOrders to make Ninject give me an IEnumerable in the factory. Just pointing out with the code what I'm actually trying to do.

推荐答案

如注释中所建议,您可以尝试将ICreateOrders指定为

As suggested in the comments, you may try to specify ICreateOrders as

ICreateOrders<out TOrderRequest, out TOrderResponse>

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

You should then be able to write and to resolve successfully :

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

这篇关于通用接口依赖项注入工厂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆