.netmonocastle-windsorresolvewindsor-3.0

List and resolve implementations of interface [Windsor Castle]


Since Autofac is not working on Mono I'm trying to switch to Windsor IoC framework. I want to search dll's for implementations of my interface IDataLoader and resolve all of them to instances.

here is my resolving code:

var container = new WindsorContainer();

System.Reflection.Assembly asm = System.Reflection.Assembly.LoadFrom("/home/konrad/DataLoader.dll");
container.Register(AllTypes.FromAssembly(asm));
IDataLoader loader = container.Resolve<IDataLoader>();

Interface looks like this:

namespace Viewer.Core.Data
{
    public interface IDataLoader
    {
        PointControl[] GetPositionData(string filePath);
    }
}

and implementation:

using OpenTK;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Viewer.Core.Data;
using Castle.Windsor;
using Castle.MicroKernel.Registration;

namespace DataLoader
{
    public class StandardDataLoader : IDataLoader
    {
        public StandardDataLoader ()
        {
        }

        public PointControl[] GetPositionData(string filePath)
        {
            return CreateCloud(filePath);
        }

        private PointControl[] CreateCloud(string path)
        {
            //loading data from file code
            return points;
        }
    }
}

After resolving I'm getting error:

{Castle.MicroKernel.ComponentNotFoundException: No component for supporting the service Viewer.Core.Data.IDataLoader 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[IDataLoader] () [0x00000] in <filename unknown>:0    at (wrapper remoting-invoke-with-check) Castle.Windsor.WindsorContainer:Resolve ()   at ViewerMultiplatform.DataModel.LoadModel (System.String modelPath) [0x00027] in /home/konrad/hg/ViewerPrototype/OpenTKMultithread/ViewerMultiplatform/Models/DataModel.cs:103 }

Is there any additional work I have to do to make my classes resolvable by Windsor framework? I also tried to use register and resolveall methods but nothing works for me.


Solution

  • I don't think AllTypes.FromThisAssembly() on it's own actually registers anything...

    Try Pick()

    container.Register(AllTypes.FromThisAssembly()
                .Pick());
    

    I'm still not 100% on the Fluent API yet though :)

    This seems to clear it up:

    Castle Windsor Fluent Registration - What does Pick() do?

    So you can use Pick() or AllTypes().Of<object>() - specifying AllTypes() without picking any types doesn't actually add any types to the container

    You also need to specify the services that the components implement:

    container.Register(AllTypes.FromThisAssembly()
                .Pick().WithService.FirstInterface());
    

    or

    container.Register(AllTypes.FromThisAssembly()
                .Pick().WithService.DefaultInterfaces());