.net核心依赖注入与构造函数

时间:2017-01-16 04:25:50

标签: dependency-injection asp.net-core

在.net核心中,如果我使用依赖注入,所有构造函数参数必须由DI提供吗?

让我们说:

public Person CreateClient()
{
    string phone = "12345678";
    return new Person(phoneNumber: phone);        
}

public class Person 
{
    private readonly ISomeService _service;
    private readonly string _phoneNumber;
    public Person (ISomeService service, string phoneNumber)
    {
        _service = service;
        _phoneNumber = phoneNumber;
    }

    public string PhoneNumber {get { return _phoneNumber; } }
    public string Gender {get { return _service.GetGenderFromDb(); } }
}

public interface ISomeService
{
    String GetGenderFromDb();
}

public class FooService : ISomeService
{
    public String GetGenderFromDb() { return "Male"; }
}

客户提供的DI和值是否可以保留在同一个构造函数中?

2 个答案:

答案 0 :(得分:18)

您呼叫的任何地方"新的"创建一个对象并不适合从上到下进行构造函数DI。当您想要将参数传递给构造函数时,DI不适用。

正如其他人所提到的,最好的方法是创建一个工厂。它可能看起来像这样。

public class Person 
{   
    private readonly ISomeService _service;
    private readonly string _phoneNumber;
    public Person (ISomeService service, string phoneNumber)
    {
        _service = service;
        _phoneNumber = phoneNumber;
    }

    public string PhoneNumber {get { return _phoneNumber; } }
    public string Gender {get { return _service.GetGenderFromDb(); } }
}

public class PersonFactory : IPersonFactory
{
    private readonly ISomeService _someService;

    public PersonFactory(ISomeService someService)
    {
        _someService = someService;
    }

    public GetPerson(string phoneNumber)
    {
        return new Person(_someService, phoneNumber);
    }
}

现在,当您想创建一个人时,您将注入一个IPersonFactory的实例,并在其上调用GetPerson

此外,您可能会发现您希望您的模型更加简洁,工厂可以完成大部分繁重的工作。我发现此时性别来自数据库,因此您可以将其更改为更像以下内容:

public class Person 
{   
    public Person (string gender, string phoneNumber)
    {
        Gender = gender;
        PhoneNumber = phoneNumber;
    }

    public string PhoneNumber {get; private set; }
    public string Gender {get; private set;}
}

public class PersonFactory : IPersonFactory
{
    private readonly ISomeService _someService;

    public PersonFactory(ISomeService someService)
    {
        _someService = someService;
    }

    public GetPerson(string phoneNumber)
    {
        var gender = _someService.GetGenderFromDb();
        return new Person(gender, phoneNumber);
    }
}

现在你的Person类没有关于从哪里获取Gender的任何细节,工厂每次都会研究如何创建Person模型。

答案 1 :(得分:1)

在我的情况下,我有一个复杂的类,有几个用例所需的构造函数。

在我转换为CORE依赖注入时,我只是创建了一个基类,其中有一个构造函数处理DBcontexts和Helper服务的注入,然后在我的原始类中继承它。

如果您只有一个构造函数,则有another good answer here