我有一个MVC应用程序,在DI中使用Ninject,我计划将其迁移到简单的Injector。但是,我找不到任何替代方法来用简单的注塑器来替换Ninject的命名绑定。
具有约束力:
kernel.Bind<IStudent>().To<Student1>().Named("Senior");
kernel.Bind<IStudent>().To<Student2>().Named("Junior");
kernel.Bind<IStudent>().To<Student3>().Named("Junior");
主计长:
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的命名绑定。但没有任何运气。
发布于 2018-06-14 07:28:23
有许多选择:
选项1:使用命名属性
要实现这一点,您必须重新创建NamedAttribute
,因为这并不存在于简单注入器有充分的理由中。
您可以为学生集合进行以下两次有条件注册:
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:不使用命名属性,方法是检查参数名
然而,一个更简单的选项是将命名的属性全部丢弃,只需根据构造函数参数的名称进行筛选:
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
恢复到手动配线,如下所示:
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
接口中,并根据该属性在控制器内进行筛选时,您的注册量将减少到以下几个方面:
container.Collection.Register<IStudent>(typeof(Student1).Assembly);
在这里,我们使用自动注册来搜索所有的学生实现,并将它们全部注册到一个集合中。
在本例中,StudentController
将保留一个构造函数参数,但您显然将过滤出成分根的责任转移到控制器中。
public class StudentController
{
private readonly IEnumerable<IStudent> _students;
public StudentController(IEnumerable<IStudent> students)
{
_students = students;
}
}
https://stackoverflow.com/questions/50851371
复制相似问题