加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 在ASP.NET 5中获取配置值(vNext)

发布时间:2020-12-15 04:20:32 所属栏目:百科 来源:网络整理
导读:我在ASP.NET 5(vNext)中挣扎着一些概念. 其中之一是用于配置的依赖注入方法.似乎我必须通过一个参数通过堆栈.我可能误会某事或做错了. 想象一下,我有一个名为“contactEmailAddress”的配置属性.当订购新订单时,我将使用该配置属性发送电子邮件.考虑到这种情
我在ASP.NET 5(vNext)中挣扎着一些概念.

其中之一是用于配置的依赖注入方法.似乎我必须通过一个参数通过堆栈.我可能误会某事或做错了.

想象一下,我有一个名为“contactEmailAddress”的配置属性.当订购新订单时,我将使用该配置属性发送电子邮件.考虑到这种情况,我的ASP.NET 5堆栈将如下所示:

Startup.cs

public class Startup
{        
  public IConfiguration Configuration { get; set; }
  public Startup(IHostingEnvironment environment)
  {
    var configuration = new Configuration().AddJsonFile("config.json");
    Configuration = configuration;
  }

  public void ConfigureServices(IServiceCollection services)
  {
    services.Configure<AppSettings>(Configuration.GetSubKey("AppSettings"));
    services.AddMvc();
  }

  public void Configure(IApplicationBuilder app)
  {
    app.UseErrorPage();
    app.UseMvc(routes =>
      {
        routes.MapRoute("default","{controller}/{action}/{id}",defaults: new { controller = "Home",action = "Index" });
      }
    );
    app.UseWelcomePage();
  }

AppSettings.cs

public class AppSettings
{
 public string ContactEmailAddress { get; set; }
}

config.json

{
  "AppSettings": {
    "ContactEmailAddress":"support@mycompany.com"  
  }
}

OrderController.cs

[Route("orders")]
public class OrdersController : Controller
{    
  private IOptions<AppSettings> AppSettings { get; set; }

  public OrdersController(IOptions<AppSettings> appSettings)
  {
    AppSettings = appSettings;
  }

  [HttpGet("new-order")]
  public IActionResult OrderCreate()
  {
    var viewModel = new OrderViewModel();
    return View(viewModel);
  }

  [HttpPost("new-order")]
  public IActionResult OrderCreate(OrderViewModel viewModel)
  {

    return new HttpStatusCodeResult(200);
  } 
}

Order.cs

public class Order()
{
  public void Save(IOptions<AppSettings> appSettings)
  {
    // Send email to address in appSettings
  }

  public static List<Order> FindAll(IOptions<AppSettings> appSettings)
  {
    // Send report email to address in appSettings
    return new List<Order>();
  }
}

正如上面的例子所示,我将AppSettings传递给整个堆栈.这听起来不正确.为了进一步担忧,如果我尝试使用需要访问配置设置的第三方库,则此方法将无法正常工作.第三方库如何访问配置设置?我误会了吗?有没有更好的方法来做到这一点?

解决方法

你正在纠缠2个不同的运行时资源提供者,AppSettings和Dependency Injection.

AppSettings提供运行时访问应用程序特定的值,如UICulture字符串,联系人电子邮件等.

DI容器是管理对服务及其终生范围的访问的工厂.例如,如果MVC控制器需要访问您的EmailService,您将进行配置

public void ConfigureServices(IServiceCollection services)
   {
      // Add all dependencies needed by Mvc.
      services.AddMvc();

      // Add EmailService to the collection. When an instance is needed,// the framework injects this instance to the objects that needs it
      services.AddSingleton<IEmailService,EmailService>();
   }

然后,如果我们的家庭控制器需要访问您的EmailService,我们通过将它作为参数添加到Controller构造函数中来添加对它的接口的依赖

public class HomeController : Controller
{
   private readonly IEmailService _emailService;
   private readonly string _emailContact;

  /// The framework will inject an instance of an IEmailService implementation.
   public HomeController(IEmailService emailService)
   {
      _emailService = emailService;
      _emailContact = System.Configuration.ConfigurationManager.
                   AppSettings.Get("ContactEmail");
   }

   [HttpPost]
   public void EmailSupport([FromBody] string message)
   {
      if (!ModelState.IsValid)
      {
         Context.Response.StatusCode = 400;
      }
      else
      {
         _emailService.Send(_emailContact,message);

依赖注入的目的是管理服务的访问和使用寿命.

在上一个示例中,在我们的应用程序启动中,我们配置了DI Factory,将IEmailService的应用程序请求与EmailService相关联.所以当我们的控制器被MVC框架实例化时,框架注意到我们的家庭控制器期望IEmailService,框架检查我们的应用服务集合.它找到映射指令,并将一个Singleton EmailService(占位接口的后代)注入我们的主控制器.

超多形态因子 – 有恶心!

为什么这很重要?

如果您的联系人电子邮件更改,您更改AppSetting值并完成.来自ConfigurationManager的“ContactEmail”的所有请求都将全局更改.字符串很容易当我们可以只是哈希时,不需要注入.

如果您的存储库,电子邮件服务,日志记录服务等更改,您希望Global方式更改对此服务的所有引用.服务引用不像不可变字符串文字那样容易地传输.服务实例化应由工厂处理以配置服务的设置和依赖关系.

所以,在一年中你开发一个RobustMailService:

Class RobustMailService : IEmailService
{

....

}

只要您的新RobustMailService继承并实现了IEmailService接口,您可以通过更改以下方式替换全局邮件服务的所有引用:

public void ConfigureServices(IServiceCollection services)
   {
      // Add all dependencies needed by Mvc.
      services.AddMvc();

      // Add RobustMailService to the collection. When an instance is needed,// the framework injects this instance to the objects that needs it 
      services.AddSingleton<IEmailService,RobustMailService>();
   }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读