1

Trying to Register the dependency that need to be passed to the Controller Methods as an Interface and after doing some research the below needs to done but after setting it Sitecore throws this errpr

ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container.Kernel));
container.Register(Classes.FromThisAssembly().BasedOn<IController>().LifestyleTransient().Configure( x => x.Named(x.Implementation.FullName)));

Code Snippet in the controller is

public ActionResult Footer(ISomeFactory someFactory) {}

I am using Glass Mapeer and Castle Windsor for IOC.

T Malik
  • 45
  • 1
  • 7

2 Answers2

2

You need to tell Castle how to resolve SitecoreController which is not defined in your assembly. Try this:

        container.Register(
            Classes.FromThisAssembly()
                .BasedOn<IController>()
                .LifestyleTransient()
                .Configure(x => x.Named(x.Implementation.FullName)),
           Component.For<SitecoreController>()
                    .ImplementedBy<SitecoreController>()
                    .LifestylePerWebRequest()
                    .DependsOn(new {databaseName = Sitecore.Context.Database})
            );

EDIT: Based on comment you can expand this registration to something like this. You may need to review Lifestyle settings for each object, and depending on your Controller's constructors you may need to add in additional implementations.

  container.Register(
            Classes.FromThisAssembly().BasedOn<IController>().LifestyleTransient(),
            Component.For<ISitecoreContext>().ImplementedBy<SitecoreContext>().LifestylePerWebRequest(),
            Component.For<ISitecoreService>().ImplementedBy<SitecoreService>(),
            Component.For<IGlassHtml>().ImplementedBy<GlassHtml>().LifestylePerWebRequest(),
            Component.For<SitecoreController>()
                .ImplementedBy<SitecoreController>()
                .LifestylePerWebRequest()
                .DependsOn(new {databaseName = Sitecore.Context.Database})
           );
Matt Gartman
  • 867
  • 4
  • 9
  • Thanks Matt. This solved the issue. But now I am getting [MissingMethodException: Cannot create an instance of an interface. Object type 'Glass.Mapper.Sc.ISitecoreContext'.]. I think there is issue with Windsor Castle and MVC 5. I even removed integration with Glass Mapper and Solr and just tried to do it in GLobal.ascx.cs file in application start and still getting this error. Either MVC 5 is not compatible with WindsorCastle or there some thing else i am missing – T Malik Oct 17 '14 at 15:52
  • Glass, Castle and MVC 5 work fine together. This error is suggesting Castle is trying to resolve an interface with an interface. You can fix this by registering ISitecoreContext to a concrete. I've updated my answer with a fuller register() method. – Matt Gartman Oct 17 '14 at 18:48
  • Thanks Matt and your are right all these work together but once you understand what is going on. I was doing it a bit different and inside GlassMapperScCustom and using the container from the DependencyResolver.CreateStandardResolver() from GM. This caused to unregister the Sitecore Controller. I will write the answer so it is easy for other to read. – T Malik Oct 17 '14 at 18:53
2

Ok Lesson Learned. First of all when you are working with Sitecore MVC, Glass Mapper and Solr then don't mix their Windsor containers. I started using the Windsor Container from GM and added the registration code in GlassMapperScCustom.CastleConfig(IWindsorContainer container) to register my components. This caused the SitecoreController to get unregistered and threw the error "No component for supporting the service Sitecore.Mvc.Controllers.SitecoreController was found". When I implemented the solution suggested by Matt Gartman then it worked. But I didn't like this and wanted a more cleaner appraoch. So here are my suggestions.

  1. Create a separate Windsor Container and register your components. Do it the Global.ascx.cs Application_Start()
  2. Keep the Glass Mapper and Solr Container intact. Don't use their containers.
  3. You can now use Controller Constructor DI with this.
  4. If you are trying to do Method DI then that is separate thing and don't assume it to work with Constructor DI. Lesson learned the hard way.

Hope this discussion will help someone who is trying to do all this with these technologies.

T Malik
  • 45
  • 1
  • 7