Asp.net mvc 手动初始化对象时的属性注入

Asp.net mvc 手动初始化对象时的属性注入,asp.net-mvc,dependency-injection,ninject,inversion-of-control,ninject.web.mvc,Asp.net Mvc,Dependency Injection,Ninject,Inversion Of Control,Ninject.web.mvc,使用Ninject属性注入时,只有当对象由框架实例化(而不是由代码中的开发人员实例化)以便注入工作时,以下操作才起作用: public class SomeController: Controller { [Inject] public DbContext db {get; set;} ... } 但是,当开发人员必须在代码中实例化对象时,绑定不会发生(我不想说失败,因为它不会发生) 公共类数据提供{ [注入] 公共DbContext数据库{get;set;} public L

使用Ninject属性注入时,只有当对象由框架实例化(而不是由代码中的开发人员实例化)以便注入工作时,以下操作才起作用:

public class SomeController: Controller {
   [Inject]
   public DbContext db {get; set;}

 ...
}
但是,当开发人员必须在代码中实例化对象时,绑定不会发生(我不想说失败,因为它不会发生)

公共类数据提供{
[注入]
公共DbContext数据库{get;set;}
public List GetList()其中T:class,new(){
返回db.Set().toList();
}
...
}
公开课考试{
公共静态无效测试(){
DataProvision dp=新的DataProvision();
var getValue=dp.GetList();
}
}
Ninject是否支持它?如果支持,解决方案是什么


我们这样做的理由:在紧急情况下轻松地在备份数据库和活动数据库之间切换这是预期的行为。如果您创建自己的实例,DI框架就没有机会注入任何东西。如果您的代码可以访问DI绑定,请设置内核并使用它来实例化您的类:

public class Test {
    public static void Test(){
        var kernel = new StandardKernel(new YourDiModule());
        DataProvision dp = kernel.Get<DataProvision>();
        var getValue = dp.GetList<Person>();
    }
}
公共类测试{
公共静态无效测试(){
var kernel=新的标准内核(new YourDiModule());
DataProvision dp=kernel.Get();
var getValue=dp.GetList();
}
}
使用上述策略,您可能需要稍微调整DI配置,以便在需要时处理上下文。(您的web应用程序通常设置为在每个web请求完成后处理上下文,并且您的测试代码看起来不像是设置为在同一种环境中运行的。)

否则,您需要手动管理依赖项注入:

public class Test {
    public static void Test(){
        using (var context = new DbContext()) // or however you create contexts
        {
            DataProvision dp = new DataProvision();
            dp.db = context;
            var getValue = dp.GetList<Person>();
        }
    }
}
公共类测试{
公共静态无效测试(){
使用(var context=new DbContext())//或创建上下文的方式
{
DataProvision dp=新的DataProvision();
dp.db=上下文;
var getValue=dp.GetList();
}
}
}

这就是为什么您应该支持构造函数注入而不是属性注入。属性注入导致了一种设计气味。
DataProvision
在其构造函数中应该需要
DbContext
依赖项。@史蒂文:这没有什么区别,因为在这种情况下,您必须传入对象。为什么?这个DataProvision类应该在MVC视图中以一种通用的方式提供下拉菜单(它不在其他视图中使用)。所以我们实际上不希望DbContext出现在构造函数中。但是,这个问题可以通过将db移出内核来利用绑定来解决。您不应该让视图具有任何依赖性。视图应该是哑的,控制器应该传递视图所需的所有数据。@史蒂文:我们使用的体系结构有点特殊,甚至连控制器的行为都完全失去耦合,更不用说视图了。没有依赖关系。DataProvision是一个静态类,实际上它填充了按需查看中使用的下拉菜单。这不是你想象的那样。
public class Test {
    public static void Test(){
        using (var context = new DbContext()) // or however you create contexts
        {
            DataProvision dp = new DataProvision();
            dp.db = context;
            var getValue = dp.GetList<Person>();
        }
    }
}