.NETCore对DAL和连接字符串的依赖注入(Dependency Injection with .NETCore for DAL and connection string)-译文

我对.NETCore的DI模式还不熟悉,在将连接字符串连接到DAL时遇到了困难。

我按照这个帖子中给出的建议,通过接受的答案和随后的评论。

这是我的基类

public class BaseRepository : IRepository<IDataModel>
{
    private readonly IConfiguration config;

    public BaseRepository(IConfiguration config)
    {
        this.config = config;
    }

    public string GetSQLConnectionString()
    {
        return config["Data:DefaultConnetion:ConnectionString"];
    }

这是继承基类的存储库类的片段

public class PrivacyLevelRepository : BaseRepository, IRepository<PrivacyLevelDM>
{
    public PrivacyLevelRepository(IConfiguration config) : base(config) { }
    public void Add(PrivacyLevelDM dataModel)
    {
         ...
    }
}

这是我的 startup.cs

public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddMvc();
        services.AddScoped<IRepository<IDataModel>>(c => new BaseRepository(Configuration));
    }

但是,在我的服务层中,repository类的实例化仍然要求将(IConfiguration config)作为参数传递。

 PrivacyLevelRepository repo = new PrivacyLevelRepository();

如何将IConfiguration直接加载到我的DAL中,而不必从Controller>BLL>DAL传递它。这看起来效率极低,而且不正确。因为DAL应该确定对象的连接,而不是控制器或服务层。他们应该对数据源不可知,不是吗?

我认为这是一个简单的问题,我只是在DI/IoC范式中没有看到,但是我无法理解。

编辑:我使用的不是实体框架,而是一个自定义的数据层。

谢谢你的帮助。

 

----------------------------------------------------------------

您可以在配置框架中遵循选项模式。这允许您定义一个自定义类型,该类型保存您的配置设置(静态类型),同时仅限于实际的相关配置。

你可以这样使用它:

public void ConfigureServices(IServiceCollection services)
{
   //注册`数据:DefaultConnection`配置节组件
   //“DatabaseOptions”类型的配置
    services.Configure<DatabaseOptions>(Configuration.GetSection("Data:DefaultConnection"));

    //注册数据库存储库
    //注意,我们不使用自定义工厂来创建对象
    services.AddScoped<IRepository<IDataModel>, BaseRepository>();
}

这假设类型数据库选项如下:

public class DatabaseOptions
{
    public string ConnectionString { get; set; }
}

然后,只需将DatabaseOptions注入BaseRepository:

public class BaseRepository
{
    private readonly DatabaseOptions _options;

    public BaseRepository(IOptions<DatabaseOptions> databaseOptions)
    {
         _options = databaseOptions.Value;
    }
}

当然,如果您有该BaseRepository的子类型,则还需要注册这些子类型并将选项传递给基类:

//同时在“ConfigureServices”方法中注册存储库
services.AddScoped<PrivacyLevelRepository>();
public class PrivacyLevelRepository : BaseRepository, IRepository<PrivacyLevelDM>
{
    public PrivacyLevelRepository(IOptions<DatabaseOptions> databaseOptions)
        : base(databaseOptions)
    { }
}

我像往常一样实例化和使用回购。我不知道如何使用我没有实例化的类。如何让这个对象知道它依赖于PrivacyLevelRepository?

PrivacyLevelRepository repo = new PrivacyLevelRepository();
returnValue = repo.GetAllByDomainID(DomainID).ToList();
return returnValue;

我像往常一样实例化和使用回购。我不知道如何使用我没有实例化的类。如何让这个对象知道它依赖于PrivacyLevelRepository?

您似乎还不了解依赖注入背后的思想。依赖注入及其基本的控制反转原理简单地说就是避免使用new来创建对象。您不再主动依赖实现(在您的示例中是PrivacyLevelRepository),而是放弃了责任,只依赖外部系统来提供所需的依赖关系。

因此,不是创建新的PrivacyLevelRepository,而是注入由其他地方创建的实例。这会使依赖关系的实现失去耦合。一个非常实际的例子是PrivacyLevelRepository如何依赖IOptions<DatabaseOptions>。作为该存储库的使用者,您不必关心如何获得这样一个对象来创建存储库实例。首先,您甚至不需要知道如何创建存储库实例。

因此,PrivacyLevelRepository的使用者应该遵循与存储库本身相同的思想:存储库不知道如何获取这些数据库选项;它只依赖于构造实体来传递这样一个对象。而你的消费者,我假设一个控制器,也应该这么做:

public class MyController
{
    private readonly PrivacyLevelRepository _privacyLevelRepository;

    public MyController(PrivacyLevelRepository privacyLevelRepository)
    {
         // instead of *creating* a repository, we just expect to get one
         _privacyLevelRepository = privacyLevelRepository;
    }

    public IActionResult SomeRoute()
    {
         var domainId = "whatever";
         var data = _privacyLevelRepository.GetAllByDomainID(domainId).ToList();
         return View(data);
    }
}

当然,在某个时刻,某些东西必须创建依赖关系。但是如果你完全接受依赖注入ASP.NET核心不仅使非常容易,而且积极地要求你这样做,以便完全工作,然后你不需要关心这一部分。您只需在ConfigureServices方法中注册类型,然后期望在需要的地方实现依赖关系。

要了解更多信息,您应该查看文档中的依赖注入一章。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值