hybridLifestyle error with Generic

Sep 1, 2013 at 8:48 AM
Hi,

I have a problem using Generic Interface registeration with hybridLifestyle, I will post my code and the exception, please help me to fix this problem, I started with MVC 4 project and added Simple Injector and its extensions.

the initializer
    public static class SimpleInjectorInitializer
    {
        private static Container _container;

        /// <summary>Initialize the container and register it as MVC3 Dependency Resolver.</summary>
        public static void Initialize()
        {
            // Did you know the container can diagnose your configuration? Go to: http://bit.ly/YE8OJj.
            _container = new Container();

            InitializeContainer(_container);

            _container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

            _container.RegisterMvcAttributeFilterProvider();

            _container.Verify();

            DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(_container));
        }

        private static void InitializeContainer(Container container)
        {
            //var hybridLifestyle = Lifestyle.CreateHybrid(() => System.Web.HttpContext.Current != null,
            //                new WebRequestLifestyle(),
            //                new LifetimeScopeLifestyle());  Lifestyle.Transient
            var hybridLifestyle = Lifestyle.CreateHybrid(
                                lifestyleSelector: () => HttpContext.Current != null,
                                trueLifestyle: new WebRequestLifestyle(),
                                falseLifestyle: new LifetimeScopeLifestyle());



            // container.Register<IRepository<Apple>, Repository<Apple>>(Lifestyle.Transient);
            // For instance:
            container.RegisterOpenGeneric(typeof(IRepository<>), typeof(Repository<>), hybridLifestyle);

        }
    }
the interface
   public interface IRepository<T>
   {
       T FindByID(int id);
   }
the interface implementation
    public class Repository<T> : IRepository<T>
        where T : new()
    {  

        public T FindByID(int id)
        {
            var item =  new T();
            return item;
        }
    }
the controller
 public class HomeController : Controller
    {
        private IRepository<Apple> _applesRepository;

        public HomeController(IRepository<Apple> applesRepository)
        {
            _applesRepository = applesRepository;
        }

        //
        // GET: /Home/

        public ActionResult Index()
        {
            var apple = _applesRepository.FindByID(1);

            var id = apple.id;
            return View();
        }

    }
the Apple Class
public class Apple
    {
        public int id;

        public Apple()
        {
            id = 90;
        }
    }
the exception I got is :
The configuration is invalid. Creating the instance for type HomeController failed. The registered delegate for type HomeController threw an exception. There was an error in the registration of open generic type IRepository<T>. Failed to build a registration for type Repository<Apple>. No registration for type LifetimeScopeManager could be found and an implicit registration could not be made. For the container to be able to create LifetimeScopeManager, it should contain exactly one public constructor, but it has 0.
Kindly help me to fix this error.
Coordinator
Sep 1, 2013 at 9:47 AM
Edited Sep 1, 2013 at 11:13 AM
I'm afraid you hit a bug. I will investigate and get back to you about this a.s.a.p.
Coordinator
Sep 1, 2013 at 10:08 AM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Marked as answer by dot_NET_Junkie on 3/2/2014 at 10:50 AM
Coordinator
Sep 1, 2013 at 11:12 AM
I just pushed version v2.3.4 (to NuGet and CodePlex) that fixes this issue.
Coordinator
Sep 2, 2013 at 7:30 AM
I'm sorry, the new patch release doesn't fix the problem.

The LifetimeScopeLifestyle does some initialization in the container and registers a single LifetimeScopeManager behind the scenes. The RegisterOpenGeneric extension method however, postpones the use of the supplied lifestyle till the moment a closed version of the supplied open generic type is requested for the first time. Since this happens after the registration phase and the container is at that point already locked, the LifetimeScopeManager can't be registered.

What should have happened however, was that the LifetimeScopeLifestyle threw an exception explaining that you should have to enable lifetime scoping in the container manually, but unfortunately it incorrectly throws an unclear exception that doesn't help you.

Long story short, to resolve the problem, add the following line of code in your configuration:
container.EnableLifetimeScoping();