简体   繁体   English

在ASP.NET Core中为服务和存储库层使用依赖注入的正确方法?

[英]Correct way to use dependency injection in ASP.NET Core for service and repository layers?

I just learned the dependency injection system in ASP.NET Core RC1 . 我刚刚学习了ASP.NET Core RC1的依赖项注入系统。 I have a controller (code below). 我有一个控制器(下面的代码)。 Option 1 (the line commented out) I've used before. 我以前使用的选项1 (该行已注释掉)。 Option 2 would need to be repeated in each controller and is not preferred. 选项2将需要在每个控制器中重复,因此不是首选。

public class UserRegisterController : Controller
{
    private readonly IUserRegisterService _userRegisterService;
    private readonly UserManager<ApplicationUser> _userManager;
    public UserRegisterController(
        UserManager<ApplicationUser> userManager, 
        IOptions<WebAppSettings> settings,
        IUserRegisterService userRegisterService)
    {
        _userManager = userManager;
        // Option 2
        _userRegisterService = userRegisterService;
        // Option 1
        //_userRegisterService = 
        //    new UserRegisterService(
        //        new ActiveDirectoryRepository(settings.Value.ContainerDomain));
    }
}

internal class UserRegisterService : IUserRegisterService
{
    private readonly IActiveDirectoryRepository _repoAd;

    internal UserRegisterService(IActiveDirectoryRepository repoAd)
    {
       _repoAd = repoAd;
    } 
}

internal class ActiveDirectoryRepository : IActiveDirectoryRepository
{
    private readonly string _container;

    public ActiveDirectoryRepository(string container)
    {
        _container = container;
    }
}

In the Startup.cs\\Configure\\ConfigureServices we have the following. Startup.cs\\Configure\\ConfigureServices我们具有以下内容。

Option 1: 选项1:

services.AddTransient<Admin.Interfaces.IActiveDirectoryRepository, 
                      Admin.Repositories.ActiveDirectoryRepository>();
services.AddTransient<Admin.Interfaces.IUserRegisterService, 
                      Admin.Services.UserRegisterService>();

Option 2: 选项2:

services.AddTransient<Admin.Interfaces.IActiveDirectoryRepository, 
                      Admin.Repositories.ActiveDirectoryRepository>();
services.AddTransient<Admin.Interfaces.IUserRegisterService, 
                      Admin.Services.UserRegisterService>(provider =>
                          new UserRegisterService(
                              new ActiveDirectoryRepository(
                                  Configuration["ContainerDomain"])));

Is option 2 the preferred implementation? 选项2是首选实现吗? I want to avoid using a third-party library for dependency injection. 我想避免使用第三方库进行依赖项注入。 I think for my needs the standard means ASP.NET Core DI should be sufficient. 我认为对于我的需求,标准意味着ASP.NET Core DI应该足够。

My preference would be to set it up as follows: 我希望将其设置如下:

public class UserRegisterController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;
    private IUserRegisterService _userRegisterService;

    public UserRegisterController(
        UserManager<ApplicationUser> userManager,
        IOptions<WebAppSettings> settings,
        IUserRegisterService userRegisterService)
    {
        _userManager = userManager;
        _userRegisterService = userRegisterService;

    }

    //...
}

internal class UserRegisterService : IUserRegisterService
{
    private readonly IActiveDirectoryRepository _repoAd;

    public UserRegisterService(IActiveDirectoryRepository repoAd)
    {
        _repoAd = repoAd;
    }

}

internal class ActiveDirectoryRepository : IActiveDirectoryRepository
{
    private readonly string _container;

    public ActiveDirectoryRepository(IOptions<WebAppSettings> settings)
    {
        _container = settings.Value.ContainerDomain;
    }

}

public class WebAppSettings
{
    public string ContainerDomain { get; set; }

}

 public void ConfigureServices(IServiceCollection services)
    {
        services.AddOptions();
        services.Configure<WebAppSettings>(Configuration);

        // Add framework services.
        services.AddMvc();

        services.AddTransient<IActiveDirectoryRepository, ActiveDirectoryRepository>();
        services.AddTransient<IUserRegisterService, UserRegisterService>();
    }

this way you have your IUserRegisterService get automatically injected with the IActiveDirectoryService anytime you resolve the IUserRegisterService. 这样,您在解决IUserRegisterService时就可以将IUserRegisterService自动注入IActiveDirectoryService。 The IActiveDirectoryService automatically gets injected with your WebAppsettings, where it can get it's config value. IActiveDirectoryService会自动与您的WebAppsettings一起注入,在那里可以获取它的配置值。 If everything is pre-wired like this then you only need to request that an instance of IUserRegisterService be injected into your controller. 如果一切都是这样预接线的,那么您只需要请求将IUserRegisterService实例注入您的控制器即可。

Is option 2 more preferable? 选项2更可取吗?

No! 没有! We should use the ConfigureServices of option 1, but we will fix the issue you're having. 我们应该使用选项1的ConfigureServices ,但是我们将解决您遇到的问题。 With DI, if you find yourself attempting to use the new keyword -- stop, take a deep breath and reevaluate what you're trying to achieve. 使用DI,如果您发现自己尝试使用new关键字-停止,请深呼吸,然后重新评估要实现的目标。

You should use dependency injection throughout, it's all or nothing. 您应该始终使用依赖项注入,这是全部或全部。 Instead of having the ActiveDirectoryRepository .ctor take a string as a parameter, have it take on the IOptions<WebAppSettings> instead. 与其让ActiveDirectoryRepository .ctor接受一个string作为参数,不如让它接受IOptions<WebAppSettings> This is part of the standard ASP.NET Core dependency injection and is preferred. 这是标准ASP.NET Core依赖项注入的一部分,因此是首选。


Let's review what you'd end up with in each... 让我们回顾一下您最终会得到什么...

First, the ActiveDirectoryRepository as I described above. 首先,如上所述的ActiveDirectoryRepository The _container variable is set from the settings as desired. _container变量是根据需要从设置中设置的。

internal class UserRegisterService : IUserRegisterService
{
    private readonly IActiveDirectoryRepository _repoAd;

    internal UserRegisterService(IActiveDirectoryRepository repoAd)
    {
        _repoAd = repoAd;
    }
}

Next, the UserRegisterService implementation can stay exactly as you have it now. 接下来, UserRegisterService实现可以完全保持现在的状态。

public class UserRegisterController : Controller
{
    private readonly IUserRegisterService _userRegisterService;
    private readonly UserManager<ApplicationUser> _userManager;

    public UserRegisterController(
        UserManager<ApplicationUser> userManager,
        IUserRegisterService userRegisterService)
    {
        _userManager = userManager;
        _userRegisterService = userRegisterService;    
    }
}

Finally, your UserRegisterController is simplified as follows: 最后,将UserRegisterController简化如下:

 public class UserRegisterController : Controller { private readonly IUserRegisterService _userRegisterService; private readonly UserManager<ApplicationUser> _userManager; public UserRegisterController( UserManager<ApplicationUser> userManager, IUserRegisterService userRegisterService) { _userManager = userManager; _userRegisterService = userRegisterService; } } 

Notice, we no longer need the IOptions<WebAppSettings> here? 注意,我们在这里不再需要IOptions<WebAppSettings>了吗? This is a good thing as the options were only being used for something unrelated to this controller specifically. 这是一件好事,因为这些选项仅用于与该控制器无关的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ASP.NET Core-在Singleton注入上存储库依赖项注入失败 - ASP.NET Core - Repository dependency injection fails on Singleton injection ASP.NET 核心依赖注入错误 - 尝试激活“服务”时无法解析“存储库”类型的服务 - ASP.NET Core Dependency Injection error - Unable to resolve service for type “Repository” while attempting to activate “Service” ASP.NET Core Worker 服务中的依赖注入 - Dependency Injection in ASP.NET Core Worker Service asp.net 5自定义类中的依赖注入,正确的方法是什么? - Dependency Injection in asp.net 5 custom classes, what is the correct way? ASP.Net核心使用什么依赖注入框架? - What Dependency Injection Framework Does ASP.Net Core Use? 如何在IHttpcontextAccessor的ASP.NET Core 2.0中使用依赖项注入 - How to use dependency injection in ASP.NET Core 2.0 for IHttpcontextAccessor 如何在 ASP.NET CORE 中使用带有依赖注入的动作过滤器? - How to use Action Filters with Dependency Injection in ASP.NET CORE? ASP.NET核心依赖注入 - ASP.NET Core Dependency Injection ASP.NET Core 2 问题中的依赖注入 - Dependency injection in ASP.NET Core 2 issue 依赖注入ASP.NET Core Singleton - Dependency Injection ASP.NET Core Singleton
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM