英文:
Constructor dependencies injection
问题
我正在通过一个接口创建一个新的服务,但我不够熟练,无法正确实现它。在实现代码时,我遇到了一个无法克服的问题:"_infoSAP"的值为null,因为它没有正确实例化,我找不到正确的方法来实现它。请参见下面的代码,问题发生在"CreateCustomerSAP"行。
// 所有 'using' 都是必需的
namespace OurBrand.Controllers
{
public class AccountController : RootController
{
private readonly IModuleSAP _infoSAP;
//CodeLens: 0 references
public AccountController()
{
}
//CodeLens: 1 references
public AccountController(IModuleSAP customerSAP)
{
_infoSAP = customerSAP;
}
//CodeLens: 0 references
public AccountController(IUserData userData, IMapper mapper, ICheckCompanyNumber checkCompanyNumber)
{
_userData = userData;
_mapper = mapper;
_checkCompanyNumber = checkCompanyNumber;
}
public JsonResult APITest(string testValue)
{
var newCustomerSAP = new CustomerSAP_DTO()
{
//属性
};
// 这里出错了:“_infoSAP”为null
_infoSAP.CreateCustomerSAP(customerDataSAP);
return Json(new
{
success = true,
}, JsonRequestBehavior.AllowGet);
}
}
}
接口:
namespace OurBrand.External.Services.Interfaces
{
public interface IModuleSAP
{
void CreateCustomerSAP(CustomerSAP_DTO customerData);
}
}
服务:
// 所有 'using' 都是必需的
namespace OurBrand.External.Services
{
public class ModuleSAP : IModuleSAP
{
public void CreateCustomerSAP(CustomerSAP_DTO customerData)
{
// 代码在这里
return;
}
}
}
如果需要进一步的帮助,请告诉我。
英文:
I'm creating a new service via an interface and I'm not skilled enough to get this right. While implementing the code I've got an issue I can't overcome: _infoSAP
is getting null
value because it is not instiantiated correctly and I can't find how to do it properly. See code below, issue occurs at CreateCustomerSAP
line.
// all 'using' needed
namespace OurBrand.Controllers
{
public class AccountController : RootController
{
private readonly IModuleSAP _infoSAP;
//CodeLens: 0 references
public AccountController()
{
}
//CodeLens: 1 references
public AccountController(IModuleSAP customerSAP)
{
_infoSAP = customerSAP;
}
//CodeLens: 0 references
public AccountController(IUserData userData, IMapper mapper, ICheckCompanyNumber checkCompanyNumber)
{
_userData = userData;
_mapper = mapper;
_checkCompanyNumber = checkCompanyNumber;
}
public JsonResult APITest(string testValue)
{
var newCustomerSAP = new CustomerSAP_DTO()
{
//Properties
};
// Here the error occurs: "_infoSAP" is null
_infoSAP.CreateCustomerSAP(customerDataSAP);
return Json(new
{
success = true,
}, JsonRequestBehavior.AllowGet);
}
}
}
Interface:
namespace OurBrand.External.Services.Interfaces
{
public interface IModuleSAP
{
void CreateCustomerSAP(CustomerSAP_DTO customerData);
}
}
Service:
// all 'using' needed
namespace OurBrand.External.Services
{
public class ModuleSAP : IModuleSAP
{
public void CreateCustomerSAP(CustomerSAP_DTO customerData)
{
// Code here
return;
}
}
}
答案1
得分: 4
以下是翻译好的内容:
"拥有完全不同参数的3个构造函数是一个很大的警告信号。构造函数的目的是确保对象初始化时具备执行其公开的方法和其他操作所需的一切。应避免为不同情景公开不同属性的构造函数,因为不能保证,特别是在依赖注入容器中,正确的构造函数将用于调用方法的实例。
使用IoC容器的构造函数使用Codelens结果是无用的,因为没有代码可检查构造函数的调用位置。容器将使用反射来发现和实例化类的实例,因此它们都应报告0次使用。拥有1次构造函数使用表示您的代码中某处正在破坏依赖注入并且创建了该类的引用。
因此,您的类应该理想地只有一个构造函数:
public AccountController(IUserData userData, IMapper mapper, ICheckCompanyNumber checkCompanyNumber, IModuleSAP customerSAP)
{
_userData = userData;
_mapper = mapper;
_checkCompanyNumber = checkCompanyNumber;
_infoSAP = customerSAP;
}
您可能遇到的问题是,容器解析的AccountController实例实际上选择了其他构造函数,因此您的_infoSAP引用未初始化。"
英文:
The fact that you have 3 constructors with completely different arguments is a big red flag. the point of a constructor is to ensure that an object is initialized with everything it will need to execute the methods and such it exposes. Constructors that expose different properties for different scenarios should be avoided because there is no guarantee, especially with dependency injection containers that the correct constructor would have been used for the instance for the method you are calling.
Codelens results are useless for constructor usage with IoC containers because there is no code to inspect for where the constructor would be called. The container will use reflection to discover and instantiate a class instance so they should all report 0 usages. The fact that you have 1 usage for a constructor means you have code that is breaking DI and new-ing up a reference of that class somewhere.
So your class should ideally have one constructor:
public AccountController(IUserData userData, IMapper mapper, ICheckCompanyNumber checkCompanyNumber, IModuleSAP customerSAP)
{
_userData = userData;
_mapper = mapper;
_checkCompanyNumber = checkCompanyNumber;
_infoSAP = customerSAP;
}
The issue you are likely encountering is that the instance of the account controller being resolved by the container was actually picking the other constructor leaving your _infoSAP reference uninitialized.
答案2
得分: 0
我发现我的问题出在RegisterTypes
,新创建的IModuleSAP
没有在那里。在创建它之后,事情又开始运作了。
尽管注意到了Steve Py的消息很重要,但只有在另一位开发人员的支持下,我才找到了上面提到的缺失点。
英文:
I've found that my issue was at RegisterTypes
, the newly created IModuleSAP
was not there. After its creation, things became operative again.
While it was important to notice Steve Py message, only with a support of another DEV that I could find the missing point stated above.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论