Resolve dependencies differently depending on whether user is logged in

Published: 18 August 2015


In a recent project I had to collect information from a user, and store that information so that we have the information available during the entire browsing session.

The application allowed for users to use the application anonymously, in which case I would store the information in a session variable. If a user was however logged into the application, I would store the information inside a database table so that it would be available on the next visit.

At first I wrote a single class which handled both cases by checking whether the user was logged in, and then either store or retrieve the information from the session or database.

I then thought of another way to handle this, and instead of doing the logic inside a single class, I split it out into two different classes and depending on whether the user is logged in I would use the appropriate class.

First I created a generic interface which specifies the contract for the class:

public class ServiceLink
{
    public ServiceLink(string serviceType, string accountName)
    {
        ServiceType = serviceType;
        AccountName = accountName;
    }

    public string AccountName { get; set; }
    public string ServiceType { get; set; }
}

public interface IServiceLinkStorage
{
    Task Add(ServiceLink serviceLink);
    Task<ServiceLink> Get(string serviceType);
    Task<List<ServiceLink>> GetAll();
    Task Remove(string serviceType);
    Task Clear();
}

And created two separate implementations. One for storing the information inside a session variable, and the other inside the database:

public class ServiceLinkSessionStorage : IServiceLinkStorage
{
	...
}

public class ServiceLinkDatabaseStorage : IServiceLinkStorage
{
	...
}

I used Autofac to inject IServiceLinkStorage into my controllers, so the only thing left was to resolve the correct class based on whether the user was logged in or not:

builder.Register<IServiceLinkStorage>(context =>
   {
       var httpContext = context.Resolve<HttpContextBase>();

       if (httpContext != null && httpContext.User.Identity.IsAuthenticated)
           return new ServiceLinkDatabaseStorage(httpContext, context.Resolve<IApplicationDbContext>());

       return new ServiceLinkSessionStorage(context.Resolve<HttpSessionStateBase>());
   })
.As<IServiceLinkStorage>()
.InstancePerRequest();

Obviously you will need to use a lifetime scope of InstancePerDependency() or InstancePerRequest() for this to work correctly.

How would you have handled this situation? Please share in the comments below.

If you found value in this blog post and want to return the favour, you can Buy me a coffee

PS: I publish a weekly newsletter for ASP.NET Developers called ASP.NET Weekly. If you want to get an email every Friday with all the best ASP.NET related blog posts from the previous week, please sign up!