Admir Tuzović
Admir Tuzović

Reputation: 11177

Autofac, multiple interfaces to same implementation per HTTP request in ASP.NET MVC

My DbContext implementation implements two interfaces. I'm trying to follow best practices and instantiate one DbContext instance per HTTP request. However, I have a controller action where I need to instantiate two classes, each of which takes different interface in constructor. I am worried if in that scenario, for that specific action, two DbContext instances would be raised.

I've setup my ContainerBuilder like this:

        builder.RegisterType<MyDbContext>()
            .As<IWorkflowPersistenceStore>()
            .As<IDocumentPersistenceStore>()
            .InstancePerHttpRequest();
    builder.RegisterType<WorkflowManager>().As<IWorkflowManager>().InstancePerHttpRequest();
    builder.RegisterType<DocumentManager>().As<IDocumentManager>().InstancePerHttpRequest();


public class OperationController : Controller
{
    private IWorkflowManager _workflowManager;
    private IDocumentManager _documentManager;

    public OperationController(IWorkflowManager workflowManager, IDocumentManager documentManager)
    {
        _workflowManager = workflowManager;
        _documentManager = documentManager;
    }

    public ActionResult SaveWorkflowDocument(...)
    {
        // will my managers point to same DbContext?
        _workflowManager.DoSomething(...);
        _documentManager.DoSomethingElse(...);

        return View();
    }
}

public class WorkflowManager : IWorkflowManager
{
    private IWorkflowPersistenceStore _store;

    public WorkflowManager(IWorkflowPersistenceStore store)
    {
        _store = store;
    }
}

public class DocumentManager : IDocumentManager
{
    private IDocumentPersistenceStore _store;

    public DocumentManager (IDocumentPersistenceStore store)
    {
        _store = store;
    }
}

Is this good enough? Do I have to add .SingleInstance()? I'm worried that it might create singleton for whole application.

Upvotes: 0

Views: 610

Answers (1)

Jim Bolla
Jim Bolla

Reputation: 8295

I think you're ok with what you have. Test passes:

using Autofac;
using NUnit.Framework;

namespace AutofacTest
{
    [TestFixture]
    public class ScopeTest
    {
        [Test]
        public void Test()
        {
            var builder = new ContainerBuilder();

            builder.RegisterType<Component>()
                .As<IServiceA>()
                .As<IServiceB>()
                .InstancePerLifetimeScope();

            using (var container = builder.Build())
            using (var scope = container.BeginLifetimeScope())
            {
                var a = scope.Resolve<IServiceA>();
                var b = scope.Resolve<IServiceB>();

                Assert.AreEqual(a, b);
            }
        }
    }

    public interface IServiceA  {   }
    public interface IServiceB  {   }
    public class Component : IServiceA, IServiceB   {   }
}

Upvotes: 3

Related Questions