C# 如何从没有参数的构造函数使用带参数的构造函数
我有一个控制器,它接受C# 如何从没有参数的构造函数使用带参数的构造函数,c#,asp.net-mvc,constructor,dependency-injection,C#,Asp.net Mvc,Constructor,Dependency Injection,我有一个控制器,它接受DbContext,还有一个不接受。即: public CalendarController() { var db = new DbContext(); CalendarController(db); // <= Not allowed } public CalendarController(IDbContext db) { _calendarManager = new CalendarManager(db); _userManag
DbContext
,还有一个不接受。即:
public CalendarController()
{
var db = new DbContext();
CalendarController(db); // <= Not allowed
}
public CalendarController(IDbContext db)
{
_calendarManager = new CalendarManager(db);
_userManager = new UserManager(db);
_farmingActionManager = new FarmingActionManager(db);
_cropManager = new CropManager(db);
}
公共日历控制器()
{
var db=new DbContext();
CalendarController(db);//您必须像这样链接到构造函数:
public CalendarController() : this(new DbContext())
{
}
这是链接到同一类中任何构造函数的语法-它不必从无参数构造函数链接到参数化构造函数,尽管它必须链接到不同的构造函数:)
请注意,这在构造函数主体之前,因此您不能先执行任何其他操作,尽管您可以调用静态方法来计算其他构造函数的参数。但是,您不能使用实例方法或属性。因此,这是可以的:
public Foo() : this(GetDefaultBar())
{
}
public Foo(int bar) { ... }
private static int GetDefaultBar() { ... }
但这不是:
public Foo() : this(GetDefaultBar())
{
}
public Foo(int bar) { ... }
private int GetDefaultBar() { ... }
链接到基类中构造函数的语法类似:
public Foo() : base(...)
如果未指定:base(…)
或:this(…)
编译器会隐式为您添加:base()
(这不一定会链接到无参数构造函数;它可以有可选参数)。您必须像这样链接到构造函数:
public CalendarController() : this(new DbContext())
{
}
这是链接到同一类中任何构造函数的语法-它不必从无参数构造函数链接到参数化构造函数,尽管它必须链接到不同的构造函数:)
请注意,这在构造函数主体之前,因此您不能先执行任何其他操作,尽管您可以调用静态方法来计算其他构造函数的参数。但是,您不能使用实例方法或属性。因此,这是可以的:
public Foo() : this(GetDefaultBar())
{
}
public Foo(int bar) { ... }
private static int GetDefaultBar() { ... }
但这不是:
public Foo() : this(GetDefaultBar())
{
}
public Foo(int bar) { ... }
private int GetDefaultBar() { ... }
链接到基类中构造函数的语法类似:
public Foo() : base(...)
如果未指定:base(…)
或:this(…)
,编译器会隐式为您添加:base()
(这不一定会链接到无参数构造函数;它可以有可选参数)显然,您正在尝试实现私生子注入反模式。不!不要这样做。@SriramSakthivel您能解释私生子注入反模式是什么吗?我这样做是因为每个控制器实例都需要相同的DbContext实例,我还没有找到更好的解决方案。autofac
很有希望,但它仍然是gave在一个请求中使用多个DbContext实例的错误。您没有完全理解DI。当您使用new
关键字时,组合根中除外(值对象除外),那么您违反了DI。您正在更新CalendarManager
,UserManager
等,您应该将它们作为构造函数参数(作为一些接口)。也就是说,当依赖项是外部默认值(在不同的程序集中实现)时,会发生私生子注入默认情况下是注入的。DbContext
是一个外来依赖项(我相信);您不应该将使用者与另一个程序集中的依赖项紧密地结合在一起。如果您真的想在依赖项注入方面做得更好,我建议。事实上,我现在正在阅读:)看,起初我将它们作为构造函数参数,但在更新数据库时,我得到了一个错误无法引用实体对象通过IEntityChangeTracker的多个实例
(请参阅)。所有管理器每个构造函数都需要相同的DbContext
实例。我如何通过注入所有管理器来实现这一点?起点在哪里?显然,您正在尝试实现私生子注入反模式。不!不要这样做。@srramsakthivel您能解释一下私生子注入反模式是什么吗?我是在因为每个控制器实例都需要相同的DbContext实例,所以我还没有找到更好的解决方案。autofac
很有希望,但它仍然给出了在一个请求中使用多个DbContext实例的错误。您没有完全理解DI。当您使用new
关键字时,除了在composition root中(值对象是例外),那么您违反了DI。您正在更新CalendarManager
,UserManager
等,您应该将它们作为构造函数参数(作为一些接口)。也就是说,当依赖项是外部默认值(在不同的程序集中实现)时,会发生私生子注入默认情况下是注入的。DbContext
是一个外部依赖项(我相信);您不应该将使用者与另一个程序集中的依赖项紧密地结合在一起。如果您真的想在依赖项注入方面做得更好,我推荐。事实上,我现在正在阅读:)看,我一开始把它们作为构造函数参数,但是当我更新数据库时,我得到了一个错误一个实体对象不能被多个IEntityChangeTracker实例引用(请参阅)。所有管理者都需要每个构造函数都有相同的DbContext
实例。我如何通过注入所有管理者来实现这一点?起点在哪里?@ErwinRooijakkers-Jon的答案充满了好的信息。很高兴知道。但是,既然你已经用依赖注入来标记这个问题,我建议不要做fall-Injec考虑一下我在你的帖子下面的评论。乔恩的回答充满了很好的信息。很好的知道。但是,既然你用依赖注入来标记这个问题,我建议不要做私底下的注射。想想我的评论就在你的帖子下面。