Constructor dependencies injection 构造函数依赖注入

huangapple go评论60阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年5月25日 07:58:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76328075.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定