Windsor Castle: How do I register a factory method when the base type is not available for my assembly?

I have a project in which my business layer is built using DI, but I'm trying to take an extra step and use Windsor to control the construction of the object.

Say I have an existing data layer (which I don’t want to change) that can be accessed through the following interface:

interface IDataFactory { IDataService Service { get; } } 

A number of classes in my business layer depend on services open through IDataFactory:

 IFactory factory = DataFactory.NewFactory(); IBusinessService service = new ConcreteBusinessService(factory.Service); 

I understand that to register an IBusinessService in a Castle Windsor container, I would use code similar to this:

 IWindsorContainer container = new WindsorContainer(); container.AddComponent("businessService", typeof(IBusinessService), typeof(ConcreteBusinessService)); 

But for life, I can't figure out how to register services from my data layer using my existing factory object. In essence, I would like to say:

 container.AddComponent("dataService", typeof(IDataService), factory.service); 

The Windsor seems to want me to say container.AddComponent ("dataService", typeof (IDataService), typeOf (SomeConcreteDataService) ), but in this case ConcreteDataService is internal to this assembly and therefore not available in mine.

How can I connect to the data service, given that SomeConcreteDataService is not known to my assembly?


This question is very similar to my own, with the exception of my case, AddComponent ("calculator", typeof (ICalcService), typeof (CalculatorService), "Create"); the call will not work - CalculatorService will be internal to another assembly, inaccessible to the assembly connecting the container.

+4
source share
2 answers

Using Windsor 2.0:

 [TestFixture] public class WindsorTests { public interface IDataService {} public class DataService: IDataService {} public interface IDataFactory { IDataService Service { get; } } public class DataFactory: IDataFactory { public IDataService Service { get { return new DataService(); } } } [Test] public void FactoryTest() { var container = new WindsorContainer(); container.AddFacility<FactorySupportFacility>(); container.AddComponent<IDataFactory, DataFactory>(); container.Register(Component.For<IDataService>().UsingFactory((IDataFactory f) => f.Service)); var service = container.Resolve<IDataService>(); Assert.IsInstanceOfType(typeof(DataService), service); } } 

See the white page on the API wiki for more information.

+14
source

Got it. Answer: you do not need to worry about the type of implementation:

  IWindsorContainer container = new WindsorContainer(); container.AddFacility("factories", new FactorySupportFacility()); container.AddComponent("standard.interceptor", typeof(StandardInterceptor)); container.AddComponent("factory", typeof(DataFactory)); MutableConfiguration config = new MutableConfiguration("dataService"); config.Attributes["factoryId"] = "factory"; config.Attributes["factoryCreate"] = "get_Service"; container.Kernel.ConfigurationStore.AddComponentConfiguration("dataService", config); container.Kernel.AddComponent("dataService", typeof(IDataService)); IDataService dataService = (IDataService) container["dataService"]; 

I had a β€œwhoa” moment when I saw that it was running successfully because I did not pass a specific implementation type to Kernel.AddComponent ()

0
source

All Articles