Question

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.

Was it helpful?

Solution

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   {   }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top