views:

84

answers:

1

Hello,

Situation: I have an interface, such as

public interface ITestClass
{
    string StringElement { get; }
}

There is an implementation for it:

public class TestClassImplementor :
    ITestClass
{
    public string StringElement
    {
        get { return "AAA"; }
    }
}

I do have a factory that creates an implementation instance:

    public class TestClassFactory
    {
    public ITestClass Create()
    {
    return new TestClassImplementor();
    }
}

I want to be able to resolve the implementation using Castle Windsor configuration file (XML), but at the same time not configuring the implementation for the interface.

Why is this needed: resolving (web) services. I do have a (web) service interface, but I don't access the implementation, as it is on another component. I want to be able to simply type MyCastleUtility.Resolve<ITestClass>() and get a prepared web service. I want to use Castle Windsor configuration file (XML) to configure the service I'm trying to access.

The problem: if I can't access the implementation, I can't configure it in the configuration file.

What I've tried so far: 1) Factories.

        <component id="mycompfactory"
  type="MyTestProject.TestClassFactory, MyTestProject"/>

        <component id="mycomp"
          type="MyTestProject.ITestClass, MyTestProject"
          factoryId="mycompfactory" factoryCreate="Create" />

I do get the: Castle.MicroKernel.ComponentRegistrationException : Type MyTestProject.INewTestClass is abstract. As such, it is not possible to instansiate it as implementation of MyTestProject.INewTestClass service

2) Proxies. Hit the wall when tried to find a way to configure that "proxy must be created for 'ITestClass' interface".

Target: configure Castle Windsor to create interface implementation without directly accessing the class, that implements the interface.

Help is much appreciated, Mindaugas

+1  A: 

For the factory approach:

  1. Did you also configure the FactoryFacility in your config?

  2. In your "mycomp", I think you want to use "service" and not "type":

<component id="mycomp" service="MyTestProject.ITestClass, MyTestProject" factoryId="mycompfactory" factoryCreate="Create" />

Patrick Steele
That's it: FactoryFacility configuration!<facilities><facilityid="factory.support"type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel"/></facilities>When this missing piece was added to Windsor configuration file (XML), when I call Resolve on my interface, it hits my factory Create() method, where I can instantiate interface implementation the way I like.Btw, I left 'type' for my interface, didn't change it with 'service', as changing it gives me "No component supporting service ITestClass was found" during component resolution.
Mindaugas
Cool. I guess Windsor is smart enough to know what you mean since you're using a factory.
Patrick Steele
re: "No component supporting service ITestClass was found" - this looks like a bug in Windsor, which simply ignores components that do not have 'type' specified when reading XML. I'll see if I can fix that for v2.5
Krzysztof Koźmic
Is there a way to configure a call to a factory' generic Create method (for example: CreateGeneric<TService>(..)), by passing the generic from 'mycomp'? In my case generic TService would have a IBaseClass constraint and I would (like to) pass the ITestClass from 'mycomp' configuration (image that ITestClass implements base interface IBaseClass).
Mindaugas