首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在简单注塑器中使用Ninject的命名绑定?

如何在简单注塑器中使用Ninject的命名绑定?
EN

Stack Overflow用户
提问于 2018-06-14 06:58:10
回答 1查看 314关注 0票数 1

我有一个MVC应用程序,在DI中使用Ninject,我计划将其迁移到简单的Injector。但是,我找不到任何替代方法来用简单的注塑器来替换Ninject的命名绑定。

具有约束力:

代码语言:javascript
运行
复制
    kernel.Bind<IStudent>().To<Student1>().Named("Senior");
    kernel.Bind<IStudent>().To<Student2>().Named("Junior");
    kernel.Bind<IStudent>().To<Student3>().Named("Junior");

主计长:

代码语言:javascript
运行
复制
public class StudentController
{
  private readonly IEnumerable<IStudent> _seniors;
  private readonly IEnumerable<IStudent> _juniors;
  public StudentController([named("Senior")] IEnumerable<IStudent> seniors,[named("Junior")] IEnumerable<IStudent> juniors)
  {
    _seniors=seniors;
    _juniors=juniors;
  }
}

我提到了几个链接如何在简单喷射器中使用Ninject的命名绑定。但没有任何运气。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-14 07:28:23

有许多选择:

选项1:使用命名属性

要实现这一点,您必须重新创建NamedAttribute,因为这并不存在于简单注入器有充分的理由中。

您可以为学生集合进行以下两次有条件注册:

代码语言:javascript
运行
复制
container.RegisterConditional<IEnumerable<IStudent>>(
    container.Collection.CreateRegistration<IStudent>(
        typeof(Student1)),
    c => c.Consumer.Target.GetCustomAttribute<namedAttribute>()?.Name == "Senior");

container.RegisterConditional<IEnumerable<IStudent>>(
    container.Collection.CreateRegistration<IStudent>(
        typeof(Student2),
        typeof(Student3)),
    c => c.Consumer.Target.GetCustomAttribute<namedAttribute>()?.Name == "Junior");

每个条件注册都为一个Registration集合包装一个IStudent集合。谓词筛选目标(在本例中是构造函数参数)以获取其namedAttribute的名称。

选项2:不使用命名属性,方法是检查参数名

然而,一个更简单的选项是将命名的属性全部丢弃,只需根据构造函数参数的名称进行筛选:

代码语言:javascript
运行
复制
container.RegisterConditional<IEnumerable<IStudent>>(
    container.Collection.CreateRegistration<IStudent>(
        typeof(Student1)),
    c => c.Consumer.Target.Name == "seniors");

container.RegisterConditional<IEnumerable<IStudent>>(
    container.Collection.CreateRegistration<IStudent>(
        typeof(Student2),
        typeof(Student3)),
    c => c.Consumer.Target.Name == "juniors");

此注册与选项1几乎相同,但现在我们根据参数的实际名称进行筛选,而不是根据其属性进行筛选。

选项3:手动连接StudentsController.

一个更简单的选择是从自动布线StudentsController恢复到手动配线,如下所示:

代码语言:javascript
运行
复制
var seniors = container.Collection.Create<IStudent>(typeof(Student1));
var juniors = container.Collection.Create<IStudent>(typeof(Student2), typeof(Student3));
container.Register(() => new StudentController(seniors: seniors, juniors: juniors));

在这里,我们请求容器创建两个学生集合,并为两个集合注入的StudentsController创建注册。

请注意,在简单注入器中,集合是流。这意味着对Collection.Create的调用是而不是创建学生实例,只是对迭代时生成学生实例的流的引用。这意味着,可以在应用程序启动时创建流,同时保留注册生活方式。

还请注意,如果调用RegisterMvcControllers,则必须重写此控制器类的现有注册。此页展示了如何做到这一点。

选项4:更改设计。使“级别”成为IStudent的属性。在控制器内过滤.

您可以决定以简化注册的方式更改您的设计。这是否更好在很大程度上取决于背景,所以请接受这一点。但是,当您将一个Level属性或类似的内容添加到表示学生是否为高年级学生的IStudent接口中,并根据该属性在控制器内进行筛选时,您的注册量将减少到以下几个方面:

代码语言:javascript
运行
复制
container.Collection.Register<IStudent>(typeof(Student1).Assembly);

在这里,我们使用自动注册来搜索所有的学生实现,并将它们全部注册到一个集合中。

在本例中,StudentController将保留一个构造函数参数,但您显然将过滤出成分根的责任转移到控制器中。

代码语言:javascript
运行
复制
public class StudentController
{
    private readonly IEnumerable<IStudent> _students;

    public StudentController(IEnumerable<IStudent> students)
    {
        _students = students;
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50851371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档