Jedediah
Jedediah

Reputation: 1944

How to use ninject to replace a repository factory

I have some code that I'm looking to refactor that looks something like this:

public static class RepositoryFactory
{
    public static IRepository Create(RepositoryType repositoryType)
    {
        switch(repositoryType)
        {
            case RepositoryType.MsSql:
                return new MsSqlRepository();
                break;
            case RepositoryType.Postgres:
                return new PostgresRepository();
                break;
            //a lot more possible types
        }
    }
}

Which is being called based on parameters from an HTTP request:

public ActionResult MyAction()
{
    var repoType = RepositoryType.MsSql; //Actually determined from HTTP request, could be any type.
    var repository = RepositoryFactory.Create(repoType);
}

So what I'd really like to do is refactor so that my controller looks like this:

[Inject]
public ActionResult MyAction(IRepository repository)

But since RepositoryType could change on each request, I can't figure out how to leverage ninject's conditional binding to make that happen. I know how to use conditional binding in general, such as Bind<IRepository>().ToMethod() and Bind<IRepository>().To<MsSqlRepository>().WhenInjectInto() etc, but I can't figure out what to do when the binding condition is coming from an outside source.

Upvotes: 1

Views: 129

Answers (1)

BatteryBackupUnit
BatteryBackupUnit

Reputation: 13243

This should actually be fairly easy:

kernel.Bind<IRepository>().To<MsSqlRepository>()
      .When(ctx => System.Web.HttpContext.Current.... (condition here) );

kernel.Bind<IRepository>().To<PostgresRepository>()
      .When(ctx => System.Web.HttpContext.Current.... (condition here) );

You can also define one as a "default" and the other as a conditional one:

// this will be used when there's not another binding
// for IRepository with a matching When condition
kernel.Bind<IRepository>().To<MsSqlRepository>(); 

// this will be used when the When condition matches
kernel.Bind<IRepository>().To<PostgresRepository>()
      .When(ctx => System.Web.HttpContext.Current.... (condition here) );

Upvotes: 1

Related Questions