Rob*_*sen 56 c# asp.net-core-mvc .net-core asp.net-core
此时我正在轻松地将内容注入到我的控制器中,在某些情况下构建我自己的ResolverServices类.生活很美好.
我无法弄清楚如何做的是让框架自动注入到非控制器类中.框架自动注入我的控制器的工作是什么IOptions,这实际上是我的项目的配置:
public class MessageCenterController : Controller
{
private readonly MyOptions _options;
public MessageCenterController(IOptions<MyOptions> options)
{
_options = options.Value;
}
}
Run Code Online (Sandbox Code Playgroud)
我认为我可以在我自己的类中发生同样的情况,我认为当我模仿控制器时我会接近,就像这样:
public class MyHelper
{
private readonly ProfileOptions _options;
public MyHelper(IOptions<ProfileOptions> options)
{
_options = options.Value;
}
public bool CheckIt()
{
return _options.SomeBoolValue;
}
}
Run Code Online (Sandbox Code Playgroud)
我想我失败的地方就是我这样称呼它:
public void DoSomething()
{
var helper = new MyHelper(??????);
if (helper.CheckIt())
{
// Do Something
}
}
Run Code Online (Sandbox Code Playgroud)
我跟踪它的问题实际上是关于DI的所有内容都是在控制器级别讨论它.我试图找到它在Controller对象源代码中发生的位置,但它在那里变得有点疯狂.
我知道我可以手动创建一个IOptions实例并将其传递给MyHelper构造函数,但似乎我应该能够让框架做到这一点,因为它适用于Controllers.
非常感谢您的帮助.
Rob*_*sen 26
下面是一个使用DI的工作示例,没有涉及MVC控制器的任何内容.这是我需要做的来理解这个过程,所以它可能会帮助别人.
ShoppingCart对象通过DI获取一个INotifier实例(通知客户他们的订单.)
using Microsoft.Extensions.DependencyInjection;
using System;
namespace DiSample
{
// STEP 1: Define an interface.
/// <summary>
/// Defines how a user is notified.
/// </summary>
public interface INotifier
{
void Send(string from, string to, string subject, string body);
}
// STEP 2: Implement the interface
/// <summary>
/// Implementation of INotifier that notifies users by email.
/// </summary>
public class EmailNotifier : INotifier
{
public void Send(string from, string to, string subject, string body)
{
// TODO: Connect to something that will send an email.
}
}
// STEP 3: Create a class that requires an implementation of the interface.
public class ShoppingCart
{
INotifier _notifier;
public ShoppingCart(INotifier notifier)
{
_notifier = notifier;
}
public void PlaceOrder(string customerEmail, string orderInfo)
{
_notifier.Send("admin@store.com", customerEmail, $"Order Placed", $"Thank you for your order of {orderInfo}");
}
}
public class Program
{
// STEP 4: Create console app to setup DI
static void Main(string[] args)
{
// create service collection
var serviceCollection = new ServiceCollection();
// ConfigureServices(serviceCollection)
serviceCollection.AddTransient<INotifier, EmailNotifier>();
// create service provider
var serviceProvider = serviceCollection.BuildServiceProvider();
// This is where DI magic happens:
var myCart = ActivatorUtilities.CreateInstance<ShoppingCart>(serviceProvider);
myCart.PlaceOrder("customer@home.com", "2 Widgets");
System.Console.Write("Press any key to end.");
System.Console.ReadLine();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*.G. 22
假设您的控制器MyHelper使用了MyService它.
解决这种情况的方法是:
注册都MyService和MyHelper在Startup.ConfigureServices.
services.AddTransient<MyService>();
services.AddTransient<MyHelper>();
Run Code Online (Sandbox Code Playgroud)控制器MyService在其构造函数中接收实例.
public HomeController(MyService service) { ... }
Run Code Online (Sandbox Code Playgroud)MyService构造函数将依次接收一个实例MyHelper.
public MyService(MyHelper helper) { ... }
Run Code Online (Sandbox Code Playgroud)DI框架将能够毫无问题地解析整个对象图.如果您担心每次解析对象时都会创建新实例,您可以阅读不同的生命周期和注册选项,如单例或请求生命周期.
当您认为必须手动创建某个服务的实例时,您应该非常怀疑,因为您最终可能会在服务定位器反模式中.最好将对象创建到DI容器.如果您确实发现自己处于这种情况(假设您创建了一个抽象工厂),那么您可以IServiceProvider直接使用(IServiceProvider在构造函数中请求一个或使用在httpContext中公开的那个).
var foo = serviceProvider.GetRequiredService<MyHelper>();
Run Code Online (Sandbox Code Playgroud)
我建议阅读有关ASP.Net 5 DI框架的特定文档以及一般的依赖注入.
不幸的是没有直接的方法.我设法使其工作的唯一方法是创建一个静态类并在其他地方使用它,如下所示:
public static class SiteUtils
{
public static string AppName { get; set; }
public static string strConnection { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后在您的启动类中,填写如下:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//normal as detauls , removed for space
// set my variables all over the site
SiteUtils.strConnection = Configuration.GetConnectionString("DefaultConnection");
SiteUtils.AppName = Configuration.GetValue<string>("AppName");
}
Run Code Online (Sandbox Code Playgroud)
虽然这是糟糕的模式,因为这将保持应用程序的整个生命周期,我找不到更好的方法在控制器外使用它.
| 归档时间: |
|
| 查看次数: |
31806 次 |
| 最近记录: |