.NETCore对DAL和连接字符串的依赖注入 [英] Dependency Injection with .NETCore for DAL and connection string

查看:601
本文介绍了.NETCore对DAL和连接字符串的依赖注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是.NETCore的DI模式的新手,但我无法将连接字符串连接到DAL。

I am new to the DI patterns with .NETCore, and I am having trouble getting my connection strings to my 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"];
    }

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

This is a snippet of a repository class inheriting the base class

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

这是在我的启动程序中。cs

This is in my startup.cs

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

但是,在我的服务层中,存储库类的实例化仍在询问

However, In my service layer, the instantiation of the repository class is still asking for the (IConfiguration config) to be passed as a parameter.

 PrivacyLevelRepository repo = new PrivacyLevelRepository();

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

How do I get the IConfiguration loaded directly to my DAL, without having to pass it from Controller > BLL > DAL. This seems extremely inefficient, and incorrect. As the DAL should be determining the connection for an object, not the controller or service layer. They should be agnostic of the datasource, no?

我认为这很简单,我只是没有在DI / IoC范式中看到,但我无法弄清楚

I figure this is something simple, that I am just not seeing within the DI/IoC paradigm, but I cannot figure it out.

编辑:我不使用Entity Framework,而是使用自定义数据层。

I am not using Entity Framework, but a custom Data layer.

感谢任何帮助。

推荐答案

您可以按照选项模式。这样一来,您就可以定义一个自定义类型,以保留配置设置(静态类型),而只限于实际的相关配置。

You could follow the options pattern with the configuration framework. This allows you to define a custom type that hold your configuration settings (statically typed) while being restricted to only your actual relevant configuration.

您可以像这样使用它:

public void ConfigureServices(IServiceCollection services)
{
    // register the `Data:DefaultConnection` configuration section as
    // a configuration for the `DatabaseOptions` type
    services.Configure<DatabaseOptions>(Configuration.GetSection("Data:DefaultConnection"));

    // register your database repository
    // note that we don’t use a custom factory where we create the object ourselves
    services.AddScoped<IRepository<IDataModel>, BaseRepository>();
}

这假设类型为 DatabaseOptions 像这样:

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

然后,您只需拥有 DatabaseOptions 注入您的 BaseRepository

Then, you can just have the DatabaseOptions injected into your BaseRepository:

public class BaseRepository
{
    private readonly DatabaseOptions _options;

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

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

Of course, if you have subtypes of that BaseRepository, you need to register those as well and pass the options to the base class:

// register the repository as well in the `ConfigureServices` method
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;


您似乎还不了解依赖注入背后的想法。依赖注入及其基本原理控制反转可以说是避免使用 new 创建对象。您没有主动依赖实现(在您的示例中为 PrivacyLevelRepository ),而是放弃了责任,而是依靠外部系统来提供

You do not appear to understand the idea behind dependency injection yet. Dependency injection with its underlying principle Inversion of Control is simply said about avoiding the use of new to create objects. Instead of actively depending on an implementation (in your example the PrivacyLevelRepository), you are giving up the responsibility and just depend on the outer system to provide you with the dependencies you need.

因此,与其创建一个新的 PrivacyLevelRepository ,您注入一个由其他地方创建的实例。这样就松散了依赖关系的实现。一个非常实际的例子是 PrivacyLevelRepository 如何依赖 IOptions< DatabaseOptions> 。作为该存储库的使用者,您无需关心如何获取这样的对象就可以创建存储库实例。您甚至根本不需要知道如何创建存储库实例。

So instead of creating a new PrivacyLevelRepository, you inject an instance that is created by something somewhere else. That looses coupling on the implementation of your dependency. A very practical example of this is how PrivacyLevelRepository depends on IOptions<DatabaseOptions>. You, as a consumer of that repository, should not need to care to know how to get such an object to be able to create the repository instance. You shouldn’t even need to know how to create a repository instance in the first place.

因此您的 PrivacyLevelRepository 应该遵循与存储库本身相同的思想:存储库不知道如何获取那些数据库选项;它仅取决于传递此类对象的构造实体。我的假定控制器是您的使用者,应该执行以下操作:

So your consumer of PrivacyLevelRepository should follow the same idea as the repository itself: The repository does not know how to get those database options; it just depends on the constructing entity to pass such an object on. And your consumer, I assume a controller, should do the same:

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 Core不仅非常容易,而且还主动要求这样做,那么它才能完全起作用),那么您就不必在意那部分了。您只需在 ConfigureServices 方法中注册类型,然后期望在需要它们的地方满足依赖项。

Of course, something has to create the dependencies at some point. But if you embrace dependency injection completely—which ASP.NET Core not only makes very easy but also actively requires you to do so in order to work completely—then you don’t need to care about that part. You just register the types in the ConfigureServices method and then expect the dependencies to be fulfilled where you need them.

有关更多信息,您绝对应该查看依赖性注入一章文档。

For more information, you should definitely check out the dependency injection chapter of the documentation.

这篇关于.NETCore对DAL和连接字符串的依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆