我如何使用Ninject公约库绑定到一个基本类型不是一个接口? [英] How do I use the Ninject Conventions library to bind to a base type that isn't an interface?

查看:191
本文介绍了我如何使用Ninject公约库绑定到一个基本类型不是一个接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图扫描一组实现在同一目录中我的应用程序的组件特定的基类的组件。我需要做的这是一种插件式建筑,作为我的应用程序使用这些类型来填充其他部件。

Ninject.Extensions.Conventions 支持本地目录扫描组件,所以我决定给它一个镜头。

问题是,该库提供了结合发电机( DefaultBindingGenerator RegexBindingGenerator )将只绑定组件接口他们实施。他们不会绑定到非接口基本类型。

我如何使用这个库按照惯例绑定到一个基类,而不是一个接口?

我使用目前的NuGet的版本 - 2.2.0.5

我现在的惯例基结合code是这样的:

  Kernel.Scan(X =>
{
    x.FromAssembliesMatching(*的DLL。);
    x.WhereTypeInheritsFrom<基本类型>();

    //我都试过DefaultBindingGenerator和RegexBindingGenerator
    x.BindWith&其中; DefaultBindingGenerator>();

    x.InTransientScope();
});
 

当我试图解决的组件,什么都不会返回:

  VAR myTypes = Kernel.GetAll<基本类型>();
诠释计数= myTypes.Count(); //总是返回零
 

解决方案

当前code碱基了GitHub上,你可以使用<一个href="https://github.com/ninject/ninject.extensions.conventions/blob/master/src/Ninject.Extensions.Conventions/BindingGenerators/BaseBindingGenerator.cs"相对=nofollow>的 BaseBindingGenerator

在codeBase的我(在上的NuGet目前一 - 2.2.0.5),我解决了这个使用自定义的 IBindingGenerator 。这是相当简单的写一次我看了看<一href="https://github.com/ninject/ninject.extensions.conventions/blob/9942fe3b8588b4998aae3f104922f7e77a18c533/src/Ninject.Extensions.Conventions/DefaultBindingGenerator.cs"相对=nofollow>中的现有绑定生成源的。

 公共类BaseTypeBindingGenerator&LT; TBASE&GT; :IBindingGenerator
{
    私人静态只读类型基本类型= ty​​peof运算(TBASE);

    公共无效过程(类型类型,函数功能&LT; IContext,对象&gt; scopeCallback,
        的iKernel内核)
    {
        如果(type.IsInterface || type.IsAbstract || type.BaseType!=基本类型)
        {
            返回;
        }

        kernel.Bind(基本类型)。为了(类型).InScope(scopeCallback);
    }
}
 

我用它是这样的:

  Kernel.Scan(X =&GT;
{
    x.FromAssembliesMatching(*的DLL。);
    x.WhereTypeInheritsFrom&LT;基本类型&GT;();

    x.BindWith&LT; BaseTypeBindingGenerator&LT;基本类型&GT;&GT;();

    x.InTransientScope();
});

// ...

VAR myTypes = Kernel.GetAll&LT;基本类型&GT;();
诠释计数= myTypes.Count(); //没有回零!
 

I'm trying to scan for a set of components that implement a specific base class in the assemblies in the same directory as my application. I need to do this as a sort of plugin-style architecture, as my application uses these types to populate other components.

Ninject.Extensions.Conventions supports scanning assemblies in the local directory, so I decided to give it a shot.

The problem is that the binding generators that library provides (DefaultBindingGenerator and RegexBindingGenerator) will only bind components to interfaces that they implement. They won't bind to non-interface base types.

How do I use this library to bind by convention to a base class, rather than an interface?

I am using the version currently on NuGet - 2.2.0.5

My current convention-based binding code looks like this:

Kernel.Scan(x =>
{
    x.FromAssembliesMatching("*.dll");
    x.WhereTypeInheritsFrom<BaseType>();

    // I've tried both DefaultBindingGenerator and RegexBindingGenerator
    x.BindWith<DefaultBindingGenerator>();

    x.InTransientScope();
});

When I try to resolve the components, nothing is returned:

var myTypes = Kernel.GetAll<BaseType>();
int count = myTypes.Count(); // Always returns zero

解决方案

In the current code base up on GitHub, you can use the BaseBindingGenerator.

In the codebase I have (the one currently on NuGet - 2.2.0.5), I solved this using a custom IBindingGenerator. It was fairly simple to write once I looked at the sources for the existing binding generators.

public class BaseTypeBindingGenerator<TBase> : IBindingGenerator
{
    private static readonly Type baseType = typeof(TBase);

    public void Process( Type type, Func<IContext, object> scopeCallback,
        IKernel kernel )
    {
        if ( type.IsInterface || type.IsAbstract || type.BaseType != baseType)
        {
            return;
        }

        kernel.Bind(baseType).To(type).InScope(scopeCallback);
    }
}

I used it like this:

Kernel.Scan(x =>
{
    x.FromAssembliesMatching("*.dll");
    x.WhereTypeInheritsFrom<BaseType>();

    x.BindWith<BaseTypeBindingGenerator<BaseType>>();

    x.InTransientScope();
});

// ...

var myTypes = Kernel.GetAll<BaseType>();
int count = myTypes.Count(); // Didn't return zero!

这篇关于我如何使用Ninject公约库绑定到一个基本类型不是一个接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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