Konrad Błasiński
Konrad Błasiński

Reputation: 15

Resolving generics in Windsor Castle

I'm trying to resolve object which inherits template class

using System;
using Controller;

namespace Controller
{
    public interface IControllerBase<T> where T:IViewBase
    {

    }

    public class ControllerBase
    {
        public string ModuleName
        {
            get;
            set;
        }
    }

    public class ControllerBase<T> : ControllerBase, IControllerBase<T>
        where T : IViewBase
    {

        public virtual T View {
            get;
            set;
        }

        public ControllerBase (T instance)
        {
            View = instance;
        }
    }

    }



IControllerBase was added recently, just to match this strategy:

    container.Register (Component.For(typeof(IControllerBase<IViewBase>)).ImplementedBy(typeof(ControllerBase<IViewBase>)).LifeStyle.Transient);

next i have class which is derrived from ControllerBase

using System;

namespace HardwareConnections
{
    public class HardwareConnectionsController : Controller.ControllerBase<IHardwareConnections>
    {
        public HardwareConnectionsController(IHardwareConnections view) : base(view)
        {
            base.ModuleName = "Hardware connections";
            Console.WriteLine("\n\n\n\n");
            Console.WriteLine("Constructor fired");
            Console.WriteLine("\n\n\n\n");
        }
    }
}

I'm trying to resolve HardwareConnectionsController by first resolving View class which implements IViewBase interface and this works fine, I'm getting instance of a View and passing it in constructor

but I have problem with resolving Controller class

var hcon = container.Resolve<ControllerBase<IViewBase>>(new { view = plug});

error is:

Castle.MicroKernel.ComponentNotFoundException has been thrown No component for supporting the service PETController.ControllerBase`1[[PETController.IViewBase, PETController, Version=1.0.4988.28227, Culture=neutral, PublicKeyToken=null]] was found stack:

Castle.MicroKernel.ComponentNotFoundException: No component for supporting the service PETController.ControllerBase`1[[PETController.IViewBase, PETController, Version=1.0.4988.28227, Culture=neutral, PublicKeyToken=null]] was found
  at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve (System.Type service, IDictionary arguments, IReleasePolicy policy) [0x00000] in <filename unknown>:0
  at Castle.MicroKernel.DefaultKernel.Resolve (System.Type service, IDictionary arguments) [0x00000] in <filename unknown>:0
  at Castle.Windsor.WindsorContainer.Resolve[ControllerBase`1] (System.Object argumentsAsAnonymousType) [0x00000] in <filename unknown>:0
  at (wrapper remoting-invoke-with-check) Castle.Windsor.WindsorContainer:Resolve (object)
  at PETController.PluginFactory.LoadPlugins[IViewBase] (System.String searchLocation) [0x001f6] in /home/konrad/hg/PET/PET/PETController/Utils/PluginFactory.cs:67
  at MainWindow..ctor () [0x00034] in /home/konrad/hg/PET/PET/PETController/MainWindow.cs:19
  at PETController.MainClass.Main (System.String[] args) [0x00005] in /home/konrad/hg/PET/PET/PETController/Main.cs:11


enter code here

Upvotes: 0

Views: 2096

Answers (2)

Matt Whetton
Matt Whetton

Reputation: 6786

Heres some stuff that might help:

When you register try (I think this is what you're looking for):

container.Register (Component.For(typeof(IControllerBase<>)).ImplementedBy(typeof(ControllerBase<>)).LifeStyle.Transient);

And when you resolve you need to use the IControllerBase rather than ControllerBase:

var hcon = container.Resolve<IControllerBase<IViewBase>>(new { view = plug});

If you register the service IControllerBase<> you need to resolve IControllerBase

Upvotes: 0

Crixo
Crixo

Reputation: 3070

I'm a little bit confused about your sample... but generally speaking if you registered a component For(typeof(IControllerBase<IViewBase>)) you have to resolve it using same type.

instead of

 var hcon = container.Resolve<ControllerBase<IViewBase>>(new { view = plug});

try

var hcon = container.Resolve<IControllerBase<IViewBase>>(new { view = plug});

I'm not sure why you are registering the component using as implementation a generic type instead of the real one... that's what I might use instead

container.Register (Component.For(typeof(IControllerBase<IViewBase>)).ImplementedBy(typeof(HardwareConnectionsController)).LifeStyle.Transient);

Upvotes: 1

Related Questions