1

I have following code:

public void ConfigureServices(IServiceCollection services)
    {
      ...
      services.AddScoped<IWsApiProvider, WsApiProvider>();
      services.AddScoped<IApplicationUserRepository, ApplicationUserRepository>();
      ...
    }

WsApiProvider has following:

public Guid SessionId { get; set; }
public IWSocketProvider WsApi { get; set; }

In Invoke method I'm updating these properties:

public Task Invoke(HttpContext httpContext, IOptions<AppSettings> appSettings)
    {
      ...
      this._wsApiProvider.SessionId = sessionGuid;
      this._wsApiProvider.WsApi = connection;
      ...
    }

And then I'm going to Controller where I injected Repository:

public AccountController(IApplicationUserRepository applicationUserRepository)
    {
        this._applicationUserRepository = applicationUserRepository;
    }

    public ApplicationUserRepository(IWsApiProvider wsApi) : base(wsApi)
    { 
    }

And here I have wsApi object with empty properties. Two questions:

  1. Why in repository constructor I have this object with empty properties?

  2. Is there any way to create one instance of IWsApiProvider for all dependencies per request (non-singleton solution)?

Thank you in advance

UPDATED. The whole middleware class:

public class WsApiMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IWsApiProvider _wsApiProvider;
    private const string QisSessionId = "QisSessionId";

    public WsApiMiddleware(RequestDelegate next, IWsApiProvider wsApiProvider)
    {
        _next = next;
        this._wsApiProvider = wsApiProvider;
    }


    public Task Invoke(HttpContext httpContext, IOptions<AppSettings> appSettings)
    {
        var sessionId = httpContext.Request.Cookies[QisSessionId];
        var sessionGuid = Guid.Empty;

        if (!string.IsNullOrEmpty(sessionId))
        {
            Guid.TryParse(sessionId, out sessionGuid);
        }

        var connection = ConnectionsPool.GetSocket(sessionGuid);

        if (connection == null)
        {
            connection = new WSocketProvider(null);

            var connectTask = Task.Run(async () =>
            await connection.Connect(appSettings.Value.WsApiServerEndPointUri, CancellationToken.None)
            );

            Task.WaitAll(connectTask);

            var sessionService = new SessionService(connection);

            var sessionOpenTask = Task.Run(async () =>
            {
                SessionDataState sessionData = null;

                //TODO [W-8/6/2017] - think about better solution for situation when sessionId doesn't exist on the server
                try
                {
                    sessionData = await sessionService.OpenSession(sessionGuid != Guid.Empty ? (Guid?)sessionGuid : null);
                }
                catch (Exception ex)
                {
                    sessionData = await sessionService.OpenSession();
                }

                sessionGuid = sessionData.SessionId;

                if (!sessionData.ClientType.HasValue)
                {
                    await sessionService.LoginClient();
                }

                ConnectionsPool.TryAddConnection(sessionGuid, connection);
                httpContext.Response.Cookies.Append(QisSessionId, sessionGuid.ToString());
            });

            Task.WaitAll(sessionOpenTask);
        }

        this._wsApiProvider.SessionId = sessionGuid;
        this._wsApiProvider.WsApi = connection;

        return this._next(httpContext);
    }
}

// Extension method used to add the middleware to the HTTP request pipeline.
public static class WsApiMiddlewareExtensions
{
    public static IApplicationBuilder UseWsApiMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<WsApiMiddleware>();
    }
}
6
  • Where does the Invoke method comes from? And what's _wsApiProvider? Commented Aug 8, 2017 at 14:32
  • Invoke method comes from MiddleWare.cs which has been registered in startup:app.UseWsApiMiddleware(); IWsApiProvider is a simple interface with two properties: public Guid SessionId { get; set; } public IWSocketProvider WsApi { get; set; } Commented Aug 8, 2017 at 14:51
  • Do you pass IWSocketProvider as an argument to Middleware.cs, or do you build it there? Commented Aug 8, 2017 at 14:54
  • Yes, I'm passing it as constructor parameter: public WsApiMiddleware(RequestDelegate next, IWsApiProvider wsApiProvider) Commented Aug 8, 2017 at 15:16
  • 2
    Post more code; particularly the middleware would be of interest. Commented Aug 8, 2017 at 20:48

1 Answer 1

3

From the ASP.Net core middleware doc :

Middleware is constructed once per application lifetime. Because middleware is constructed at app startup, not per-request, scoped lifetime services used by middleware constructors are not shared with other dependency-injected types during each request.

And the most important part in you situation:

If you must share a scoped service between your middleware and other types, add these services to the Invoke method's signature. The Invoke method can accept additional parameters that are populated by dependency injection.

Since IWsApiProvider is a scoped service(i.e. per request), it should be passed as an argument to the Invoke method, as follow:

public class WsApiMiddleware
{
    private readonly RequestDelegate _next;

    // no longer passed in the constructor
    public WsApiMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    // passed as an argument to Invoke, via dependency injection
    public Task Invoke(HttpContext httpContext, IWsApiProvider wsApiProvider, IOptions<AppSettings> appSettings)
    {
        wsApiProvider.SessionId = "SessionId";
        wsApiProvider.WsApi = "WsApi";

        return this._next(httpContext);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.