1

When a http request comes in, I would like to instantiate a class and pass this instance to any class that needs it. For e.g., I have a custom Customer class with two properties. Based on the Request parameters and business logic, I'd like to set the Actions property and any controller or repository that needs this class should have access to the Actions property. I could not use "AddInstance" since ConfigureServices method does not have access to current request.

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();
    });
}

Controller

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.
    }
}
Kiran
  • 21
  • 1
  • 3
  • Maybe it would be a better idea to put a kind of CustomerCreator class into dependency injection once and let it build up the customer when needed. The CustomerCreator can get acces to the HttpContext via DI: http://stackoverflow.com/questions/31243068/httpcontext-current-in-asp-net-vnext – Michael A. Volz aka Flynn Mar 12 '16 at 19:31
  • Thanks for the link. That worked!! However, I'm not sure why the CustomerClass is being called twice even though I'm using AddScoped. – Kiran Mar 14 '16 at 22:36
  • @Flynn thanks for your suggestion!! – Kiran Mar 14 '16 at 22:42

3 Answers3

1

If you want to inject a class created in a middleware, you might try something like this:

In Startup.cs:

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

GetMyObject() is an extension method of the HttpContext

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

    return null;
}

Then in your middleware:

public async Task Invoke(HttpContext httpContext)
{
    MyObject myObj = new MyObject();
    // Your bussiness logic goes here.

    httpContext.Items[Key] = myObj;

    await next_(httpContext);
}
regnauld
  • 4,046
  • 3
  • 23
  • 22
0

A different approach could be to store the generated Customer into the items Dictionary of the HttpContext like so:

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

step1 : instead of a class define an interface for ex: ICustomer

step 2 : Create a service provider and configure this provider at the time of injecting object

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"
              };
        }
    }

step 3 and in startup.cs file,

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

that is all, you get the new instance that is created everytinme.

noufalcep
  • 3,446
  • 15
  • 33
  • 51
venkat
  • 1