Resolving dependencies per call rather than singleton

Feb 1, 2011 at 2:56 PM

Greetings -

I have a setup like so:

interface IWCFService {}

class WCFService : IWCFService
{
  WCFService(IBusinessService service)
  {
  }
}

interface IBusinessService{}

class BusinessService : IBusinessService
{
  BusinessService(IRepository repo)
  {
  }
}

interface IRepository{}

class Repository : IRepository
{
}

... and so on...

We're wiring all of these dependencies together through Unity's API (RegisterType) and calling Resolve in a WCF instance provider.  What I'm seeing is that for each call into our WCF service, a new instance of WCFService is created, which is good, this is what we want to happen.  However, each instance of WCFService appears to be using a singleton instance of BusinessService which is using a singleton instance of Repository.  How can I ensure that a new instance of Repository is created for each call to container.Resolve<WCFService>()?

Thanks!

Chris

 

Feb 1, 2011 at 4:00 PM

Use the PerResolveLifetimeManager for those types instead of ContainerControlledLifetimeManager. This is new in Unity 2.0.

 

Feb 1, 2011 at 4:17 PM

Thanks.  I tried that, but I'm still seeing the same behavior.  I've also tried TransientLifetimeManager with no luck wither.

 

 

Feb 2, 2011 at 10:52 PM

Then something else is going on. Either the container's not configured the way you expected, or something else is doing the caching. Or is the service instance itself getting reused and not going back through the container? What's the lifetime of the service instance? If that's container controlled, it's not going to re-inject on every request. Just a guess, though.

One thing you could do is look at the container.Registrations property - go through and find the registration for the type you're interested in. The lifetime manager type is provided there. Double check and see if it matches what you're seeing.

 

Feb 3, 2011 at 2:34 PM

We don't have too many types registered at this point, so I went through the Registrations property as you suggested and checked the lifetime manager for each registration.  All of them were set to TransientLifetimeManager with the exception of the registration for the IUnityContainer itself, which is set to Microsoft.Practices.Unity.UnityDefaultBehaviorExtension.ContainerLifetimeManager.  I assume this is expected behavior.

Right now the way I've been examining this problem is through a fairly simple unit test, so I'm not sure what else could be doing the caching.  The unit test code is below:

        private IUnityContainer unityContainer;
        private IModuleConfiguration dataModuleConfiguration;
        private IModuleConfiguration businessModuleConfiguration;
        private IModuleConfiguration servicesModuleConfiguration;

        [TestInitialize()]
        public void Setup()
        {
            unityContainer = new UnityContainer();
           
            dataModuleConfiguration = new DataModuleConfiguration();
            businessModuleConfiguration = new BusinessModuleConfiguration();
            servicesModuleConfiguration = new ServicesModuleConfiguration();

            dataModuleConfiguration.Configure(unityContainer);
            businessModuleConfiguration.Configure(unityContainer);
        }

 

        [TestMethod()]
        public void TestResolve()
        {
            servicesModuleConfiguration.Configure(unityContainer);

            for (int i = 0; i < 10; i++)
            {
                var X = unityContainer.Resolve<Services.Contracts.Service.ILookupService>();
            }
        }

IModuleConfiguration is our own interface that we implement in each layer (WCF, business, data) to handle registering types into our core Unity container. 

Since I have trace statements in the constructors for our business and data layer components, I expect when the test above runs, I should see each of those trace statements output ten times, however I'm only seeing them output on the first iteration through that loop.