0

I have a service layer that I am reusing (AKA Business Layer).

Here's an example of one of my services with an IMyContextFactory dependency, this returns an instance of IMyContext.

public class MyService : IMyService 
{
    private IMyContextFactory DbContextFactory;

    public MyService(IMyContextFactory dbContextFactory)
    {
        this.DbContextFactory = dbContextFactory;
    }

    public DoSomething(int id)
    {
        // Get instance of the db for use
        IMyContext dbContext = this.DbContextFactory.CreateMyDbContext();

        // Use the business layer for something
        var user = dbContext.Set<User>().Find(id);
    }
}

I am using the Ninject Factory extension.

Is it possible to make the IMyContextFactory to return the same instance of IMyContext every time?

Background

Originally I was injecting IMyDbContext straight into the service without the factory and I had this InRequestScope() when initialized by my ASP.NET MVC website.

But now I am making use of the service it in a Windows Service too and I don't want my DbContext to become bloated because of frequent looping. I didn't want my service to be newed up for every request either, so that's why I thought a factory within the service would do the trick.

I need the best of InRequestScope() and a new instance every time depending on the configuration. I already have a separate config for ASP.NET and for the Windows Service - it's just how I get a singleton each time from the factory.

Luke
  • 22,826
  • 31
  • 110
  • 193
  • You *MUST* always destroy your DbContexts after every use. They have no mechanism to clean themselves up other than by destroying them. Thus, they will grow and consume more and more resources if you do not periodically discard them. DbContexts are also not thread or multi-user safe, because they have inherent state. Do yourself a favor, always destroy your contexts after every use. – Erik Funkenbusch Jun 03 '15 at 08:55
  • That's indeed what I thought, which is why I have my DbContext in request scope (created and destroyed per request) and I'd like it to be a new one for each call to the method on my service layer when I call it on a loop from my windows service. Thanks for your help – Luke Jun 03 '15 at 08:58
  • I'm confused. Your title indicates you want to use the same instance everywhere. But your comment indicates you do not.. which is it? I really don't understand your question because you keep switching between singleton (one instance for the life of the application) and Request lifetimes.. – Erik Funkenbusch Jun 03 '15 at 09:01
  • @ErikFunkenbusch No problem. Sorry for confusing you. I am calling my service layer and configuring it from two separate projects, this is why for one I need the same instance every time and for the other I need a new instance every time, depending on the Ninject configuration. The snag is that they use the same code but it must be able to do one or the other. I started using the factory, but I wanted it to return the same instance every time - essentially configuring the factory to behave differently. – Luke Jun 03 '15 at 09:18

1 Answers1

1

I'm not fully proficient with Ninject, but according to this page https://github.com/ninject/Ninject.Extensions.Factory/wiki/Factory-interface it seems that the instance returned by the factory is retrieved from the IResolutionRoot.

My take would be that you have to register your IMyContext concrete type with a singleton lifetime type.

(But it seems that it's not that of a good idea to not destroy your context, according to Erik Fukenbusch's comment)

Philippe
  • 3,945
  • 3
  • 38
  • 56
  • Ooo right. So I can continue to set the scope and my factory will adhere to that scope? – Luke Jun 03 '15 at 08:59
  • Fantastic, you are right! If I configure `IMyContext` for `InRequestScope()` or for `InTransientScope()` the Factory uses this information when creating new instances! Works like a charm – Luke Jun 03 '15 at 09:43