Thomas.Benz
Thomas.Benz

Reputation: 8599

Am I using correct lifetime managers for dependency injection?

I have an asp.net web api application that uses Unity dependency injection libraries from MS Unity.AspNet.WebApi and Unity nuget packages. Also, the application uses Entity Framework version 6 database context for ORM and a generic repository.

Custom service types are consumed by Api controllers. Custom Service classes consumes EF database contexts and the generic repository.

My question is: Are HierarchicalLifetimeManager and ContainerControlledLifetimeManager correct lifetime managers for my web api application?

Codes in the UnityConfig class of my application:

    using System;
    using System.Configuration;
    using System.Data.Entity;
    using Microsoft.Practices.Unity;
    using Microsoft.Practices.Unity.Configuration;
    using App.Api.Models;
    using App.Dal;

    public class UnityConfig
        {
            #region Unity Container
            private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
            {
                var container = new UnityContainer();
                RegisterTypes(container);
                return container;
            });

            /// <summary>
            /// Gets the configured Unity container.
            /// </summary>
            public static IUnityContainer GetConfiguredContainer()
            {
                return container.Value;
            }
            #endregion

            /// <summary>Registers the type mappings with the Unity container.</summary>
            /// <param name="container">The unity container to configure.</param>
            /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
            /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
            public static void RegisterTypes(IUnityContainer container)
            {

                var connectionStringEntityFramework= ConfigurationManager.ConnectionStrings["AppEntities"].ToString();


            // Entity Framework database context and generic repository
// HierarchicalLifetimeManager  is used:

                container.RegisterType<DbContext, FirstAngularJsEntities>(new HierarchicalLifetimeManager(), new InjectionConstructor(connectionStringFirstAngularJsEntities));
                container.RegisterType<IRepository, GenRepository>(new HierarchicalLifetimeManager(), new InjectionConstructor(typeof(DbContext)));


                // services
// ContainerControlledLifetimeManager is used:

                container.RegisterType<IContactService, ContactService>(new ContainerControlledLifetimeManager());
                container.RegisterType<IProductService, ProductService>(new ContainerControlledLifetimeManager());

            }

A sample api controller has custom service injected in its constructor:

public class ContactApiController : ApiController
    {
        private readonly IContactService _contactService;

        public ContactApiController(IContactService contactService)
        {
            _contactService = contactService;
        }

...
}

A sample custom service has EF DbContext and repository injected in its constructor:

public class ContactService : IContactService
    {
        private readonly IRepository _repo;
        private readonly DbContext _context;


        public ContactService(DbContext context, IRepository repo)
        {
            _context = context;
            _repo = repo;

        }

...
}

Upvotes: 4

Views: 10313

Answers (2)

Paul Hatcher
Paul Hatcher

Reputation: 8156

I tend to look at this as what is the shortest lifetime that is compatible with the semantics of what you are trying to do, with the default lifetime being Transient unless otherwise required.

  1. DbContext holds state so we need to be consistent for the request so PerRequest or Hierachic
  2. Repository is/should be stateless since it's state is the DbContext, so Transient
  3. Services is/should be stateless so Transient

One reason for going with Hierarchic rather than PerRequest is that the PerRequest manager does not play well with Owin, see http://www.reply.com/solidsoft-reply/en/content/managing-object-lifetimes-with-owin-and-unity, and you will need to write some cleanup middleware to replace the HttpModule

Upvotes: 5

Backs
Backs

Reputation: 24903

Using ContainerControlledLifetimeManager you'll get singletons of your services. One instance for a long time (untill IIS recycling). HierarchicalLifetimeManager is used with child containers - create new instance of object for every child container, so you don't create child containers it works like a singleton again :) The best way for WebApi apllication is using PerRequestLifetimeManager. Create new instances for every request to Api.

Upvotes: 8

Related Questions