类库中的ASP.NET Core DI?

时间:2019-02-19 21:12:20

标签: c# asp.net-core dependency-injection

我有一个ASP.NET Core 2.1项目,该项目引用典型的.NET Core类库的“数据访问层”项目。

Data Access Layger需要来自ASP.NET Core项目中appsettings.json的连接字符串。

我已经创建了一个像这样的简单容器:

public class DatabaseConnectionString : IDatabaseConnectionString
{
    private readonly string _connectionString;

    public DatabaseConnectionString(string connectionString)
    {
        _connectionString = connectionString;
    }

    public string ConnectionString {
        get { return _connectionString; }
        set {  }
    }
}

在ASP.NET Core Startup.cs> ConfigureService中,我具有以下内容:

services.AddScoped<IDatabaseConnectionString>(p => new DatabaseConnectionString(Configuration.GetConnectionString("DefaultConnection")));

我知道我可以将IDatabaseConnectionString添加到ASP.NET中的控制器的构造函数中以获取容器。但是如何在类库中获取它?我不想将其从控制器一直传递下去,而只是将IDatabaseConnectionString添加到类库中的类的构造函数中是行不通的。

我可能需要一个服务,我可以要求创建一个类的对象,然后让该服务用正确的对象填充构造函数的接口?

例如,在此类中填写IDatabasConnectionString:

public class UserFactory : FactoryBase
{
    private readonly IDatabaseConnectionString _iDatabaseConnectionString;

    public UserFactory(IDatabaseConnectionString connectionString)
    {
        _iDatabaseConnectionString = connectionString;
    }

}

2 个答案:

答案 0 :(得分:3)

  

我知道我可以将IDatabaseConnectionString添加到ASP.NET中的控制器的构造函数中以获取容器。

不,不需要,那是错误的。

  

仅将IDatabaseConnectionString添加到类库中的类的构造函数中是行不通的。

这不起作用,因为您需要创建将使用连接字符串并将添加到服务容器中的服务。

例如:

public class Repository: IRepository
{
    public Repository(IDatabaseConnectionString databaseConnectionString)
    {
        _databaseConnectionString = databaseConnectionString;
    }
}

public class ServiceThatRequiresDatabase : IServiceThatRequiresDatabase
{
    public ServiceThatRequiresDatabase(IRepository repository)
    {
        _repository = repository;
    }
}

// ...
services.AddScoped<IRepository, Repository>();
services.AddScoped<IServiceThatRequiresDatabase, ServiceThatRequiresDatabase>();


public class HomeController : Controller
{
    public HomeController(IServiceThatRequiresDatabase service)
    {
        _service = service;
    }
}

顺便说一句,就像@YeldarKurmangaliyev所说,如果您想将其设为只读,则您的DatabaseConnectionString应该是这样的:

public class DatabaseConnectionString : IDatabaseConnectionString
{
    public string ConnectionString { get; }

    public DatabaseConnectionString(string connectionString)
    {
        ConnectionString = connectionString;
    }
}

答案 1 :(得分:2)

类库中的控制器和类之间没有区别。您需要

  1. 在类库中定义一个类,并将IDatabaseConnectionString注入其中。您的UserFactory是正确的方法。

  2. 为DI注册UserFactory

    serviceCollection.AddScoped<IUserFactory, UserFactory>();
    
  3. 通过DI解析UserFactory。例如,在某些控制器中将UserFactory用作构造函数参数。一切都由DI自动连接。

    public MyController(IUserFactory userFactory)
    {
        _userFactory = myUserFactory;
    }
    

Here是理解组成根的很好解释。