【问题标题】:.NET Core/Pass Object created in Startup.cs to all Depending Classes.NET Core/将 Startup.cs 中创建的对象传递给所有依赖类
【发布时间】:2016-06-27 23:32:48
【问题描述】:

当一个 http 请求进来时,我想实例化一个类并将这个实例传递给任何需要它的类。 例如,我有一个具有两个属性的自定义 Customer 类。基于请求参数和业务逻辑,我想设置 Actions 属性,并且任何需要此类的控制器或存储库都应该有权访问 Actions 属性。我无法使用“AddInstance”,因为 ConfigureServices 方法无权访问当前请求。

CustomerClass.cs

public class CustomerClass
{
    public string UserName{get;set;}
    public string Actions{get;set;}
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<CustomerClass, CustomerClass>();
}
public void Configure(IApplicationBuilder app, CustomerClass cs)
{
    app.Use((context, next) =>
    {
        cs.UserName = context.User.Identity.Name;
        // cs.Actions = BUSINESSLOGICBASEDONREQUEST
        return next();
    });
}

控制器

public class CustomerController : Controller
{
    CustomerClass _local;
    public CustomerController(CustomerClass cls)
    {
        // here, I expect to use the class instantiated in Startup.cs >
        // Configure method since I set the CustomerClass to have "Scoped" 
        // life span. However, a new  Customer class instance is being
        // requested.
    }
}

【问题讨论】:

  • 也许将一种 CustomerCreator 类放入依赖注入一次并让它在需要时建立客户会是一个更好的主意。 CustomerCreator 可以通过 DI 访问 HttpContext:stackoverflow.com/questions/31243068/…
  • 感谢您的链接。那行得通!但是,即使我使用的是 AddScoped,我也不确定为什么 CustomerClass 会被调用两次。
  • @Flynn 谢谢你的建议!!

标签: dependency-injection asp.net-core


【解决方案1】:

另一种方法是将生成的Customer 存储到HttpContextitems 字典中,如下所示:

app.Use(async (context, next) =>
{
    var customer = new Customer();
    context.Items.Add("customerKey", customer);
    await next();
});

【讨论】:

    【解决方案2】:

    如果你想注入一个在中间件中创建的类,你可以试试这样:

    Startup.cs:

    services.AddScoped(prov => 
    prov.GetService<IHttpContextAccessor>()?.HttpContext?.GetMyObject());
    

    GetMyObject()HttpContext的扩展方法

    public static MyObject GetMyObject(this HttpContext context)
    {
        object myObj;
        if (context.Items.TryGetValue(Key, out myObj))
        {
            return myObj as MyObject;
        }
    
        return null;
    }
    

    然后在你的中间件中:

    public async Task Invoke(HttpContext httpContext)
    {
        MyObject myObj = new MyObject();
        // Your bussiness logic goes here.
    
        httpContext.Items[Key] = myObj;
    
        await next_(httpContext);
    }
    

    【讨论】:

      【解决方案3】:

      step1 : 代替类为 ex: ICustomer 定义一个接口

      第 2 步: 创建一个服务提供者,并在注入对象的时候配置这个提供者

      public class InterceptServiceProvider : IServiceProvider
          {
              public object GetService(Type serviceType)
              {
                 // you can do lot of stuff here based on serviceType
                 return new CustomerClass {
                      UserName = context.User.Identity.Name;
                      Actions = "BUSINESSLOGICBASEDONREQUEST"
                    };
              }
          }
      

      第 3 步和在 startup.cs 文件中,

      services.AddTransient(obj => new InterceptServiceProvider().GetService(typeof(CustomerClass)) as ICustomer);
      

      就是这样,你得到了每一次创建的新实例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-02
        • 1970-01-01
        • 2017-07-18
        • 2017-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-30
        相关资源
        最近更新 更多