Ninject绑定通用接口 [英] Ninject bind generic interface

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

问题描述

这是对将通用接口依赖项注入工厂的后续行动

答案是正确的,但是我简化了代码.因为在接口上没有参数,所以在create方法中不能将TOrderRequest作为输入参数.并且在界面上使用出入"时,绑定将不再起作用.

The answer is correct, but I oversimplified the code. Because with out parameter on the interface you can't have the TOrderRequest as an input parm in the create method. And with Out and In on the interface the binding wont work again.

那么您如何将它与Ninject绑定?

So how do you bind this with Ninject?

using System;
using Ninject;
using System.Collections.Generic;
using System.Linq;

namespace NinjectPlayGround
{
    class Program
    {
        static void Main(string[] args)
        {
            var kernel = new StandardKernel();

            //How to bind this?
            kernel.Bind(typeof(ICreateOrders<,>)).To<HorseOrderCreator>();
            //kernel.Bind<ICreateOrders<IOrderRequest, IOrderResponse>>().To(typeof(OrderCreator));

            kernel.Bind<IOrderCreatorFactory>().To<OrderCreatorFactory>();

            var factory = kernel.Get<IOrderCreatorFactory>();

            var orderCreator = factory.GetOrderCreator(new OrderRequest());
            var create = orderCreator.Create(new OrderRequest());

        }
    }
    public class OrderRequest : IOrderRequest
    {

    }
    public class OrderResponse : IOrderResponse
    {

    }
    public class HorseOrderRequest : IOrderRequest
    {

    }
    public class HorseOrderResponse : IOrderResponse
    {
        public string HorseName { get; set; }
    }
    public class HorseOrderCreator : ICreateOrders<HorseOrderRequest, HorseOrderResponse>
    {        
        public HorseOrderResponse Create(HorseOrderRequest orderRequest)
        {
            return new HorseOrderResponse() { HorseName = "Fred" };
        }
    }
    public class OrderCreator : ICreateOrders<OrderRequest, OrderResponse>
    {        

        public OrderResponse Create(OrderRequest orderRequest)
        {
            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.
        }
    }
    public interface ICreateOrders<TOrderRequest, TOrderResponse> where TOrderRequest : IOrderRequest where TOrderResponse : IOrderResponse
    {
        TOrderResponse Create(TOrderRequest orderRequest);
    }
    public interface IOrderCreatorFactory
    {
        ICreateOrders<IOrderRequest, IOrderResponse> GetOrderCreator(IOrderRequest orderRequest);
    }
    public interface IOrderRequest
    {

    }
    public interface IOrderResponse
    {

    }
}

推荐答案

这是我在上一个问题"Create的空实现和this.createOrders.First()有点混淆了您要实现的目标"的观点. "

That was the point of my comment in your previous question "The empty implementation of Create and the this.createOrders.First() somewhate obfuscates what you want to achieve"

无论如何,这里可能会满足您的需求.它主要依靠ICreateOrders

Anyway here is something which might match your needs. It mostly relies on the CanHandle method in ICreateOrders

using System;
using Ninject;
using System.Collections.Generic;
using System.Linq;

namespace NinjectPlayGround
{   
    class Program
    {
        static void Main(string[] args)
        {
            var kernel = new StandardKernel();

            //How to bind this?
            kernel.Bind<ICreateOrders<IOrderRequest, IOrderResponse>>().To(typeof(OrderCreator));
            kernel.Bind<ICreateOrders<IOrderRequest, IOrderResponse>>().To(typeof(HorseOrderCreator));

            kernel.Bind<IOrderCreatorFactory>().To<OrderCreatorFactory>();

            var factory = kernel.Get<IOrderCreatorFactory>();

            var orderCreator = factory.GetOrderCreator(new OrderRequest());
            var orderResponse = orderCreator.Create(new OrderRequest());    
            if (!(orderResponse is OrderResponse)) throw new InvalidCastException();

            var horseOrderCreator = factory.GetOrderCreator(new HorseOrderRequest());
            var horseResponse = horseOrderCreator.Create(new HorseOrderRequest());    
            if (!(horseResponse is HorseOrderResponse)) throw new InvalidCastException();

            Console.WriteLine("All resolutions successfull");
            Console.ReadLine();

        }
    }
    public class OrderRequest : IOrderRequest
    {

    }
    public class OrderResponse : IOrderResponse
    {

    }
    public class HorseOrderRequest : IOrderRequest
    {

    }
    public class HorseOrderResponse : IOrderResponse
    {
        public string HorseName { get; set; }
    }

    public abstract class BaseOrderCreator<TOrderRequest, TOrderResponse> : ICreateOrders<IOrderRequest, IOrderResponse> where TOrderRequest : IOrderRequest where TOrderResponse : IOrderResponse
    {
        public bool CanHandle(IOrderRequest request)
        {
            return request is TOrderRequest;
        }

        public abstract TOrderResponse SpecificCreate(TOrderRequest orderRequest);

        public IOrderResponse Create(IOrderRequest orderRequest)
        {
            return this.SpecificCreate((TOrderRequest)orderRequest);
        }
    }

    public class HorseOrderCreator : BaseOrderCreator<HorseOrderRequest, HorseOrderResponse>
    {
        public override HorseOrderResponse SpecificCreate(HorseOrderRequest orderRequest)
        {
            return new HorseOrderResponse() { HorseName = "Fred" };
        }
    }
    public class OrderCreator : BaseOrderCreator<OrderRequest, OrderResponse>
    {
        public override OrderResponse SpecificCreate(OrderRequest orderRequest)
        {
            return new OrderResponse();
        }
    }
    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)
        {
            return createOrders.FirstOrDefault(co => co.CanHandle(orderRequest));
        }
    }
    public interface ICreateOrders<in TOrderRequest, out TOrderResponse> where TOrderRequest : IOrderRequest where TOrderResponse : IOrderResponse
    {
        bool CanHandle(IOrderRequest request);

        TOrderResponse Create(TOrderRequest orderRequest);
    }
    public interface IOrderCreatorFactory
    {
        ICreateOrders<IOrderRequest, IOrderResponse> GetOrderCreator(IOrderRequest orderRequest);
    }
    public interface IOrderRequest
    {

    }
    public interface IOrderResponse
    {

    }
}

这篇关于Ninject绑定通用接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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