类型Ninject绑定当祖先牛逼 [英] Ninject Bind When Ancestor Of Type T

查看:202
本文介绍了类型Ninject绑定当祖先牛逼的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个依赖链,看起来大致是这样的:

I've got a dependency chain that looks roughly like this:

public class CarSalesBatchJob
{
    public CarSalesBatchJob(IFileProvider fileProvider)
    { ... }
}

public class MotorcycleSalesBatchJob
{
    public MotorcycleSalesBatchJob(IFileProvider fileProvider)
    { ... }
}    

public class FtpFileProvider : IFileProvider
{
    public FtpFileProvider(IFtpSettings settings)
    { ... }
}

public class CarSalesFtpSettings : IFtpSettings { ... }
public class MotorcycleSalesFtpSettings : IFtpSettings { ... }

到现在为止,我一直在使用基于绑定的惯例,但是这还不够好了,因为我有一个以上的实施 IFtpSettings 。所以我决定用一些上下文绑定。乍一看 kernel.Bind<>()到<>()WhenInjectedInto<>()看起来很有希望,但是这不仅有利于在第一级,也就是说,如果我有一个 CarSalesFtpFileProvider MotorcycleSalesFtpProvider 我能做到这一点:

Up until now, I've been using conventions based bindings, but that isn't good enough anymore because I've got more than one implementation for IFtpSettings. So I decided to use some contextual bindings. At first blush kernel.Bind<>().To<>().WhenInjectedInto<>() looked promising, but that only helps at the first level, meaning that if I had a CarSalesFtpFileProvider and a MotorcycleSalesFtpProvider I could do this:

kernel.Bind<IFtpSettings>().To<CarSalesFtpSettings>()
    .WhenInjectedInto<CarSalesFtpFileProvider>();
kernel.Bind<IFtpSettings>().To<MotorcycleSalesFtpSettings>()
    .WhenInjectedInto<MotorcycleSalesFtpFileProvider>();

但似乎pretty的愚蠢创造 FtpFileProvider 两个具体的实现,真正的唯一区别我希望他们使用什么样的设置。我看到有一个名为方法 WhenAnyAnchestorNamed(字符串名称)。但是,这条路线需要我把属性和魔法串在我的批处理作业,而我不是激动不已。

But it seems pretty stupid to create two concrete implementations of FtpFileProvider that really only differ on what settings I want them to use. I saw that there is a method called WhenAnyAnchestorNamed(string name). But this route requires me to put attributes and magic strings on my batch jobs, which I'm not thrilled about.

我也注意到,有一个普通的老式。当(Func键&LT; IRequest,布尔&GT;)约束力声明的方法,所以我想出了这个作为我的约束性声明

I also noticed that there is a plain old .When(Func<IRequest, bool>) method on binding statements, so I came up with this as my binding statements:

//at this point I've already ran the conventions based bindings code so I need to unbind
kernel.Unbind<IFtpSettings>();
kernel.Bind<IFtpSettings>().To<CarSalesFtpSettings>()
    .When(r => HasAncestorOfType<CarSalesBatchJob>(r));
kernel.Bind<IFtpSettings>().To<MotorcycleSalesFtpSettings>()
    .When(r => HasAncestorOfType<MotorcycleSalesBatchJob>(r));

// later on in the same class
private static bool HasAncestorOfType<T>(IRequest request)
{
    if (request == null)
        return false;

    if (request.Service == typeof(T))
        return true;

    return HasAncestorOfType<T>(request.ParentRequest);
}

因此​​,如果一个构造要求IFtpSettings,我们递归了请求树,以查看是否任何所请求的服务的/在链类型匹配提供的类型(CarSalesBatchJob或MotorcycleSalesBatchJob),如果是这样,则返回true。如果我们得到了所有的方式向链的顶端,我们返回false。

So if a constructor asks for IFtpSettings, we recurse up the request tree to see if any of the requested services/types in the chain match the provided type (CarSalesBatchJob or MotorcycleSalesBatchJob) and if so returns true. If we get all the way to the top of the chain, we return false.

对不起,长时间的后台的解释。

Sorry for the long background explanation.

这是我的问题:是否有任何理由为什么我不应该处理这个问题这样这被认为是不好的形式?有没有找到祖先请求类型的更好的办法?我应该调整我的课/依赖关系链到一个更惬意的时尚?

Here is my question: Is there any reason why I should not approach the problem this way? Is this considered bad form? Is there a better way of finding the ancestor request types? Should I restructure my classes/dependency chain to a more "agreeable" fashion?

推荐答案

您应该使用 request.Target.Member.ReflectedType 而不是请求。服务这是实现类型。

You should use request.Target.Member.ReflectedType instead of request.Service This is the implementation type.

另外WhenAnyAncestorNamed不需要属性。您可以使用方法标记你的工作的绑定。

Also WhenAnyAncestorNamed does not require Attributes. You can mark the bindings of your Jobs using the Named method.

这篇关于类型Ninject绑定当祖先牛逼的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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